WindowAndroid.java revision 558790d6acca3451cf3a6b497803a5f07d0bec58
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 3// found in the LICENSE file. 4 5package org.chromium.ui; 6 7import android.app.Activity; 8import android.content.ActivityNotFoundException; 9import android.content.ContentResolver; 10import android.content.Context; 11import android.content.Intent; 12import android.os.Bundle; 13import android.util.SparseArray; 14import android.view.WindowManager; 15import android.widget.Toast; 16 17import java.util.HashMap; 18 19import org.chromium.base.JNINamespace; 20 21/** 22 * The window base class that has the minimum functionality. 23 */ 24@JNINamespace("ui") 25public class WindowAndroid { 26 27 // Native pointer to the c++ WindowAndroid object. 28 private int mNativeWindowAndroid = 0; 29 30 // Constants used for intent request code bounding. 31 private static final int REQUEST_CODE_PREFIX = 1000; 32 private static final int REQUEST_CODE_RANGE_SIZE = 100; 33 // A string used as a key to store intent errors in a bundle 34 static final String WINDOW_CALLBACK_ERRORS = "window_callback_errors"; 35 36 private int mNextRequestCode = 0; 37 protected Activity mActivity; 38 protected SparseArray<IntentCallback> mOutstandingIntents; 39 protected HashMap<Integer, String> mIntentErrors; 40 41 /** 42 * @param activity 43 */ 44 public WindowAndroid(Activity activity) { 45 mActivity = activity; 46 mOutstandingIntents = new SparseArray<IntentCallback>(); 47 mIntentErrors = new HashMap<Integer, String>(); 48 49 } 50 51 /** 52 * Shows an intent and returns the results to the callback object. 53 * @param intent The intent that needs to be showed. 54 * @param callback The object that will receive the results for the intent. 55 * @param error The error string to be show if activity is paused before intent results. 56 * @return Whether the intent was shown. 57 */ 58 public boolean showIntent(Intent intent, IntentCallback callback, String error) { 59 int requestCode = REQUEST_CODE_PREFIX + mNextRequestCode; 60 mNextRequestCode = (mNextRequestCode + 1) % REQUEST_CODE_RANGE_SIZE; 61 62 try { 63 mActivity.startActivityForResult(intent, requestCode); 64 } catch (ActivityNotFoundException e) { 65 return false; 66 } 67 68 mOutstandingIntents.put(requestCode, callback); 69 if (error != null) mIntentErrors.put(requestCode, error); 70 71 return true; 72 } 73 74 /** 75 * Displays an error message with a provided error message string. 76 * @param error The error message string to be displayed. 77 */ 78 public void showError(String error) { 79 if (error != null) { 80 Toast.makeText(mActivity, error, Toast.LENGTH_SHORT).show(); 81 } 82 } 83 84 /** 85 * Displays an error message from the given resource id. 86 * @param resId The error message string's resource id. 87 */ 88 public void showError(int resId) { 89 showError(mActivity.getString(resId)); 90 } 91 92 /** 93 * Displays an error message for a nonexistent callback. 94 * @param error The error message string to be displayed. 95 */ 96 protected void showCallbackNonExistentError(String error) { 97 showError(error); 98 } 99 100 /** 101 * Broadcasts the given intent to all interested BroadcastReceivers. 102 */ 103 public void sendBroadcast(Intent intent) { 104 mActivity.sendBroadcast(intent); 105 } 106 107 /** 108 * TODO(nileshagrawal): Stop returning Activity Context crbug.com/233440. 109 * @return Activity context. 110 */ 111 @Deprecated 112 public Context getContext() { 113 return mActivity; 114 } 115 116 /** 117 * Saves the error messages that should be shown if any pending intents would return 118 * after the application has been put onPause. 119 * @param bundle The bundle to save the information in onPause 120 */ 121 public void saveInstanceState(Bundle bundle) { 122 bundle.putSerializable(WINDOW_CALLBACK_ERRORS, mIntentErrors); 123 } 124 125 /** 126 * Restores the error messages that should be shown if any pending intents would return 127 * after the application has been put onPause. 128 * @param bundle The bundle to restore the information from onResume 129 */ 130 public void restoreInstanceState(Bundle bundle) { 131 if (bundle == null) return; 132 133 Object errors = bundle.getSerializable(WINDOW_CALLBACK_ERRORS); 134 if (errors instanceof HashMap) { 135 @SuppressWarnings("unchecked") 136 HashMap<Integer, String> intentErrors = (HashMap<Integer, String>) errors; 137 mIntentErrors = intentErrors; 138 } 139 } 140 141 /** 142 * Responds to the intent result if the intent was created by the native window. 143 * @param requestCode Request code of the requested intent. 144 * @param resultCode Result code of the requested intent. 145 * @param data The data returned by the intent. 146 * @return Boolean value of whether the intent was started by the native window. 147 */ 148 public boolean onActivityResult(int requestCode, int resultCode, Intent data) { 149 IntentCallback callback = mOutstandingIntents.get(requestCode); 150 mOutstandingIntents.delete(requestCode); 151 String errorMessage = mIntentErrors.remove(requestCode); 152 153 if (callback != null) { 154 callback.onIntentCompleted(this, resultCode, 155 mActivity.getContentResolver(), data); 156 return true; 157 } else { 158 if (errorMessage != null) { 159 showCallbackNonExistentError(errorMessage); 160 return true; 161 } 162 } 163 return false; 164 } 165 166 /** 167 * An interface that intent callback objects have to implement. 168 */ 169 public interface IntentCallback { 170 /** 171 * Handles the data returned by the requested intent. 172 * @param window A window reference. 173 * @param resultCode Result code of the requested intent. 174 * @param contentResolver An instance of ContentResolver class for accessing returned data. 175 * @param data The data returned by the intent. 176 */ 177 public void onIntentCompleted(WindowAndroid window, int resultCode, 178 ContentResolver contentResolver, Intent data); 179 } 180 181 /** 182 * Destroys the c++ WindowAndroid object if one has been created. 183 */ 184 public void destroy() { 185 if (mNativeWindowAndroid != 0) { 186 nativeDestroy(mNativeWindowAndroid); 187 mNativeWindowAndroid = 0; 188 } 189 } 190 191 /** 192 * Returns a pointer to the c++ AndroidWindow object and calls the initializer if 193 * the object has not been previously initialized. 194 * @return A pointer to the c++ AndroidWindow. 195 */ 196 public int getNativePointer() { 197 if (mNativeWindowAndroid == 0) { 198 mNativeWindowAndroid = nativeInit(); 199 } 200 return mNativeWindowAndroid; 201 } 202 203 public void keepScreenOn(boolean screenOn) { 204 if (screenOn) { 205 mActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 206 } else { 207 mActivity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 208 } 209 } 210 211 private native int nativeInit(); 212 private native void nativeDestroy(int nativeWindowAndroid); 213 214} 215