blob: a41edc08b4cf51d4462e95f93d0791ff2ae9a139 [file] [log] [blame]
Sunny Goyal27835952017-01-13 12:15:53 -08001/*
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
17package com.android.launcher3;
18
Sunny Goyal7eff40f2018-04-11 15:30:46 -070019import static java.lang.annotation.RetentionPolicy.SOURCE;
20
Sunny Goyal27835952017-01-13 12:15:53 -080021import android.app.Activity;
22import android.content.Context;
23import android.content.ContextWrapper;
Sunny Goyal64a75aa2017-07-03 13:50:52 -070024import android.content.Intent;
Winson Chung1a77c3d2018-04-11 12:47:47 -070025import android.content.res.Configuration;
Sunny Goyalf633ef52018-03-13 09:57:05 -070026import android.graphics.Point;
Sunny Goyal7eff40f2018-04-11 15:30:46 -070027import android.support.annotation.IntDef;
Sunny Goyalf633ef52018-03-13 09:57:05 -070028import android.view.Display;
Sunny Goyal27835952017-01-13 12:15:53 -080029import android.view.View.AccessibilityDelegate;
30
Sunny Goyalfde55052018-02-01 14:46:13 -080031import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
Sunny Goyala535ae42017-02-27 10:07:13 -080032import com.android.launcher3.logging.UserEventDispatcher;
Sunny Goyal8392c822017-06-20 10:03:56 -070033import com.android.launcher3.util.SystemUiController;
Sunny Goyala535ae42017-02-27 10:07:13 -080034
Sunny Goyal7eff40f2018-04-11 15:30:46 -070035import java.lang.annotation.Retention;
Sunny Goyalfde55052018-02-01 14:46:13 -080036import java.util.ArrayList;
37
Sunny Goyal27835952017-01-13 12:15:53 -080038public abstract class BaseActivity extends Activity {
39
Sunny Goyal7eff40f2018-04-11 15:30:46 -070040 public static final int INVISIBLE_BY_STATE_HANDLER = 1 << 0;
41 public static final int INVISIBLE_BY_APP_TRANSITIONS = 1 << 1;
42 public static final int INVISIBLE_ALL =
43 INVISIBLE_BY_STATE_HANDLER | INVISIBLE_BY_APP_TRANSITIONS;
44
45 @Retention(SOURCE)
46 @IntDef(
47 flag = true,
48 value = {INVISIBLE_BY_STATE_HANDLER, INVISIBLE_BY_APP_TRANSITIONS})
49 public @interface InvisibilityFlags{}
50
Sunny Goyalfde55052018-02-01 14:46:13 -080051 private final ArrayList<OnDeviceProfileChangeListener> mDPChangeListeners = new ArrayList<>();
Winson Chung1a77c3d2018-04-11 12:47:47 -070052 private final ArrayList<MultiWindowModeChangedListener> mMultiWindowModeChangedListeners =
53 new ArrayList<>();
Sunny Goyalfde55052018-02-01 14:46:13 -080054
Sunny Goyal27835952017-01-13 12:15:53 -080055 protected DeviceProfile mDeviceProfile;
Sunny Goyala535ae42017-02-27 10:07:13 -080056 protected UserEventDispatcher mUserEventDispatcher;
Sunny Goyal8392c822017-06-20 10:03:56 -070057 protected SystemUiController mSystemUiController;
Sunny Goyal27835952017-01-13 12:15:53 -080058
Sunny Goyal3483c522018-04-12 11:23:33 -070059 private static final int ACTIVITY_STATE_STARTED = 1 << 0;
60 private static final int ACTIVITY_STATE_RESUMED = 1 << 1;
61 /**
62 * State flag indicating if the user is active or the actitvity when to background as a result
63 * of user action.
64 * @see #isUserActive()
65 */
66 private static final int ACTIVITY_STATE_USER_ACTIVE = 1 << 2;
67
68 @Retention(SOURCE)
69 @IntDef(
70 flag = true,
71 value = {ACTIVITY_STATE_STARTED, ACTIVITY_STATE_RESUMED, ACTIVITY_STATE_USER_ACTIVE})
72 public @interface ActivityFlags{}
73
74 @ActivityFlags
75 private int mActivityFlags;
Sunny Goyal7eff40f2018-04-11 15:30:46 -070076
Winson Chung9800e732018-04-04 13:33:23 -070077 // When the recents animation is running, the visibility of the Launcher is managed by the
78 // animation
Sunny Goyal7eff40f2018-04-11 15:30:46 -070079 @InvisibilityFlags private int mForceInvisible;
Sunny Goyalcc96aa12018-01-11 09:56:07 -080080
Sunny Goyal27835952017-01-13 12:15:53 -080081 public DeviceProfile getDeviceProfile() {
82 return mDeviceProfile;
83 }
84
85 public AccessibilityDelegate getAccessibilityDelegate() {
86 return null;
87 }
88
Sunny Goyala535ae42017-02-27 10:07:13 -080089 public final UserEventDispatcher getUserEventDispatcher() {
90 if (mUserEventDispatcher == null) {
Sunny Goyald70e75a2018-02-22 10:07:32 -080091 mUserEventDispatcher = UserEventDispatcher.newInstance(this, mDeviceProfile);
Sunny Goyala535ae42017-02-27 10:07:13 -080092 }
93 return mUserEventDispatcher;
94 }
95
Jon Mirandafe964322017-03-22 10:25:17 -070096 public boolean isInMultiWindowModeCompat() {
97 return Utilities.ATLEAST_NOUGAT && isInMultiWindowMode();
98 }
99
Sunny Goyal27835952017-01-13 12:15:53 -0800100 public static BaseActivity fromContext(Context context) {
101 if (context instanceof BaseActivity) {
102 return (BaseActivity) context;
103 }
104 return ((BaseActivity) ((ContextWrapper) context).getBaseContext());
105 }
Sunny Goyal8392c822017-06-20 10:03:56 -0700106
107 public SystemUiController getSystemUiController() {
108 if (mSystemUiController == null) {
109 mSystemUiController = new SystemUiController(getWindow());
110 }
111 return mSystemUiController;
112 }
Sunny Goyal64a75aa2017-07-03 13:50:52 -0700113
114 @Override
115 public void onActivityResult(int requestCode, int resultCode, Intent data) {
116 super.onActivityResult(requestCode, resultCode, data);
117 }
Sunny Goyalcc96aa12018-01-11 09:56:07 -0800118
119 @Override
120 protected void onStart() {
Sunny Goyal3483c522018-04-12 11:23:33 -0700121 mActivityFlags |= ACTIVITY_STATE_STARTED;
Sunny Goyalcc96aa12018-01-11 09:56:07 -0800122 super.onStart();
123 }
124
125 @Override
Tracy Zhoua706f002018-03-28 13:55:19 -0700126 protected void onResume() {
Sunny Goyal3483c522018-04-12 11:23:33 -0700127 mActivityFlags |= ACTIVITY_STATE_RESUMED | ACTIVITY_STATE_USER_ACTIVE;
Tracy Zhoua706f002018-03-28 13:55:19 -0700128 super.onResume();
129 }
130
131 @Override
132 protected void onUserLeaveHint() {
Sunny Goyal3483c522018-04-12 11:23:33 -0700133 mActivityFlags &= ~ACTIVITY_STATE_USER_ACTIVE;
Tracy Zhoua706f002018-03-28 13:55:19 -0700134 super.onUserLeaveHint();
135 }
136
137 @Override
Winson Chung1a77c3d2018-04-11 12:47:47 -0700138 public void onMultiWindowModeChanged(boolean isInMultiWindowMode, Configuration newConfig) {
139 super.onMultiWindowModeChanged(isInMultiWindowMode, newConfig);
140 for (int i = mMultiWindowModeChangedListeners.size() - 1; i >= 0; i--) {
141 mMultiWindowModeChangedListeners.get(i).onMultiWindowModeChanged(isInMultiWindowMode);
142 }
143 }
144
145 @Override
Sunny Goyalcc96aa12018-01-11 09:56:07 -0800146 protected void onStop() {
Tracy Zhoub67e3532018-04-17 23:45:47 -0700147 mActivityFlags &= ~ACTIVITY_STATE_STARTED & ~ACTIVITY_STATE_USER_ACTIVE;
Sunny Goyal7eff40f2018-04-11 15:30:46 -0700148 mForceInvisible = 0;
Sunny Goyalcc96aa12018-01-11 09:56:07 -0800149 super.onStop();
150 }
151
Sunny Goyal3483c522018-04-12 11:23:33 -0700152 @Override
153 protected void onPause() {
154 mActivityFlags &= ~ACTIVITY_STATE_RESUMED;
155 super.onPause();
156 }
157
Sunny Goyalcc96aa12018-01-11 09:56:07 -0800158 public boolean isStarted() {
Sunny Goyal3483c522018-04-12 11:23:33 -0700159 return (mActivityFlags & ACTIVITY_STATE_STARTED) != 0;
160 }
161
162 /**
163 * isResumed in already defined as a hidden final method in Activity.java
164 */
165 public boolean hasBeenResumed() {
166 return (mActivityFlags & ACTIVITY_STATE_RESUMED) != 0;
Sunny Goyalcc96aa12018-01-11 09:56:07 -0800167 }
Sunny Goyalfde55052018-02-01 14:46:13 -0800168
Tracy Zhoua706f002018-03-28 13:55:19 -0700169 public boolean isUserActive() {
Sunny Goyal3483c522018-04-12 11:23:33 -0700170 return (mActivityFlags & ACTIVITY_STATE_USER_ACTIVE) != 0;
Tracy Zhoua706f002018-03-28 13:55:19 -0700171 }
172
Sunny Goyalfde55052018-02-01 14:46:13 -0800173 public void addOnDeviceProfileChangeListener(OnDeviceProfileChangeListener listener) {
174 mDPChangeListeners.add(listener);
175 }
176
Winson Chung8a968fa2018-03-15 17:59:04 -0700177 public void removeOnDeviceProfileChangeListener(OnDeviceProfileChangeListener listener) {
178 mDPChangeListeners.remove(listener);
179 }
180
Sunny Goyalfde55052018-02-01 14:46:13 -0800181 protected void dispatchDeviceProfileChanged() {
Winson Chung8a968fa2018-03-15 17:59:04 -0700182 for (int i = mDPChangeListeners.size() - 1; i >= 0; i--) {
Sunny Goyalfde55052018-02-01 14:46:13 -0800183 mDPChangeListeners.get(i).onDeviceProfileChanged(mDeviceProfile);
184 }
185 }
Sunny Goyalf633ef52018-03-13 09:57:05 -0700186
Winson Chung1a77c3d2018-04-11 12:47:47 -0700187 public void addMultiWindowModeChangedListener(MultiWindowModeChangedListener listener) {
188 mMultiWindowModeChangedListeners.add(listener);
189 }
190
191 public void removeMultiWindowModeChangedListener(MultiWindowModeChangedListener listener) {
192 mMultiWindowModeChangedListeners.remove(listener);
193 }
194
Sunny Goyalf633ef52018-03-13 09:57:05 -0700195 /**
Winson Chung9800e732018-04-04 13:33:23 -0700196 * Used to set the override visibility state, used only to handle the transition home with the
197 * recents animation.
198 * @see LauncherAppTransitionManagerImpl.getWallpaperOpenRunner()
199 */
Sunny Goyal7eff40f2018-04-11 15:30:46 -0700200 public void addForceInvisibleFlag(@InvisibilityFlags int flag) {
201 mForceInvisible |= flag;
Winson Chung9800e732018-04-04 13:33:23 -0700202 }
203
Sunny Goyal7eff40f2018-04-11 15:30:46 -0700204 public void clearForceInvisibleFlag(@InvisibilityFlags int flag) {
205 mForceInvisible &= ~flag;
206 }
207
208
Winson Chung9800e732018-04-04 13:33:23 -0700209 /**
210 * @return Wether this activity should be considered invisible regardless of actual visibility.
211 */
212 public boolean isForceInvisible() {
Sunny Goyal7eff40f2018-04-11 15:30:46 -0700213 return mForceInvisible != 0;
Winson Chung9800e732018-04-04 13:33:23 -0700214 }
215
216 /**
Sunny Goyalf633ef52018-03-13 09:57:05 -0700217 * Sets the device profile, adjusting it accordingly in case of multi-window
218 */
219 protected void setDeviceProfile(DeviceProfile dp) {
220 mDeviceProfile = dp;
221 if (isInMultiWindowModeCompat()) {
222 Display display = getWindowManager().getDefaultDisplay();
223 Point mwSize = new Point();
224 display.getSize(mwSize);
225 mDeviceProfile = mDeviceProfile.getMultiWindowProfile(this, mwSize);
226 }
227 }
Winson Chung1a77c3d2018-04-11 12:47:47 -0700228
229 public interface MultiWindowModeChangedListener {
230 void onMultiWindowModeChanged(boolean isInMultiWindowMode);
231 }
Sunny Goyal27835952017-01-13 12:15:53 -0800232}