1 // Copyright 2013 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.Activity; 8 import android.app.PendingIntent; 9 import android.content.ActivityNotFoundException; 10 import android.content.Intent; 11 import android.content.IntentSender.SendIntentException; 12 13 import java.lang.ref.WeakReference; 14 15 /** 16 * The class provides the WindowAndroid's implementation which requires 17 * Activity Instance. 18 * Only instantiate this class when you need the implemented features. 19 */ 20 public class ActivityWindowAndroid extends WindowAndroid { 21 // Constants used for intent request code bounding. 22 private static final int REQUEST_CODE_PREFIX = 1000; 23 private static final int REQUEST_CODE_RANGE_SIZE = 100; 24 private static final String TAG = "ActivityWindowAndroid"; 25 26 private final WeakReference<Activity> mActivityRef; 27 private int mNextRequestCode = 0; 28 29 public ActivityWindowAndroid(Activity activity) { 30 super(activity.getApplicationContext()); 31 mActivityRef = new WeakReference<Activity>(activity); 32 } 33 34 @Override 35 public int showCancelableIntent(PendingIntent intent, IntentCallback callback, int errorId) { 36 Activity activity = mActivityRef.get(); 37 if (activity == null) return START_INTENT_FAILURE; 38 39 int requestCode = generateNextRequestCode(); 40 41 try { 42 activity.startIntentSenderForResult( 43 intent.getIntentSender(), requestCode, new Intent(), 0, 0, 0); 44 } catch (SendIntentException e) { 45 return START_INTENT_FAILURE; 46 } 47 48 storeCallbackData(requestCode, callback, errorId); 49 return requestCode; 50 } 51 52 @Override 53 public int showCancelableIntent(Intent intent, IntentCallback callback, int errorId) { 54 Activity activity = mActivityRef.get(); 55 if (activity == null) return START_INTENT_FAILURE; 56 57 int requestCode = generateNextRequestCode(); 58 59 try { 60 activity.startActivityForResult(intent, requestCode); 61 } catch (ActivityNotFoundException e) { 62 return START_INTENT_FAILURE; 63 } 64 65 storeCallbackData(requestCode, callback, errorId); 66 return requestCode; 67 } 68 69 @Override 70 public void cancelIntent(int requestCode) { 71 Activity activity = mActivityRef.get(); 72 if (activity == null) return; 73 activity.finishActivity(requestCode); 74 } 75 76 @Override 77 public boolean onActivityResult(int requestCode, int resultCode, Intent data) { 78 IntentCallback callback = mOutstandingIntents.get(requestCode); 79 mOutstandingIntents.delete(requestCode); 80 String errorMessage = mIntentErrors.remove(requestCode); 81 82 if (callback != null) { 83 callback.onIntentCompleted(this, resultCode, 84 mApplicationContext.getContentResolver(), data); 85 return true; 86 } else { 87 if (errorMessage != null) { 88 showCallbackNonExistentError(errorMessage); 89 return true; 90 } 91 } 92 return false; 93 } 94 95 @Override 96 public WeakReference<Activity> getActivity() { 97 // Return a new WeakReference to prevent clients from releasing our internal WeakReference. 98 return new WeakReference<Activity>(mActivityRef.get()); 99 } 100 101 private int generateNextRequestCode() { 102 int requestCode = REQUEST_CODE_PREFIX + mNextRequestCode; 103 mNextRequestCode = (mNextRequestCode + 1) % REQUEST_CODE_RANGE_SIZE; 104 return requestCode; 105 } 106 107 private void storeCallbackData(int requestCode, IntentCallback callback, int errorId) { 108 mOutstandingIntents.put(requestCode, callback); 109 mIntentErrors.put(requestCode, mApplicationContext.getString(errorId)); 110 } 111 } 112