OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.ui.gfx; | 5 package org.chromium.ui.gfx; |
6 | 6 |
7 import android.app.Activity; | 7 import android.app.Activity; |
8 import android.content.ActivityNotFoundException; | 8 import android.content.ActivityNotFoundException; |
9 import android.content.ContentResolver; | |
10 import android.content.Intent; | 9 import android.content.Intent; |
11 import android.content.res.Resources; | |
12 import android.os.Bundle; | 10 import android.os.Bundle; |
13 import android.util.SparseArray; | 11 import android.util.SparseArray; |
14 import android.widget.Toast; | 12 import android.widget.Toast; |
15 | 13 |
16 import org.chromium.base.JNINamespace; | |
17 | |
18 import java.util.HashMap; | 14 import java.util.HashMap; |
19 | 15 |
20 /** | 16 /** |
21 * The window that has access to the main activity and is able to create and rec
eive intents, | 17 * The window that has access to the main activity and is able to create and rec
eive intents, |
22 * and show error messages. | 18 * and show error messages. |
23 */ | 19 */ |
24 @JNINamespace("ui") | 20 public class ActivityNativeWindow extends NativeWindow { |
25 public class NativeWindow { | |
26 | 21 |
27 // Constants used for intent request code bounding. | 22 // Constants used for intent request code bounding. |
28 private static final int REQUEST_CODE_PREFIX = 1000; | 23 private static final int REQUEST_CODE_PREFIX = 1000; |
29 private static final int REQUEST_CODE_RANGE_SIZE = 100; | 24 private static final int REQUEST_CODE_RANGE_SIZE = 100; |
30 // A string used as a key to store intent errors in a bundle | 25 // A string used as a key to store intent errors in a bundle |
31 static final String WINDOW_CALLBACK_ERRORS = "window_callback_errors"; | 26 static final String WINDOW_CALLBACK_ERRORS = "window_callback_errors"; |
32 | 27 |
33 // Native pointer to the c++ WindowAndroid object. | |
34 private int mNativeWindowAndroid = 0; | |
35 private int mNextRequestCode = 0; | 28 private int mNextRequestCode = 0; |
36 protected Activity mActivity; | 29 protected Activity mActivity; |
37 private SparseArray<IntentCallback> mOutstandingIntents; | 30 protected SparseArray<IntentCallback> mOutstandingIntents; |
38 private HashMap<Integer, String> mIntentErrors; | 31 protected HashMap<Integer, String> mIntentErrors; |
39 | 32 |
40 /** | 33 /** |
41 * An interface that intent callback objects have to implement. | 34 * @param activity |
42 */ | 35 */ |
43 public interface IntentCallback { | 36 public ActivityNativeWindow(Activity activity) { |
44 /** | 37 super(activity); |
45 * Handles the data returned by the requested intent. | 38 mActivity = activity; |
46 * @param window A window reference. | 39 mOutstandingIntents = new SparseArray<IntentCallback>(); |
47 * @param resultCode Result code of the requested intent. | 40 mIntentErrors = new HashMap<Integer, String>(); |
48 * @param contentResolver An instance of ContentResolver class for acces
sing returned data. | 41 |
49 * @param data The data returned by the intent. | |
50 */ | |
51 public void onIntentCompleted(NativeWindow window, int resultCode, | |
52 ContentResolver contentResolver, Intent data); | |
53 } | 42 } |
54 | 43 |
55 /** | 44 /** |
56 * Constructs a Window object, saves a reference to the main activity, and i
nitializes the | |
57 * outstanding intent map. NativeWindowAndroid gets lazily loaded on getNati
vePointer(). | |
58 * @param activity The main application activity. | |
59 */ | |
60 public NativeWindow(Activity activity) { | |
61 mActivity = activity; | |
62 mOutstandingIntents = new SparseArray<IntentCallback>(); | |
63 mIntentErrors = new HashMap<Integer, String>(); | |
64 mNativeWindowAndroid = 0; | |
65 } | |
66 | |
67 /** | |
68 * Destroys the c++ WindowAndroid object if one has been created. | |
69 */ | |
70 public void destroy() { | |
71 if (mNativeWindowAndroid != 0) { | |
72 nativeDestroy(mNativeWindowAndroid); | |
73 mNativeWindowAndroid = 0; | |
74 } | |
75 } | |
76 | |
77 /** | |
78 * Shows an intent and returns the results to the callback object. | |
79 * @param intent The intent that needs to be showed. | |
80 * @param callback The object that will receive the results for the intent. | |
81 * @return Whether the intent was shown. | |
82 */ | |
83 public boolean showIntent(Intent intent, IntentCallback callback) { | |
84 return showIntent(intent, callback, null); | |
85 } | |
86 | |
87 /** | |
88 * Shows an intent and returns the results to the callback object. | |
89 * @param intent The intent that needs to be showed. | |
90 * @param callback The object that will receive the results for the intent. | |
91 * @param errorId The id of the error string to be show if activity is pause
d before intent | |
92 * results. | |
93 * @return Whether the intent was shown. | |
94 */ | |
95 public boolean showIntent(Intent intent, IntentCallback callback, int errorI
d) { | |
96 String error = null; | |
97 try { | |
98 error = mActivity.getString(errorId); | |
99 } catch (Resources.NotFoundException e) { } | |
100 return showIntent(intent, callback, error); | |
101 } | |
102 | |
103 /** | |
104 * Shows an intent and returns the results to the callback object. | 45 * Shows an intent and returns the results to the callback object. |
105 * @param intent The intent that needs to be showed. | 46 * @param intent The intent that needs to be showed. |
106 * @param callback The object that will receive the results for the intent. | 47 * @param callback The object that will receive the results for the intent. |
107 * @param error The error string to be show if activity is paused before int
ent results. | 48 * @param error The error string to be show if activity is paused before int
ent results. |
108 * @return Whether the intent was shown. | 49 * @return Whether the intent was shown. |
109 */ | 50 */ |
| 51 @Override |
110 public boolean showIntent(Intent intent, IntentCallback callback, String err
or) { | 52 public boolean showIntent(Intent intent, IntentCallback callback, String err
or) { |
111 int requestCode = REQUEST_CODE_PREFIX + mNextRequestCode; | 53 int requestCode = REQUEST_CODE_PREFIX + mNextRequestCode; |
112 mNextRequestCode = (mNextRequestCode + 1) % REQUEST_CODE_RANGE_SIZE; | 54 mNextRequestCode = (mNextRequestCode + 1) % REQUEST_CODE_RANGE_SIZE; |
113 | 55 |
114 try { | 56 try { |
115 mActivity.startActivityForResult(intent, requestCode); | 57 mActivity.startActivityForResult(intent, requestCode); |
116 } catch (ActivityNotFoundException e) { | 58 } catch (ActivityNotFoundException e) { |
117 return false; | 59 return false; |
118 } | 60 } |
119 | 61 |
120 mOutstandingIntents.put(requestCode, callback); | 62 mOutstandingIntents.put(requestCode, callback); |
121 if (error != null) mIntentErrors.put(requestCode, error); | 63 if (error != null) mIntentErrors.put(requestCode, error); |
122 | 64 |
123 return true; | 65 return true; |
124 } | 66 } |
125 | 67 |
126 /** | 68 /** |
| 69 * Displays an error message with a provided error message string. |
| 70 * @param error The error message string to be displayed. |
| 71 */ |
| 72 @Override |
| 73 public void showError(String error) { |
| 74 if (error != null) { |
| 75 Toast.makeText(mActivity, error, Toast.LENGTH_SHORT).show(); |
| 76 } |
| 77 } |
| 78 |
| 79 /** |
| 80 * Displays an error message for a nonexistent callback. |
| 81 * @param error The error message string to be displayed. |
| 82 */ |
| 83 protected void showCallbackNonExistentError(String error) { |
| 84 showError(error); |
| 85 } |
| 86 |
| 87 /** |
| 88 * Broadcasts the given intent to all interested BroadcastReceivers. |
| 89 */ |
| 90 @Override |
| 91 public void sendBroadcast(Intent intent) { |
| 92 mActivity.sendBroadcast(intent); |
| 93 } |
| 94 |
| 95 /** |
| 96 * @return Application activity. |
| 97 */ |
| 98 public Activity getActivity() { |
| 99 return mActivity; |
| 100 } |
| 101 |
| 102 /** |
127 * Saves the error messages that should be shown if any pending intents woul
d return | 103 * Saves the error messages that should be shown if any pending intents woul
d return |
128 * after the application has been put onPause. | 104 * after the application has been put onPause. |
129 * @param bundle The bundle to save the information in onPause | 105 * @param bundle The bundle to save the information in onPause |
130 */ | 106 */ |
131 public void saveInstanceState(Bundle bundle) { | 107 public void saveInstanceState(Bundle bundle) { |
132 bundle.putSerializable(WINDOW_CALLBACK_ERRORS, mIntentErrors); | 108 bundle.putSerializable(WINDOW_CALLBACK_ERRORS, mIntentErrors); |
133 } | 109 } |
134 | 110 |
135 /** | 111 /** |
136 * Restores the error messages that should be shown if any pending intents w
ould return | 112 * Restores the error messages that should be shown if any pending intents w
ould return |
137 * after the application has been put onPause. | 113 * after the application has been put onPause. |
138 * @param bundle The bundle to restore the information from onResume | 114 * @param bundle The bundle to restore the information from onResume |
139 */ | 115 */ |
140 public void restoreInstanceState(Bundle bundle) { | 116 public void restoreInstanceState(Bundle bundle) { |
141 if (bundle == null) return; | 117 if (bundle == null) return; |
142 | 118 |
143 Object errors = bundle.getSerializable(WINDOW_CALLBACK_ERRORS); | 119 Object errors = bundle.getSerializable(WINDOW_CALLBACK_ERRORS); |
144 if (errors instanceof HashMap) { | 120 if (errors instanceof HashMap) { |
145 @SuppressWarnings("unchecked") | 121 @SuppressWarnings("unchecked") |
146 HashMap<Integer, String> intentErrors = (HashMap<Integer, String>) e
rrors; | 122 HashMap<Integer, String> intentErrors = (HashMap<Integer, String>) e
rrors; |
147 mIntentErrors = intentErrors; | 123 mIntentErrors = intentErrors; |
148 } | 124 } |
149 } | 125 } |
150 | 126 |
151 /** | 127 /** |
152 * Displays an error message with a provided error message string. | |
153 * @param error The error message string to be displayed. | |
154 */ | |
155 public void showError(String error) { | |
156 if (error != null) Toast.makeText(mActivity, error, Toast.LENGTH_SHORT).
show(); | |
157 } | |
158 | |
159 /** | |
160 * Displays an error message with a provided error message string id. | |
161 * @param errorId The string id of the error message string to be displayed. | |
162 */ | |
163 public void showError(int errorId) { | |
164 String error = null; | |
165 try { | |
166 error = mActivity.getString(errorId); | |
167 } catch (Resources.NotFoundException e) { } | |
168 showError(error); | |
169 } | |
170 | |
171 /** | |
172 * Displays an error message for a nonexistent callback. | |
173 * @param error The error message string to be displayed. | |
174 */ | |
175 protected void showCallbackNonExistentError(String error) { | |
176 showError(error); | |
177 } | |
178 | |
179 /** | |
180 * @return The main application activity. | |
181 */ | |
182 public Activity getActivity() { | |
183 return mActivity; | |
184 } | |
185 | |
186 /** | |
187 * Responds to the intent result if the intent was created by the native win
dow. | 128 * Responds to the intent result if the intent was created by the native win
dow. |
188 * @param requestCode Request code of the requested intent. | 129 * @param requestCode Request code of the requested intent. |
189 * @param resultCode Result code of the requested intent. | 130 * @param resultCode Result code of the requested intent. |
190 * @param data The data returned by the intent. | 131 * @param data The data returned by the intent. |
191 * @return Boolean value of whether the intent was started by the native win
dow. | 132 * @return Boolean value of whether the intent was started by the native win
dow. |
192 */ | 133 */ |
193 public boolean onActivityResult(int requestCode, int resultCode, Intent data
) { | 134 public boolean onActivityResult(int requestCode, int resultCode, Intent data
) { |
194 IntentCallback callback = mOutstandingIntents.get(requestCode); | 135 IntentCallback callback = mOutstandingIntents.get(requestCode); |
195 mOutstandingIntents.delete(requestCode); | 136 mOutstandingIntents.delete(requestCode); |
196 String errorMessage = mIntentErrors.remove(requestCode); | 137 String errorMessage = mIntentErrors.remove(requestCode); |
197 | 138 |
198 if (callback != null) { | 139 if (callback != null) { |
199 callback.onIntentCompleted(this, resultCode, | 140 callback.onIntentCompleted(this, resultCode, |
200 mActivity.getContentResolver(), data); | 141 mActivity.getContentResolver(), data); |
201 return true; | 142 return true; |
202 } else { | 143 } else { |
203 if (errorMessage != null) { | 144 if (errorMessage != null) { |
204 showCallbackNonExistentError(errorMessage); | 145 showCallbackNonExistentError(errorMessage); |
205 return true; | 146 return true; |
206 } | 147 } |
207 } | 148 } |
208 return false; | 149 return false; |
209 } | 150 } |
210 | 151 |
211 /** | |
212 * Returns a pointer to the c++ AndroidWindow object and calls the initializ
er if | |
213 * the object has not been previously initialized. | |
214 * @return A pointer to the c++ AndroidWindow. | |
215 */ | |
216 public int getNativePointer() { | |
217 if (mNativeWindowAndroid == 0) { | |
218 mNativeWindowAndroid = nativeInit(); | |
219 } | |
220 return mNativeWindowAndroid; | |
221 } | |
222 | |
223 private native int nativeInit(); | |
224 private native void nativeDestroy(int nativeWindowAndroid); | |
225 | |
226 } | 152 } |
OLD | NEW |