Chromium Code Reviews| 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; | 5 package org.chromium.ui; |
| 6 | 6 |
| 7 import android.app.Activity; | |
| 8 import android.content.ActivityNotFoundException; | |
| 9 import android.content.ContentResolver; | 7 import android.content.ContentResolver; |
| 10 import android.content.Context; | 8 import android.content.Context; |
| 11 import android.content.Intent; | 9 import android.content.Intent; |
| 12 import android.graphics.Bitmap; | |
| 13 import android.graphics.Rect; | |
| 14 import android.os.Bundle; | 10 import android.os.Bundle; |
| 15 import android.util.Log; | 11 import android.util.Log; |
| 16 import android.util.SparseArray; | 12 import android.util.SparseArray; |
| 17 import android.view.View; | |
| 18 import android.widget.Toast; | 13 import android.widget.Toast; |
| 19 | 14 |
| 20 import java.io.ByteArrayOutputStream; | |
| 21 import java.util.HashMap; | 15 import java.util.HashMap; |
| 22 | 16 |
| 23 import org.chromium.base.CalledByNative; | 17 import org.chromium.base.CalledByNative; |
| 24 import org.chromium.base.JNINamespace; | 18 import org.chromium.base.JNINamespace; |
| 25 | 19 |
| 26 /** | 20 /** |
| 27 * The window base class that has the minimum functionality. | 21 * The window base class that has the minimum functionality. |
| 28 */ | 22 */ |
| 29 @JNINamespace("ui") | 23 @JNINamespace("ui") |
| 30 public class WindowAndroid { | 24 public class WindowAndroid { |
| 25 // This simple class is used to prevent activity from being directly accesse d | |
| 26 // and output the alert if the activity is null. | |
| 27 private static void showActivityRequiredWarning() { | |
|
joth
2013/11/01 18:45:01
nit: show => log
michaelbai
2013/11/01 21:27:05
Done.
| |
| 28 Log.w(TAG, "Wrong type of Context, Activity's Context is required"); | |
|
joth
2013/11/01 18:45:01
"A Content of type Activity is required."
seems t
michaelbai
2013/11/01 21:27:05
Done.
This message is especially for the webview
| |
| 29 } | |
| 31 | 30 |
| 32 private static final String TAG = "WindowAndroid"; | 31 private static final String TAG = "WindowAndroid"; |
| 33 | 32 |
| 34 // Native pointer to the c++ WindowAndroid object. | 33 // Native pointer to the c++ WindowAndroid object. |
| 35 private int mNativeWindowAndroid = 0; | 34 private int mNativeWindowAndroid = 0; |
| 36 | 35 |
| 37 // Constants used for intent request code bounding. | |
| 38 private static final int REQUEST_CODE_PREFIX = 1000; | |
| 39 private static final int REQUEST_CODE_RANGE_SIZE = 100; | |
| 40 // A string used as a key to store intent errors in a bundle | 36 // A string used as a key to store intent errors in a bundle |
| 41 static final String WINDOW_CALLBACK_ERRORS = "window_callback_errors"; | 37 static final String WINDOW_CALLBACK_ERRORS = "window_callback_errors"; |
| 42 | 38 |
| 43 private int mNextRequestCode = 0; | |
| 44 protected Activity mActivity; | |
| 45 protected Context mApplicationContext; | 39 protected Context mApplicationContext; |
| 46 protected SparseArray<IntentCallback> mOutstandingIntents; | 40 protected SparseArray<IntentCallback> mOutstandingIntents; |
| 47 protected HashMap<Integer, String> mIntentErrors; | 41 protected HashMap<Integer, String> mIntentErrors; |
| 48 | 42 |
| 49 /** | 43 /** |
| 50 * @param activity | 44 * @param context, the application context.. |
| 51 */ | 45 */ |
| 52 public WindowAndroid(Activity activity) { | 46 public WindowAndroid(Context context) { |
| 53 mActivity = activity; | 47 assert context == context.getApplicationContext(); |
| 54 mApplicationContext = mActivity.getApplicationContext(); | 48 mApplicationContext = context; |
| 55 mOutstandingIntents = new SparseArray<IntentCallback>(); | 49 mOutstandingIntents = new SparseArray<IntentCallback>(); |
| 56 mIntentErrors = new HashMap<Integer, String>(); | 50 mIntentErrors = new HashMap<Integer, String>(); |
| 57 | |
| 58 } | 51 } |
| 59 | 52 |
| 60 /** | 53 /** |
| 61 * Shows an intent and returns the results to the callback object. | 54 * Shows an intent and returns the results to the callback object. |
| 62 * @param intent The intent that needs to be showed. | 55 * @param intent The intent that needs to be showed. |
| 63 * @param callback The object that will receive the results for the intent. | 56 * @param callback The object that will receive the results for the intent. |
| 64 * @param errorId The ID of error string to be show if activity is paused be fore intent | 57 * @param errorId The ID of error string to be show if activity is paused be fore intent |
| 65 * results. | 58 * results. |
| 66 * @return Whether the intent was shown. | 59 * @return Whether the intent was shown. |
| 67 */ | 60 */ |
| 68 public boolean showIntent(Intent intent, IntentCallback callback, int errorI d) { | 61 public boolean showIntent(Intent intent, IntentCallback callback, int errorI d) { |
| 69 int requestCode = REQUEST_CODE_PREFIX + mNextRequestCode; | 62 showActivityRequiredWarning(); |
| 70 mNextRequestCode = (mNextRequestCode + 1) % REQUEST_CODE_RANGE_SIZE; | 63 return false; |
| 71 | |
| 72 try { | |
| 73 mActivity.startActivityForResult(intent, requestCode); | |
| 74 } catch (ActivityNotFoundException e) { | |
| 75 return false; | |
| 76 } | |
| 77 | |
| 78 mOutstandingIntents.put(requestCode, callback); | |
| 79 mIntentErrors.put(requestCode, mActivity.getString(errorId)); | |
| 80 | |
| 81 return true; | |
| 82 } | 64 } |
| 83 | 65 |
| 84 /** | 66 /** |
| 85 * Displays an error message with a provided error message string. | 67 * Displays an error message with a provided error message string. |
| 86 * @param error The error message string to be displayed. | 68 * @param error The error message string to be displayed. |
| 87 */ | 69 */ |
| 88 public void showError(String error) { | 70 public void showError(String error) { |
| 89 if (error != null) { | 71 if (error != null) { |
| 90 Toast.makeText(mActivity, error, Toast.LENGTH_SHORT).show(); | 72 Toast.makeText(mApplicationContext, error, Toast.LENGTH_SHORT).show( ); |
| 91 } | 73 } |
| 92 } | 74 } |
| 93 | 75 |
| 94 /** | 76 /** |
| 95 * Displays an error message from the given resource id. | 77 * Displays an error message from the given resource id. |
| 96 * @param resId The error message string's resource id. | 78 * @param resId The error message string's resource id. |
| 97 */ | 79 */ |
| 98 public void showError(int resId) { | 80 public void showError(int resId) { |
| 99 showError(mActivity.getString(resId)); | 81 showError(mApplicationContext.getString(resId)); |
| 100 } | 82 } |
| 101 | 83 |
| 102 /** | 84 /** |
| 103 * Displays an error message for a nonexistent callback. | 85 * Displays an error message for a nonexistent callback. |
| 104 * @param error The error message string to be displayed. | 86 * @param error The error message string to be displayed. |
| 105 */ | 87 */ |
| 106 protected void showCallbackNonExistentError(String error) { | 88 protected void showCallbackNonExistentError(String error) { |
| 107 showError(error); | 89 showError(error); |
| 108 } | 90 } |
| 109 | 91 |
| 110 /** | 92 /** |
| 111 * Broadcasts the given intent to all interested BroadcastReceivers. | 93 * Broadcasts the given intent to all interested BroadcastReceivers. |
| 112 */ | 94 */ |
| 113 public void sendBroadcast(Intent intent) { | 95 public void sendBroadcast(Intent intent) { |
| 114 mActivity.sendBroadcast(intent); | 96 mApplicationContext.sendBroadcast(intent); |
| 115 } | 97 } |
| 116 | 98 |
| 117 /** | 99 /** |
| 118 * TODO(nileshagrawal): Stop returning Activity Context crbug.com/233440. | 100 * TODO(nileshagrawal): Stop returning Activity Context crbug.com/233440. |
| 119 * @return Activity context. | 101 * @return Activity context, it could be null. Note, in most cases, you prob ably |
| 102 * just need Application Context returned by getApplicationContext(). | |
| 120 * @see #getApplicationContext() | 103 * @see #getApplicationContext() |
| 121 */ | 104 */ |
| 122 @Deprecated | 105 @Deprecated |
| 123 public Context getContext() { | 106 public Context getContext() { |
|
joth
2013/11/01 18:45:01
can we remove this from the base class? (it's depr
michaelbai
2013/11/01 21:27:05
There are some usages in clank. I would remove the
| |
| 124 return mActivity; | 107 showActivityRequiredWarning(); |
| 108 return null; | |
| 125 } | 109 } |
| 126 | 110 |
| 127 /** | 111 /** |
| 128 * @return The application context for this activity. | 112 * @return The application context for this activity. |
| 129 */ | 113 */ |
| 130 public Context getApplicationContext() { | 114 public Context getApplicationContext() { |
| 131 return mApplicationContext; | 115 return mApplicationContext; |
| 132 } | 116 } |
| 133 | 117 |
| 134 /** | 118 /** |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 157 } | 141 } |
| 158 | 142 |
| 159 /** | 143 /** |
| 160 * Responds to the intent result if the intent was created by the native win dow. | 144 * Responds to the intent result if the intent was created by the native win dow. |
| 161 * @param requestCode Request code of the requested intent. | 145 * @param requestCode Request code of the requested intent. |
| 162 * @param resultCode Result code of the requested intent. | 146 * @param resultCode Result code of the requested intent. |
| 163 * @param data The data returned by the intent. | 147 * @param data The data returned by the intent. |
| 164 * @return Boolean value of whether the intent was started by the native win dow. | 148 * @return Boolean value of whether the intent was started by the native win dow. |
| 165 */ | 149 */ |
| 166 public boolean onActivityResult(int requestCode, int resultCode, Intent data ) { | 150 public boolean onActivityResult(int requestCode, int resultCode, Intent data ) { |
| 167 IntentCallback callback = mOutstandingIntents.get(requestCode); | 151 showActivityRequiredWarning(); |
| 168 mOutstandingIntents.delete(requestCode); | |
| 169 String errorMessage = mIntentErrors.remove(requestCode); | |
| 170 | |
| 171 if (callback != null) { | |
| 172 callback.onIntentCompleted(this, resultCode, | |
| 173 mActivity.getContentResolver(), data); | |
| 174 return true; | |
| 175 } else { | |
| 176 if (errorMessage != null) { | |
| 177 showCallbackNonExistentError(errorMessage); | |
| 178 return true; | |
| 179 } | |
| 180 } | |
| 181 return false; | 152 return false; |
| 182 } | 153 } |
| 183 | 154 |
| 184 /** | 155 /** |
| 185 * An interface that intent callback objects have to implement. | 156 * An interface that intent callback objects have to implement. |
| 186 */ | 157 */ |
| 187 public interface IntentCallback { | 158 public interface IntentCallback { |
| 188 /** | 159 /** |
| 189 * Handles the data returned by the requested intent. | 160 * Handles the data returned by the requested intent. |
| 190 * @param window A window reference. | 161 * @param window A window reference. |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 217 } | 188 } |
| 218 return mNativeWindowAndroid; | 189 return mNativeWindowAndroid; |
| 219 } | 190 } |
| 220 | 191 |
| 221 /** | 192 /** |
| 222 * Returns a PNG-encoded screenshot of the the window region at (|windowX|, | 193 * Returns a PNG-encoded screenshot of the the window region at (|windowX|, |
| 223 * |windowY|) with the size |width| by |height| pixels. | 194 * |windowY|) with the size |width| by |height| pixels. |
| 224 */ | 195 */ |
| 225 @CalledByNative | 196 @CalledByNative |
| 226 public byte[] grabSnapshot(int windowX, int windowY, int width, int height) { | 197 public byte[] grabSnapshot(int windowX, int windowY, int width, int height) { |
| 227 try { | 198 showActivityRequiredWarning(); |
| 228 // Take a screenshot of the root activity view. This generally inclu des UI | 199 return null; |
| 229 // controls such as the URL bar and OS windows such as the status ba r. | |
| 230 View rootView = mActivity.findViewById(android.R.id.content).getRoot View(); | |
| 231 Bitmap bitmap = UiUtils.generateScaledScreenshot(rootView, 0, Bitmap .Config.ARGB_8888); | |
| 232 if (bitmap == null) return null; | |
| 233 | |
| 234 // Clip the result into the requested region. | |
| 235 if (windowX > 0 || windowY > 0 || width != bitmap.getWidth() || | |
| 236 height != bitmap.getHeight()) { | |
| 237 Rect clip = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight() ); | |
| 238 clip.intersect(windowX, windowY, windowX + width, windowY + heig ht); | |
| 239 bitmap = Bitmap.createBitmap( | |
| 240 bitmap, clip.left, clip.top, clip.width(), clip.height() ); | |
| 241 } | |
| 242 | |
| 243 // Compress the result into a PNG. | |
| 244 ByteArrayOutputStream result = new ByteArrayOutputStream(); | |
| 245 if (!bitmap.compress(Bitmap.CompressFormat.PNG, 100, result)) return null; | |
| 246 bitmap.recycle(); | |
| 247 return result.toByteArray(); | |
| 248 } catch (OutOfMemoryError e) { | |
| 249 Log.e(TAG, "Out of memory while grabbing window snapshot.", e); | |
| 250 return null; | |
| 251 } | |
| 252 } | 200 } |
| 253 | 201 |
| 254 private native int nativeInit(); | 202 private native int nativeInit(); |
| 255 private native void nativeDestroy(int nativeWindowAndroid); | 203 private native void nativeDestroy(int nativeWindowAndroid); |
| 256 | 204 |
| 257 } | 205 } |
| OLD | NEW |