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 21 import android.content.Context; 22 import android.content.res.Configuration; 23 import android.os.Bundle; 24 import android.view.ActionMode; 25 import android.view.View; 26 27 import androidx.annotation.MainThread; 28 import androidx.annotation.NonNull; 29 import androidx.annotation.Nullable; 30 31 import com.android.launcher3.model.data.ItemInfo; 32 import com.android.launcher3.touch.ItemClickHandler; 33 import com.android.launcher3.util.ActivityOptionsWrapper; 34 import com.android.launcher3.util.DisplayController; 35 import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener; 36 import com.android.launcher3.util.DisplayController.Info; 37 import com.android.launcher3.util.OnColorHintListener; 38 import com.android.launcher3.util.Themes; 39 import com.android.launcher3.util.WallpaperColorHints; 40 import com.android.launcher3.util.WindowBounds; 41 42 /** 43 * Extension of BaseActivity allowing support for drag-n-drop 44 */ 45 @SuppressWarnings("NewApi") 46 public abstract class BaseDraggingActivity extends BaseActivity 47 implements OnColorHintListener, DisplayInfoChangeListener { 48 49 // When starting an action mode, setting this tag will cause the action mode to be cancelled 50 // automatically when user interacts with the launcher. 51 public static final Object AUTO_CANCEL_ACTION_MODE = new Object(); 52 53 private ActionMode mCurrentActionMode; 54 55 private int mThemeRes = R.style.AppTheme; 56 57 @Override onCreate(Bundle savedInstanceState)58 protected void onCreate(Bundle savedInstanceState) { 59 super.onCreate(savedInstanceState); 60 DisplayController.INSTANCE.get(this).addChangeListener(this); 61 62 // Update theme 63 WallpaperColorHints.get(this).registerOnColorHintsChangedListener(this); 64 int themeRes = Themes.getActivityThemeRes(this); 65 if (themeRes != mThemeRes) { 66 mThemeRes = themeRes; 67 setTheme(themeRes); 68 } 69 } 70 71 @MainThread 72 @Override onColorHintsChanged(int colorHints)73 public void onColorHintsChanged(int colorHints) { 74 updateTheme(); 75 } 76 77 @Override onConfigurationChanged(Configuration newConfig)78 public void onConfigurationChanged(Configuration newConfig) { 79 super.onConfigurationChanged(newConfig); 80 updateTheme(); 81 } 82 updateTheme()83 private void updateTheme() { 84 if (mThemeRes != Themes.getActivityThemeRes(this)) { 85 recreate(); 86 } 87 } 88 89 @Override onActionModeStarted(ActionMode mode)90 public void onActionModeStarted(ActionMode mode) { 91 super.onActionModeStarted(mode); 92 mCurrentActionMode = mode; 93 } 94 95 @Override onActionModeFinished(ActionMode mode)96 public void onActionModeFinished(ActionMode mode) { 97 super.onActionModeFinished(mode); 98 mCurrentActionMode = null; 99 } 100 isInAutoCancelActionMode()101 protected boolean isInAutoCancelActionMode() { 102 return mCurrentActionMode != null && AUTO_CANCEL_ACTION_MODE == mCurrentActionMode.getTag(); 103 } 104 105 @Override finishAutoCancelActionMode()106 public boolean finishAutoCancelActionMode() { 107 if (isInAutoCancelActionMode()) { 108 mCurrentActionMode.finish(); 109 return true; 110 } 111 return false; 112 } 113 getRootView()114 public abstract View getRootView(); 115 returnToHomescreen()116 public void returnToHomescreen() { 117 // no-op 118 } 119 120 @Override 121 @NonNull getActivityLaunchOptions(View v, @Nullable ItemInfo item)122 public ActivityOptionsWrapper getActivityLaunchOptions(View v, @Nullable ItemInfo item) { 123 ActivityOptionsWrapper wrapper = super.getActivityLaunchOptions(v, item); 124 addEventCallback(EVENT_RESUMED, wrapper.onEndCallback::executeAllAndDestroy); 125 return wrapper; 126 } 127 128 @Override makeDefaultActivityOptions(int splashScreenStyle)129 public ActivityOptionsWrapper makeDefaultActivityOptions(int splashScreenStyle) { 130 ActivityOptionsWrapper wrapper = super.makeDefaultActivityOptions(splashScreenStyle); 131 addEventCallback(EVENT_RESUMED, wrapper.onEndCallback::executeAllAndDestroy); 132 return wrapper; 133 } 134 135 @Override onDestroy()136 protected void onDestroy() { 137 super.onDestroy(); 138 DisplayController.INSTANCE.get(this).removeChangeListener(this); 139 WallpaperColorHints.get(this).unregisterOnColorsChangedListener(this); 140 } 141 onDeviceProfileInitiated()142 protected void onDeviceProfileInitiated() { 143 if (mDeviceProfile.isVerticalBarLayout()) { 144 mDeviceProfile.updateIsSeascape(this); 145 } 146 } 147 148 @Override onDisplayInfoChanged(Context context, Info info, int flags)149 public void onDisplayInfoChanged(Context context, Info info, int flags) { 150 if ((flags & CHANGE_ROTATION) != 0 && mDeviceProfile.isVerticalBarLayout()) { 151 mDeviceProfile.updateIsSeascape(this); 152 reapplyUi(); 153 } 154 } 155 156 @Override getItemOnClickListener()157 public View.OnClickListener getItemOnClickListener() { 158 return ItemClickHandler.INSTANCE; 159 } 160 reapplyUi()161 protected abstract void reapplyUi(); 162 getMultiWindowDisplaySize()163 protected WindowBounds getMultiWindowDisplaySize() { 164 return WindowBounds.fromWindowMetrics(getWindowManager().getCurrentWindowMetrics()); 165 } 166 167 @Override isAppBlockedForSafeMode()168 public boolean isAppBlockedForSafeMode() { 169 return LauncherAppState.getInstance(this).isSafeModeEnabled(); 170 } 171 } 172