• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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.DisplayController.CHANGE_ROTATION;
20 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
21 
22 import android.app.WallpaperColors;
23 import android.app.WallpaperManager;
24 import android.app.WallpaperManager.OnColorsChangedListener;
25 import android.content.Context;
26 import android.content.res.Configuration;
27 import android.graphics.Point;
28 import android.graphics.Rect;
29 import android.os.Bundle;
30 import android.view.ActionMode;
31 import android.view.Display;
32 import android.view.View;
33 
34 import androidx.annotation.NonNull;
35 import androidx.annotation.Nullable;
36 
37 import com.android.launcher3.model.data.ItemInfo;
38 import com.android.launcher3.touch.ItemClickHandler;
39 import com.android.launcher3.util.ActivityOptionsWrapper;
40 import com.android.launcher3.util.DisplayController;
41 import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener;
42 import com.android.launcher3.util.DisplayController.Info;
43 import com.android.launcher3.util.RunnableList;
44 import com.android.launcher3.util.Themes;
45 import com.android.launcher3.util.TraceHelper;
46 import com.android.launcher3.util.WindowBounds;
47 
48 /**
49  * Extension of BaseActivity allowing support for drag-n-drop
50  */
51 @SuppressWarnings("NewApi")
52 public abstract class BaseDraggingActivity extends BaseActivity
53         implements OnColorsChangedListener, DisplayInfoChangeListener {
54 
55     private static final String TAG = "BaseDraggingActivity";
56 
57     // When starting an action mode, setting this tag will cause the action mode to be cancelled
58     // automatically when user interacts with the launcher.
59     public static final Object AUTO_CANCEL_ACTION_MODE = new Object();
60 
61     private ActionMode mCurrentActionMode;
62     protected boolean mIsSafeModeEnabled;
63 
64     private Runnable mOnStartCallback;
65     private RunnableList mOnResumeCallbacks = new RunnableList();
66 
67     private int mThemeRes = R.style.AppTheme;
68 
69     @Override
onCreate(Bundle savedInstanceState)70     protected void onCreate(Bundle savedInstanceState) {
71         super.onCreate(savedInstanceState);
72 
73         mIsSafeModeEnabled = TraceHelper.allowIpcs("isSafeMode",
74                 () -> getPackageManager().isSafeMode());
75         DisplayController.INSTANCE.get(this).addChangeListener(this);
76 
77         // Update theme
78         if (Utilities.ATLEAST_P) {
79             getSystemService(WallpaperManager.class)
80                     .addOnColorsChangedListener(this, MAIN_EXECUTOR.getHandler());
81         }
82         int themeRes = Themes.getActivityThemeRes(this);
83         if (themeRes != mThemeRes) {
84             mThemeRes = themeRes;
85             setTheme(themeRes);
86         }
87     }
88 
89     @Override
onResume()90     protected void onResume() {
91         super.onResume();
92         mOnResumeCallbacks.executeAllAndClear();
93     }
94 
addOnResumeCallback(Runnable callback)95     public void addOnResumeCallback(Runnable callback) {
96         mOnResumeCallbacks.add(callback);
97     }
98 
99     @Override
onColorsChanged(WallpaperColors wallpaperColors, int which)100     public void onColorsChanged(WallpaperColors wallpaperColors, int which) {
101         updateTheme();
102     }
103 
104     @Override
onConfigurationChanged(Configuration newConfig)105     public void onConfigurationChanged(Configuration newConfig) {
106         super.onConfigurationChanged(newConfig);
107         updateTheme();
108     }
109 
updateTheme()110     private void updateTheme() {
111         if (mThemeRes != Themes.getActivityThemeRes(this)) {
112             recreate();
113         }
114     }
115 
116     @Override
onActionModeStarted(ActionMode mode)117     public void onActionModeStarted(ActionMode mode) {
118         super.onActionModeStarted(mode);
119         mCurrentActionMode = mode;
120     }
121 
122     @Override
onActionModeFinished(ActionMode mode)123     public void onActionModeFinished(ActionMode mode) {
124         super.onActionModeFinished(mode);
125         mCurrentActionMode = null;
126     }
127 
isInAutoCancelActionMode()128     protected boolean isInAutoCancelActionMode() {
129         return mCurrentActionMode != null && AUTO_CANCEL_ACTION_MODE == mCurrentActionMode.getTag();
130     }
131 
132     @Override
finishAutoCancelActionMode()133     public boolean finishAutoCancelActionMode() {
134         if (isInAutoCancelActionMode()) {
135             mCurrentActionMode.finish();
136             return true;
137         }
138         return false;
139     }
140 
getOverviewPanel()141     public abstract <T extends View> T getOverviewPanel();
142 
getRootView()143     public abstract View getRootView();
144 
returnToHomescreen()145     public void returnToHomescreen() {
146         // no-op
147     }
148 
149     @Override
150     @NonNull
getActivityLaunchOptions(View v, @Nullable ItemInfo item)151     public ActivityOptionsWrapper getActivityLaunchOptions(View v, @Nullable ItemInfo item) {
152         ActivityOptionsWrapper wrapper = super.getActivityLaunchOptions(v, item);
153         addOnResumeCallback(wrapper.onEndCallback::executeAllAndDestroy);
154         return wrapper;
155     }
156 
157     @Override
onStart()158     protected void onStart() {
159         super.onStart();
160 
161         if (mOnStartCallback != null) {
162             mOnStartCallback.run();
163             mOnStartCallback = null;
164         }
165     }
166 
167     @Override
onDestroy()168     protected void onDestroy() {
169         super.onDestroy();
170         if (Utilities.ATLEAST_P) {
171             getSystemService(WallpaperManager.class).removeOnColorsChangedListener(this);
172         }
173         DisplayController.INSTANCE.get(this).removeChangeListener(this);
174     }
175 
runOnceOnStart(Runnable action)176     public void runOnceOnStart(Runnable action) {
177         mOnStartCallback = action;
178     }
179 
clearRunOnceOnStartCallback()180     public void clearRunOnceOnStartCallback() {
181         mOnStartCallback = null;
182     }
183 
onDeviceProfileInitiated()184     protected void onDeviceProfileInitiated() {
185         if (mDeviceProfile.isVerticalBarLayout()) {
186             mDeviceProfile.updateIsSeascape(this);
187         }
188     }
189 
190     @Override
onDisplayInfoChanged(Context context, Info info, int flags)191     public void onDisplayInfoChanged(Context context, Info info, int flags) {
192         if ((flags & CHANGE_ROTATION) != 0 && mDeviceProfile.updateIsSeascape(this)) {
193             reapplyUi();
194         }
195     }
196 
197     @Override
getItemOnClickListener()198     public View.OnClickListener getItemOnClickListener() {
199         return ItemClickHandler.INSTANCE;
200     }
201 
reapplyUi()202     protected abstract void reapplyUi();
203 
getMultiWindowDisplaySize()204     protected WindowBounds getMultiWindowDisplaySize() {
205         if (Utilities.ATLEAST_R) {
206             return WindowBounds.fromWindowMetrics(getWindowManager().getCurrentWindowMetrics());
207         }
208         // Note: Calls to getSize() can't rely on our cached DefaultDisplay since it can return
209         // the app window size
210         Display display = getWindowManager().getDefaultDisplay();
211         Point mwSize = new Point();
212         display.getSize(mwSize);
213         return new WindowBounds(new Rect(0, 0, mwSize.x, mwSize.y), new Rect());
214     }
215 
216     @Override
isAppBlockedForSafeMode()217     public boolean isAppBlockedForSafeMode() {
218         return mIsSafeModeEnabled;
219     }
220 }
221