Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / ui / android / java / src / org / chromium / ui / base / WindowAndroid.java
1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.ui.base;
6
7 import android.app.PendingIntent;
8 import android.content.ContentResolver;
9 import android.content.Context;
10 import android.content.Intent;
11 import android.os.Bundle;
12 import android.util.Log;
13 import android.util.SparseArray;
14 import android.widget.Toast;
15
16 import org.chromium.base.CalledByNative;
17 import org.chromium.base.JNINamespace;
18
19 import java.util.HashMap;
20
21 /**
22  * The window base class that has the minimum functionality.
23  */
24 @JNINamespace("ui")
25 public class WindowAndroid {
26     private static final String TAG = "WindowAndroid";
27
28     // Native pointer to the c++ WindowAndroid object.
29     private long mNativeWindowAndroid = 0;
30
31     // A string used as a key to store intent errors in a bundle
32     static final String WINDOW_CALLBACK_ERRORS = "window_callback_errors";
33
34     // Error code returned when an Intent fails to start an Activity.
35     public static final int START_INTENT_FAILURE = -1;
36
37     protected Context mApplicationContext;
38     protected SparseArray<IntentCallback> mOutstandingIntents;
39     protected HashMap<Integer, String> mIntentErrors;
40
41     /**
42      * @param context The application context.
43      */
44     public WindowAndroid(Context context) {
45         assert context == context.getApplicationContext();
46         mApplicationContext = context;
47         mOutstandingIntents = new SparseArray<IntentCallback>();
48         mIntentErrors = new HashMap<Integer, String>();
49     }
50
51     /**
52      * Shows an intent and returns the results to the callback object.
53      * @param intent   The PendingIntent that needs to be shown.
54      * @param callback The object that will receive the results for the intent.
55      * @param errorId  The ID of error string to be show if activity is paused before intent
56      *                 results.
57      * @return Whether the intent was shown.
58      */
59     public boolean showIntent(PendingIntent intent, IntentCallback callback, int errorId) {
60         return showCancelableIntent(intent, callback, errorId) >= 0;
61     }
62
63     /**
64      * Shows an intent and returns the results to the callback object.
65      * @param intent   The intent that needs to be shown.
66      * @param callback The object that will receive the results for the intent.
67      * @param errorId  The ID of error string to be show if activity is paused before intent
68      *                 results.
69      * @return Whether the intent was shown.
70      */
71     public boolean showIntent(Intent intent, IntentCallback callback, int errorId) {
72         return showCancelableIntent(intent, callback, errorId) >= 0;
73     }
74
75     /**
76      * Shows an intent that could be canceled and returns the results to the callback object.
77      * @param  intent   The PendingIntent that needs to be shown.
78      * @param  callback The object that will receive the results for the intent.
79      * @param  errorId  The ID of error string to be show if activity is paused before intent
80      *                  results.
81      * @return A non-negative request code that could be used for finishActivity, or
82      *         START_INTENT_FAILURE if failed.
83      */
84     public int showCancelableIntent(PendingIntent intent, IntentCallback callback, int errorId) {
85         Log.d(TAG, "Can't show intent as context is not an Activity: " + intent);
86         return START_INTENT_FAILURE;
87     }
88
89     /**
90      * Shows an intent that could be canceled and returns the results to the callback object.
91      * @param  intent   The intent that needs to be showed.
92      * @param  callback The object that will receive the results for the intent.
93      * @param  errorId  The ID of error string to be show if activity is paused before intent
94      *                  results.
95      * @return A non-negative request code that could be used for finishActivity, or
96      *         START_INTENT_FAILURE if failed.
97      */
98     public int showCancelableIntent(Intent intent, IntentCallback callback, int errorId) {
99         Log.d(TAG, "Can't show intent as context is not an Activity: " + intent);
100         return START_INTENT_FAILURE;
101     }
102
103     /**
104      * Force finish another activity that you had previously started with showCancelableIntent.
105      * @param requestCode The request code returned from showCancelableIntent.
106      */
107     public void cancelIntent(int requestCode) {
108         Log.d(TAG, "Can't cancel intent as context is not an Activity: " + requestCode);
109     }
110
111     /**
112      * Removes a callback from the list of pending intents, so that nothing happens if/when the
113      * result for that intent is received.
114      * @param callback The object that should have received the results
115      * @return True if the callback was removed, false if it was not found.
116     */
117     public boolean removeIntentCallback(IntentCallback callback) {
118         int requestCode = mOutstandingIntents.indexOfValue(callback);
119         if (requestCode < 0) return false;
120         mOutstandingIntents.remove(requestCode);
121         mIntentErrors.remove(requestCode);
122         return true;
123     }
124
125     /**
126      * Displays an error message with a provided error message string.
127      * @param error The error message string to be displayed.
128      */
129     public void showError(String error) {
130         if (error != null) {
131             Toast.makeText(mApplicationContext, error, Toast.LENGTH_SHORT).show();
132         }
133     }
134
135     /**
136      * Displays an error message from the given resource id.
137      * @param resId The error message string's resource id.
138      */
139     public void showError(int resId) {
140         showError(mApplicationContext.getString(resId));
141     }
142
143     /**
144      * Displays an error message for a nonexistent callback.
145      * @param error The error message string to be displayed.
146      */
147     protected void showCallbackNonExistentError(String error) {
148         showError(error);
149     }
150
151     /**
152      * Broadcasts the given intent to all interested BroadcastReceivers.
153      */
154     public void sendBroadcast(Intent intent) {
155         mApplicationContext.sendBroadcast(intent);
156     }
157
158     /**
159      * TODO(nileshagrawal): Stop returning Activity Context crbug.com/233440.
160      * @return Activity context, it could be null. Note, in most cases, you probably
161      * just need Application Context returned by getApplicationContext().
162      * @see #getApplicationContext()
163      */
164     @Deprecated
165     public Context getContext() {
166         return null;
167     }
168
169     /**
170      * @return The application context for this activity.
171      */
172     public Context getApplicationContext() {
173         return mApplicationContext;
174     }
175
176     /**
177      * Saves the error messages that should be shown if any pending intents would return
178      * after the application has been put onPause.
179      * @param bundle The bundle to save the information in onPause
180      */
181     public void saveInstanceState(Bundle bundle) {
182         bundle.putSerializable(WINDOW_CALLBACK_ERRORS, mIntentErrors);
183     }
184
185     /**
186      * Restores the error messages that should be shown if any pending intents would return
187      * after the application has been put onPause.
188      * @param bundle The bundle to restore the information from onResume
189      */
190     public void restoreInstanceState(Bundle bundle) {
191         if (bundle == null) return;
192
193         Object errors = bundle.getSerializable(WINDOW_CALLBACK_ERRORS);
194         if (errors instanceof HashMap) {
195             @SuppressWarnings("unchecked")
196             HashMap<Integer, String> intentErrors = (HashMap<Integer, String>) errors;
197             mIntentErrors = intentErrors;
198         }
199     }
200
201     /**
202      * Responds to the intent result if the intent was created by the native window.
203      * @param requestCode Request code of the requested intent.
204      * @param resultCode Result code of the requested intent.
205      * @param data The data returned by the intent.
206      * @return Boolean value of whether the intent was started by the native window.
207      */
208     public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
209         return false;
210     }
211
212     /**
213      * An interface that intent callback objects have to implement.
214      */
215     public interface IntentCallback {
216         /**
217          * Handles the data returned by the requested intent.
218          * @param window A window reference.
219          * @param resultCode Result code of the requested intent.
220          * @param contentResolver An instance of ContentResolver class for accessing returned data.
221          * @param data The data returned by the intent.
222          */
223         public void onIntentCompleted(WindowAndroid window, int resultCode,
224                 ContentResolver contentResolver, Intent data);
225     }
226
227     /**
228      * Tests that an activity is available to handle the passed in intent.
229      * @param  intent The intent to check.
230      * @return True if an activity is available to process this intent when started, meaning that
231      *         Context.startActivity will not throw ActivityNotFoundException.
232      */
233     public boolean canResolveActivity(Intent intent) {
234         return mApplicationContext.getPackageManager().resolveActivity(intent, 0) != null;
235     }
236
237     /**
238      * Destroys the c++ WindowAndroid object if one has been created.
239      */
240     public void destroy() {
241         if (mNativeWindowAndroid != 0) {
242             nativeDestroy(mNativeWindowAndroid);
243             mNativeWindowAndroid = 0;
244         }
245     }
246
247     /**
248      * Returns a pointer to the c++ AndroidWindow object and calls the initializer if
249      * the object has not been previously initialized.
250      * @return A pointer to the c++ AndroidWindow.
251      */
252     public long getNativePointer() {
253         if (mNativeWindowAndroid == 0) {
254             mNativeWindowAndroid = nativeInit();
255         }
256         return mNativeWindowAndroid;
257     }
258
259     /**
260      * Returns a PNG-encoded screenshot of the the window region at (|windowX|,
261      * |windowY|) with the size |width| by |height| pixels.
262      */
263     @CalledByNative
264     public byte[] grabSnapshot(int windowX, int windowY, int width, int height) {
265         return null;
266     }
267
268     private native long nativeInit();
269     private native void nativeDestroy(long nativeWindowAndroid);
270
271 }