• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.launcher3;
18 
19 import static com.android.launcher3.util.SystemUiController.UI_STATE_OVERVIEW;
20 
21 import static java.lang.annotation.RetentionPolicy.SOURCE;
22 
23 import android.app.Activity;
24 import android.content.Context;
25 import android.content.ContextWrapper;
26 import android.content.Intent;
27 import android.content.res.Configuration;
28 import android.support.annotation.IntDef;
29 import android.view.View.AccessibilityDelegate;
30 
31 import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
32 import com.android.launcher3.logging.UserEventDispatcher;
33 import com.android.launcher3.logging.UserEventDispatcher.UserEventDelegate;
34 import com.android.launcher3.uioverrides.UiFactory;
35 import com.android.launcher3.userevent.nano.LauncherLogProto;
36 import com.android.launcher3.util.SystemUiController;
37 
38 import java.io.FileDescriptor;
39 import java.io.PrintWriter;
40 import java.lang.annotation.Retention;
41 import java.util.ArrayList;
42 
43 public abstract class BaseActivity extends Activity implements UserEventDelegate{
44 
45     public static final int INVISIBLE_BY_STATE_HANDLER = 1 << 0;
46     public static final int INVISIBLE_BY_APP_TRANSITIONS = 1 << 1;
47     public static final int INVISIBLE_ALL =
48             INVISIBLE_BY_STATE_HANDLER | INVISIBLE_BY_APP_TRANSITIONS;
49 
50     @Retention(SOURCE)
51     @IntDef(
52             flag = true,
53             value = {INVISIBLE_BY_STATE_HANDLER, INVISIBLE_BY_APP_TRANSITIONS})
54     public @interface InvisibilityFlags{}
55 
56     private final ArrayList<OnDeviceProfileChangeListener> mDPChangeListeners = new ArrayList<>();
57     private final ArrayList<MultiWindowModeChangedListener> mMultiWindowModeChangedListeners =
58             new ArrayList<>();
59 
60     protected DeviceProfile mDeviceProfile;
61     protected UserEventDispatcher mUserEventDispatcher;
62     protected SystemUiController mSystemUiController;
63 
64     private static final int ACTIVITY_STATE_STARTED = 1 << 0;
65     private static final int ACTIVITY_STATE_RESUMED = 1 << 1;
66     /**
67      * State flag indicating if the user is active or the actitvity when to background as a result
68      * of user action.
69      * @see #isUserActive()
70      */
71     private static final int ACTIVITY_STATE_USER_ACTIVE = 1 << 2;
72 
73     @Retention(SOURCE)
74     @IntDef(
75             flag = true,
76             value = {ACTIVITY_STATE_STARTED, ACTIVITY_STATE_RESUMED, ACTIVITY_STATE_USER_ACTIVE})
77     public @interface ActivityFlags{}
78 
79     @ActivityFlags
80     private int mActivityFlags;
81 
82     // When the recents animation is running, the visibility of the Launcher is managed by the
83     // animation
84     @InvisibilityFlags private int mForceInvisible;
85 
getDeviceProfile()86     public DeviceProfile getDeviceProfile() {
87         return mDeviceProfile;
88     }
89 
getAccessibilityDelegate()90     public AccessibilityDelegate getAccessibilityDelegate() {
91         return null;
92     }
93 
modifyUserEvent(LauncherLogProto.LauncherEvent event)94     public void modifyUserEvent(LauncherLogProto.LauncherEvent event) {}
95 
getUserEventDispatcher()96     public final UserEventDispatcher getUserEventDispatcher() {
97         if (mUserEventDispatcher == null) {
98             mUserEventDispatcher = UserEventDispatcher.newInstance(this, mDeviceProfile, this);
99         }
100         return mUserEventDispatcher;
101     }
102 
isInMultiWindowModeCompat()103     public boolean isInMultiWindowModeCompat() {
104         return Utilities.ATLEAST_NOUGAT && isInMultiWindowMode();
105     }
106 
fromContext(Context context)107     public static BaseActivity fromContext(Context context) {
108         if (context instanceof BaseActivity) {
109             return (BaseActivity) context;
110         }
111         return ((BaseActivity) ((ContextWrapper) context).getBaseContext());
112     }
113 
getSystemUiController()114     public SystemUiController getSystemUiController() {
115         if (mSystemUiController == null) {
116             mSystemUiController = new SystemUiController(getWindow());
117         }
118         return mSystemUiController;
119     }
120 
121     @Override
onActivityResult(int requestCode, int resultCode, Intent data)122     public void onActivityResult(int requestCode, int resultCode, Intent data) {
123         super.onActivityResult(requestCode, resultCode, data);
124     }
125 
126     @Override
onStart()127     protected void onStart() {
128         mActivityFlags |= ACTIVITY_STATE_STARTED;
129         super.onStart();
130     }
131 
132     @Override
onResume()133     protected void onResume() {
134         mActivityFlags |= ACTIVITY_STATE_RESUMED | ACTIVITY_STATE_USER_ACTIVE;
135         super.onResume();
136     }
137 
138     @Override
onUserLeaveHint()139     protected void onUserLeaveHint() {
140         mActivityFlags &= ~ACTIVITY_STATE_USER_ACTIVE;
141         super.onUserLeaveHint();
142     }
143 
144     @Override
onMultiWindowModeChanged(boolean isInMultiWindowMode, Configuration newConfig)145     public void onMultiWindowModeChanged(boolean isInMultiWindowMode, Configuration newConfig) {
146         super.onMultiWindowModeChanged(isInMultiWindowMode, newConfig);
147         for (int i = mMultiWindowModeChangedListeners.size() - 1; i >= 0; i--) {
148             mMultiWindowModeChangedListeners.get(i).onMultiWindowModeChanged(isInMultiWindowMode);
149         }
150     }
151 
152     @Override
onStop()153     protected void onStop() {
154         mActivityFlags &= ~ACTIVITY_STATE_STARTED & ~ACTIVITY_STATE_USER_ACTIVE;
155         mForceInvisible = 0;
156         super.onStop();
157     }
158 
159     @Override
onPause()160     protected void onPause() {
161         mActivityFlags &= ~ACTIVITY_STATE_RESUMED;
162         super.onPause();
163 
164         // Reset the overridden sysui flags used for the task-swipe launch animation, we do this
165         // here instead of at the end of the animation because the start of the new activity does
166         // not happen immediately, which would cause us to reset to launcher's sysui flags and then
167         // back to the new app (causing a flash)
168         getSystemUiController().updateUiState(UI_STATE_OVERVIEW, 0);
169     }
170 
isStarted()171     public boolean isStarted() {
172         return (mActivityFlags & ACTIVITY_STATE_STARTED) != 0;
173     }
174 
175     /**
176      * isResumed in already defined as a hidden final method in Activity.java
177      */
hasBeenResumed()178     public boolean hasBeenResumed() {
179         return (mActivityFlags & ACTIVITY_STATE_RESUMED) != 0;
180     }
181 
isUserActive()182     public boolean isUserActive() {
183         return (mActivityFlags & ACTIVITY_STATE_USER_ACTIVE) != 0;
184     }
185 
addOnDeviceProfileChangeListener(OnDeviceProfileChangeListener listener)186     public void addOnDeviceProfileChangeListener(OnDeviceProfileChangeListener listener) {
187         mDPChangeListeners.add(listener);
188     }
189 
removeOnDeviceProfileChangeListener(OnDeviceProfileChangeListener listener)190     public void removeOnDeviceProfileChangeListener(OnDeviceProfileChangeListener listener) {
191         mDPChangeListeners.remove(listener);
192     }
193 
dispatchDeviceProfileChanged()194     protected void dispatchDeviceProfileChanged() {
195         for (int i = mDPChangeListeners.size() - 1; i >= 0; i--) {
196             mDPChangeListeners.get(i).onDeviceProfileChanged(mDeviceProfile);
197         }
198     }
199 
addMultiWindowModeChangedListener(MultiWindowModeChangedListener listener)200     public void addMultiWindowModeChangedListener(MultiWindowModeChangedListener listener) {
201         mMultiWindowModeChangedListeners.add(listener);
202     }
203 
removeMultiWindowModeChangedListener(MultiWindowModeChangedListener listener)204     public void removeMultiWindowModeChangedListener(MultiWindowModeChangedListener listener) {
205         mMultiWindowModeChangedListeners.remove(listener);
206     }
207 
208     /**
209      * Used to set the override visibility state, used only to handle the transition home with the
210      * recents animation.
211      * @see LauncherAppTransitionManagerImpl.getWallpaperOpenRunner()
212      */
addForceInvisibleFlag(@nvisibilityFlags int flag)213     public void addForceInvisibleFlag(@InvisibilityFlags int flag) {
214         mForceInvisible |= flag;
215     }
216 
clearForceInvisibleFlag(@nvisibilityFlags int flag)217     public void clearForceInvisibleFlag(@InvisibilityFlags int flag) {
218         mForceInvisible &= ~flag;
219     }
220 
221 
222     /**
223      * @return Wether this activity should be considered invisible regardless of actual visibility.
224      */
isForceInvisible()225     public boolean isForceInvisible() {
226         return mForceInvisible != 0;
227     }
228 
229     public interface MultiWindowModeChangedListener {
onMultiWindowModeChanged(boolean isInMultiWindowMode)230         void onMultiWindowModeChanged(boolean isInMultiWindowMode);
231     }
232 
233     @Override
dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args)234     public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
235         if (!UiFactory.dumpActivity(this, writer)) {
236             super.dump(prefix, fd, writer, args);
237         }
238     }
239 
dumpMisc(PrintWriter writer)240     protected void dumpMisc(PrintWriter writer) {
241         writer.println(" deviceProfile isTransposed=" + getDeviceProfile().isVerticalBarLayout());
242         writer.println(" orientation=" + getResources().getConfiguration().orientation);
243         writer.println(" mSystemUiController: " + mSystemUiController);
244         writer.println(" mActivityFlags: " + mActivityFlags);
245         writer.println(" mForceInvisible: " + mForceInvisible);
246     }
247 }
248