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.content.ActivityNotFoundException;
9 import android.content.Context;
10 import android.content.Intent;
11 import android.content.IntentSender;
12 import android.content.IntentSender.SendIntentException;
13 
14 import org.chromium.base.ActivityState;
15 import org.chromium.base.ApplicationStatus;
16 import org.chromium.base.ContextUtils;
17 
18 import java.lang.ref.WeakReference;
19 
20 /**
21  * The class provides the WindowAndroid's implementation which requires
22  * Activity Instance.
23  * Only instantiate this class when you need the implemented features.
24  */
25 public class ActivityWindowAndroid
26         extends IntentWindowAndroid implements ApplicationStatus.ActivityStateListener {
27     private boolean mListenToActivityState;
28 
29     // Just create one ImmutableWeakReference object to avoid gc churn.
30     private ImmutableWeakReference<Activity> mActivityWeakRefHolder;
31 
32     /**
33      * Creates an Activity-specific WindowAndroid with associated intent functionality.
34      * TODO(jdduke): Remove this overload when all callsites have been updated to
35      * indicate their activity state listening preference.
36      * @param context Context wrapping an activity associated with the WindowAndroid.
37      */
ActivityWindowAndroid(Context context)38     public ActivityWindowAndroid(Context context) {
39         this(context, true);
40     }
41 
42     /**
43      * Creates an Activity-specific WindowAndroid with associated intent functionality.
44      * @param context Context wrapping an activity associated with the WindowAndroid.
45      * @param listenToActivityState Whether to listen to activity state changes.
46      */
ActivityWindowAndroid(Context context, boolean listenToActivityState)47     public ActivityWindowAndroid(Context context, boolean listenToActivityState) {
48         super(context);
49         Activity activity = ContextUtils.activityFromContext(context);
50         if (activity == null) {
51             throw new IllegalArgumentException("Context is not and does not wrap an Activity");
52         }
53         mListenToActivityState = listenToActivityState;
54         if (listenToActivityState) {
55             ApplicationStatus.registerStateListenerForActivity(this, activity);
56         }
57 
58         setKeyboardDelegate(createKeyboardVisibilityDelegate());
59         setAndroidPermissionDelegate(createAndroidPermissionDelegate());
60     }
61 
createAndroidPermissionDelegate()62     protected ActivityAndroidPermissionDelegate createAndroidPermissionDelegate() {
63         return new ActivityAndroidPermissionDelegate(getActivity());
64     }
65 
createKeyboardVisibilityDelegate()66     protected ActivityKeyboardVisibilityDelegate createKeyboardVisibilityDelegate() {
67         return new ActivityKeyboardVisibilityDelegate(getActivity());
68     }
69 
70     @Override
getKeyboardDelegate()71     public ActivityKeyboardVisibilityDelegate getKeyboardDelegate() {
72         return (ActivityKeyboardVisibilityDelegate) super.getKeyboardDelegate();
73     }
74 
75     @Override
startIntentSenderForResult(IntentSender intentSender, int requestCode)76     protected final boolean startIntentSenderForResult(IntentSender intentSender, int requestCode) {
77         Activity activity = getActivity().get();
78         if (activity == null) return false;
79 
80         try {
81             activity.startIntentSenderForResult(intentSender, requestCode, new Intent(), 0, 0, 0);
82         } catch (SendIntentException e) {
83             return false;
84         }
85         return true;
86     }
87 
88     @Override
startActivityForResult(Intent intent, int requestCode)89     protected final boolean startActivityForResult(Intent intent, int requestCode) {
90         Activity activity = getActivity().get();
91         if (activity == null) return false;
92 
93         try {
94             activity.startActivityForResult(intent, requestCode);
95         } catch (ActivityNotFoundException e) {
96             return false;
97         }
98         return true;
99     }
100 
101     @Override
getActivity()102     public WeakReference<Activity> getActivity() {
103         if (mActivityWeakRefHolder == null) {
104             mActivityWeakRefHolder = new ImmutableWeakReference<>(
105                     ContextUtils.activityFromContext(getContext().get()));
106         }
107         return mActivityWeakRefHolder;
108     }
109 
110     @Override
onActivityStateChange(Activity activity, int newState)111     public void onActivityStateChange(Activity activity, int newState) {
112         if (newState == ActivityState.STOPPED) {
113             onActivityStopped();
114         } else if (newState == ActivityState.STARTED) {
115             onActivityStarted();
116         } else if (newState == ActivityState.PAUSED) {
117             onActivityPaused();
118         } else if (newState == ActivityState.RESUMED) {
119             onActivityResumed();
120         }
121     }
122 
123     @Override
124     @ActivityState
getActivityState()125     public int getActivityState() {
126         return mListenToActivityState ? ApplicationStatus.getStateForActivity(getActivity().get())
127                                       : super.getActivityState();
128     }
129 }
130