2019-10-17 12:05:38 -07:00
|
|
|
/*
|
|
|
|
|
* Copyright (C) 2019 The Android Open Source Project
|
|
|
|
|
*
|
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
|
*
|
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
*
|
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
|
* limitations under the License.
|
|
|
|
|
*/
|
|
|
|
|
package com.android.launcher3;
|
|
|
|
|
|
|
|
|
|
import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
|
|
|
|
|
import static com.android.launcher3.AbstractFloatingView.TYPE_HIDE_BACK_BUTTON;
|
2020-04-23 19:00:36 -07:00
|
|
|
import static com.android.launcher3.LauncherState.FLAG_HIDE_BACK_BUTTON;
|
2019-10-17 12:05:38 -07:00
|
|
|
import static com.android.launcher3.LauncherState.NORMAL;
|
2020-02-05 15:06:52 -08:00
|
|
|
import static com.android.quickstep.SysUINavigationMode.removeShelfFromOverview;
|
2020-03-07 02:14:19 +00:00
|
|
|
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY;
|
2019-10-17 12:05:38 -07:00
|
|
|
|
|
|
|
|
import android.animation.AnimatorSet;
|
|
|
|
|
import android.animation.ValueAnimator;
|
|
|
|
|
import android.content.Intent;
|
|
|
|
|
import android.content.IntentSender;
|
2020-04-08 17:48:41 -07:00
|
|
|
import android.content.SharedPreferences;
|
2019-10-17 12:05:38 -07:00
|
|
|
import android.os.Bundle;
|
|
|
|
|
import android.os.CancellationSignal;
|
|
|
|
|
|
|
|
|
|
import com.android.launcher3.LauncherStateManager.StateHandler;
|
2020-02-05 15:06:52 -08:00
|
|
|
import com.android.launcher3.config.FeatureFlags;
|
2019-10-23 17:44:27 -07:00
|
|
|
import com.android.launcher3.model.WellbeingModel;
|
|
|
|
|
import com.android.launcher3.popup.SystemShortcut;
|
2019-10-17 12:05:38 -07:00
|
|
|
import com.android.launcher3.proxy.ProxyActivityStarter;
|
|
|
|
|
import com.android.launcher3.proxy.StartActivityParams;
|
2020-03-24 12:41:56 -07:00
|
|
|
import com.android.launcher3.statehandlers.BackButtonAlphaHandler;
|
|
|
|
|
import com.android.launcher3.statehandlers.DepthController;
|
2019-10-17 12:05:38 -07:00
|
|
|
import com.android.launcher3.uioverrides.RecentsViewStateController;
|
2020-04-08 17:48:41 -07:00
|
|
|
import com.android.launcher3.util.OnboardingPrefs;
|
2019-10-17 12:05:38 -07:00
|
|
|
import com.android.launcher3.util.UiThreadHelper;
|
|
|
|
|
import com.android.quickstep.RecentsModel;
|
|
|
|
|
import com.android.quickstep.SysUINavigationMode;
|
|
|
|
|
import com.android.quickstep.SysUINavigationMode.Mode;
|
|
|
|
|
import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener;
|
|
|
|
|
import com.android.quickstep.SystemUiProxy;
|
2020-04-08 17:48:41 -07:00
|
|
|
import com.android.quickstep.util.QuickstepOnboardingPrefs;
|
2020-03-02 18:05:58 -08:00
|
|
|
import com.android.quickstep.util.RemoteAnimationProvider;
|
2019-10-17 12:05:38 -07:00
|
|
|
import com.android.quickstep.util.RemoteFadeOutAnimationListener;
|
2019-11-07 13:28:50 -08:00
|
|
|
import com.android.quickstep.util.ShelfPeekAnim;
|
2020-04-15 16:36:27 -07:00
|
|
|
import com.android.quickstep.views.OverviewActionsView;
|
2019-12-19 11:50:55 -08:00
|
|
|
import com.android.quickstep.views.RecentsView;
|
2019-11-21 01:32:58 +08:00
|
|
|
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
2020-03-02 18:05:58 -08:00
|
|
|
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
2019-10-17 12:05:38 -07:00
|
|
|
|
2019-10-23 17:44:27 -07:00
|
|
|
import java.util.stream.Stream;
|
|
|
|
|
|
2019-10-17 12:05:38 -07:00
|
|
|
/**
|
|
|
|
|
* Extension of Launcher activity to provide quickstep specific functionality
|
|
|
|
|
*/
|
|
|
|
|
public abstract class BaseQuickstepLauncher extends Launcher
|
|
|
|
|
implements NavigationModeChangeListener {
|
|
|
|
|
|
2020-03-24 12:41:56 -07:00
|
|
|
private DepthController mDepthController = new DepthController(this);
|
2020-01-27 16:23:03 -08:00
|
|
|
|
2019-10-17 12:05:38 -07:00
|
|
|
/**
|
|
|
|
|
* Reusable command for applying the back button alpha on the background thread.
|
|
|
|
|
*/
|
|
|
|
|
public static final UiThreadHelper.AsyncCommand SET_BACK_BUTTON_ALPHA =
|
|
|
|
|
(context, arg1, arg2) -> SystemUiProxy.INSTANCE.get(context).setBackButtonAlpha(
|
|
|
|
|
Float.intBitsToFloat(arg1), arg2 != 0);
|
|
|
|
|
|
2019-11-07 13:28:50 -08:00
|
|
|
private final ShelfPeekAnim mShelfPeekAnim = new ShelfPeekAnim(this);
|
|
|
|
|
|
2020-04-15 16:36:27 -07:00
|
|
|
private OverviewActionsView mActionsView;
|
2020-03-26 15:28:36 -07:00
|
|
|
|
2019-10-17 12:05:38 -07:00
|
|
|
@Override
|
|
|
|
|
protected void onCreate(Bundle savedInstanceState) {
|
|
|
|
|
super.onCreate(savedInstanceState);
|
|
|
|
|
|
2020-04-03 17:10:11 -07:00
|
|
|
SysUINavigationMode.INSTANCE.get(this).addModeChangeListener(this);
|
2019-10-17 12:05:38 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onDestroy() {
|
|
|
|
|
SysUINavigationMode.INSTANCE.get(this).removeModeChangeListener(this);
|
|
|
|
|
super.onDestroy();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onNavigationModeChanged(Mode newMode) {
|
|
|
|
|
getDragLayer().recreateControllers();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onEnterAnimationComplete() {
|
|
|
|
|
super.onEnterAnimationComplete();
|
|
|
|
|
// After the transition to home, enable the high-res thumbnail loader if it wasn't enabled
|
|
|
|
|
// as a part of quickstep, so that high-res thumbnails can load the next time we enter
|
|
|
|
|
// overview
|
|
|
|
|
RecentsModel.INSTANCE.get(this).getThumbnailCache()
|
|
|
|
|
.getHighResLoadingState().setVisible(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onTrimMemory(int level) {
|
|
|
|
|
super.onTrimMemory(level);
|
|
|
|
|
RecentsModel.INSTANCE.get(this).onTrimMemory(level);
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-21 01:32:58 +08:00
|
|
|
@Override
|
|
|
|
|
protected void onUiChangedWhileSleeping() {
|
|
|
|
|
// Remove the snapshot because the content view may have obvious changes.
|
|
|
|
|
ActivityManagerWrapper.getInstance().invalidateHomeTaskSnapshot(this);
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-17 12:05:38 -07:00
|
|
|
@Override
|
|
|
|
|
public void startIntentSenderForResult(IntentSender intent, int requestCode,
|
|
|
|
|
Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options) {
|
|
|
|
|
if (requestCode != -1) {
|
|
|
|
|
mPendingActivityRequestCode = requestCode;
|
|
|
|
|
StartActivityParams params = new StartActivityParams(this, requestCode);
|
|
|
|
|
params.intentSender = intent;
|
|
|
|
|
params.fillInIntent = fillInIntent;
|
|
|
|
|
params.flagsMask = flagsMask;
|
|
|
|
|
params.flagsValues = flagsValues;
|
|
|
|
|
params.extraFlags = extraFlags;
|
|
|
|
|
params.options = options;
|
|
|
|
|
startActivity(ProxyActivityStarter.getLaunchIntent(this, params));
|
|
|
|
|
} else {
|
|
|
|
|
super.startIntentSenderForResult(intent, requestCode, fillInIntent, flagsMask,
|
|
|
|
|
flagsValues, extraFlags, options);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
|
|
|
|
|
if (requestCode != -1) {
|
2020-02-12 12:50:49 -08:00
|
|
|
mPendingActivityRequestCode = requestCode;
|
2019-10-17 12:05:38 -07:00
|
|
|
StartActivityParams params = new StartActivityParams(this, requestCode);
|
|
|
|
|
params.intent = intent;
|
|
|
|
|
params.options = options;
|
|
|
|
|
startActivity(ProxyActivityStarter.getLaunchIntent(this, params));
|
|
|
|
|
} else {
|
|
|
|
|
super.startActivityForResult(intent, requestCode, options);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
protected void onDeferredResumed() {
|
|
|
|
|
if (mPendingActivityRequestCode != -1 && isInState(NORMAL)) {
|
|
|
|
|
// Remove any active ProxyActivityStarter task and send RESULT_CANCELED to Launcher.
|
|
|
|
|
onActivityResult(mPendingActivityRequestCode, RESULT_CANCELED, null);
|
|
|
|
|
// ProxyActivityStarter is started with clear task to reset the task after which it
|
|
|
|
|
// removes the task itself.
|
|
|
|
|
startActivity(ProxyActivityStarter.getLaunchIntent(this, null));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-05 15:06:52 -08:00
|
|
|
@Override
|
|
|
|
|
protected void setupViews() {
|
|
|
|
|
super.setupViews();
|
2020-04-22 15:53:38 -07:00
|
|
|
|
|
|
|
|
SysUINavigationMode.INSTANCE.get(this).updateMode();
|
2020-03-26 15:28:36 -07:00
|
|
|
mActionsView = findViewById(R.id.overview_actions_view);
|
2020-04-15 16:36:27 -07:00
|
|
|
((RecentsView) getOverviewPanel()).init(mActionsView);
|
2020-02-05 15:06:52 -08:00
|
|
|
|
|
|
|
|
if (FeatureFlags.ENABLE_OVERVIEW_ACTIONS.get() && removeShelfFromOverview(this)) {
|
|
|
|
|
// Overview is above all other launcher elements, including qsb, so move it to the top.
|
2020-02-21 17:53:02 -08:00
|
|
|
getOverviewPanel().bringToFront();
|
2020-04-15 16:36:27 -07:00
|
|
|
mActionsView.bringToFront();
|
2020-02-05 15:06:52 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-15 16:36:27 -07:00
|
|
|
public <T extends OverviewActionsView> T getActionsView() {
|
|
|
|
|
return (T) mActionsView;
|
2020-03-26 15:28:36 -07:00
|
|
|
}
|
|
|
|
|
|
2020-03-07 02:14:19 +00:00
|
|
|
@Override
|
|
|
|
|
protected void closeOpenViews(boolean animate) {
|
|
|
|
|
super.closeOpenViews(animate);
|
|
|
|
|
ActivityManagerWrapper.getInstance()
|
|
|
|
|
.closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY);
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-17 12:05:38 -07:00
|
|
|
@Override
|
|
|
|
|
protected StateHandler[] createStateHandlers() {
|
|
|
|
|
return new StateHandler[] {
|
|
|
|
|
getAllAppsController(),
|
|
|
|
|
getWorkspace(),
|
2020-03-17 17:11:32 -07:00
|
|
|
getDepthController(),
|
2019-10-17 12:05:38 -07:00
|
|
|
new RecentsViewStateController(this),
|
|
|
|
|
new BackButtonAlphaHandler(this)};
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-24 12:41:56 -07:00
|
|
|
public DepthController getDepthController() {
|
|
|
|
|
return mDepthController;
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-08 17:48:41 -07:00
|
|
|
@Override
|
|
|
|
|
protected OnboardingPrefs createOnboardingPrefs(SharedPreferences sharedPrefs,
|
|
|
|
|
LauncherStateManager stateManager) {
|
|
|
|
|
return new QuickstepOnboardingPrefs(this, sharedPrefs, stateManager);
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-17 12:05:38 -07:00
|
|
|
@Override
|
|
|
|
|
public void useFadeOutAnimationForLauncherStart(CancellationSignal signal) {
|
|
|
|
|
QuickstepAppTransitionManagerImpl appTransitionManager =
|
|
|
|
|
(QuickstepAppTransitionManagerImpl) getAppTransitionManager();
|
2020-03-02 18:05:58 -08:00
|
|
|
appTransitionManager.setRemoteAnimationProvider(new RemoteAnimationProvider() {
|
|
|
|
|
@Override
|
|
|
|
|
public AnimatorSet createWindowAnimation(RemoteAnimationTargetCompat[] appTargets,
|
|
|
|
|
RemoteAnimationTargetCompat[] wallpaperTargets) {
|
|
|
|
|
|
|
|
|
|
// On the first call clear the reference.
|
|
|
|
|
signal.cancel();
|
|
|
|
|
|
|
|
|
|
ValueAnimator fadeAnimation = ValueAnimator.ofFloat(1, 0);
|
|
|
|
|
fadeAnimation.addUpdateListener(new RemoteFadeOutAnimationListener(appTargets,
|
|
|
|
|
wallpaperTargets));
|
|
|
|
|
AnimatorSet anim = new AnimatorSet();
|
|
|
|
|
anim.play(fadeAnimation);
|
|
|
|
|
return anim;
|
|
|
|
|
}
|
2019-10-17 12:05:38 -07:00
|
|
|
}, signal);
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-01 20:13:12 -07:00
|
|
|
@Override
|
|
|
|
|
public float[] getNormalOverviewScaleAndOffset() {
|
|
|
|
|
return SysUINavigationMode.getMode(this) == Mode.NO_BUTTON
|
|
|
|
|
? new float[] {1, 1} : new float[] {1.1f, 0};
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-17 12:05:38 -07:00
|
|
|
@Override
|
|
|
|
|
public void onDragLayerHierarchyChanged() {
|
|
|
|
|
onLauncherStateOrFocusChanged();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
protected void onActivityFlagsChanged(int changeBits) {
|
|
|
|
|
if ((changeBits
|
|
|
|
|
& (ACTIVITY_STATE_WINDOW_FOCUSED | ACTIVITY_STATE_TRANSITION_ACTIVE)) != 0) {
|
|
|
|
|
onLauncherStateOrFocusChanged();
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-24 12:41:56 -07:00
|
|
|
if ((changeBits & ACTIVITY_STATE_STARTED) != 0) {
|
|
|
|
|
mDepthController.setActivityStarted(isStarted());
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-17 12:05:38 -07:00
|
|
|
super.onActivityFlagsChanged(changeBits);
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-30 23:03:52 -07:00
|
|
|
public boolean shouldBackButtonBeHidden(LauncherState toState) {
|
2019-10-17 12:05:38 -07:00
|
|
|
Mode mode = SysUINavigationMode.getMode(this);
|
|
|
|
|
boolean shouldBackButtonBeHidden = mode.hasGestures
|
2020-04-30 23:03:52 -07:00
|
|
|
&& toState.hasFlag(FLAG_HIDE_BACK_BUTTON)
|
2019-10-17 12:05:38 -07:00
|
|
|
&& hasWindowFocus()
|
|
|
|
|
&& (getActivityFlags() & ACTIVITY_STATE_TRANSITION_ACTIVE) == 0;
|
|
|
|
|
if (shouldBackButtonBeHidden) {
|
|
|
|
|
// Show the back button if there is a floating view visible.
|
|
|
|
|
shouldBackButtonBeHidden = AbstractFloatingView.getTopOpenViewWithType(this,
|
|
|
|
|
TYPE_ALL & ~TYPE_HIDE_BACK_BUTTON) == null;
|
|
|
|
|
}
|
2020-04-30 23:03:52 -07:00
|
|
|
return shouldBackButtonBeHidden;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Sets the back button visibility based on the current state/window focus.
|
|
|
|
|
*/
|
|
|
|
|
private void onLauncherStateOrFocusChanged() {
|
|
|
|
|
boolean shouldBackButtonBeHidden = shouldBackButtonBeHidden(getStateManager().getState());
|
2019-10-17 12:05:38 -07:00
|
|
|
UiThreadHelper.setBackButtonAlphaAsync(this, SET_BACK_BUTTON_ALPHA,
|
|
|
|
|
shouldBackButtonBeHidden ? 0f : 1f, true /* animate */);
|
|
|
|
|
if (getDragLayer() != null) {
|
|
|
|
|
getRootView().setDisallowBackGesture(shouldBackButtonBeHidden);
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-10-23 17:44:27 -07:00
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void finishBindingItems(int pageBoundFirst) {
|
|
|
|
|
super.finishBindingItems(pageBoundFirst);
|
|
|
|
|
// Instantiate and initialize WellbeingModel now that its loading won't interfere with
|
|
|
|
|
// populating workspace.
|
|
|
|
|
// TODO: Find a better place for this
|
2019-12-09 14:55:56 -08:00
|
|
|
WellbeingModel.INSTANCE.get(this);
|
2019-10-23 17:44:27 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Stream<SystemShortcut.Factory> getSupportedShortcuts() {
|
|
|
|
|
return Stream.concat(super.getSupportedShortcuts(),
|
|
|
|
|
Stream.of(WellbeingModel.SHORTCUT_FACTORY));
|
|
|
|
|
}
|
2019-11-07 13:28:50 -08:00
|
|
|
|
|
|
|
|
public ShelfPeekAnim getShelfPeekAnim() {
|
|
|
|
|
return mShelfPeekAnim;
|
|
|
|
|
}
|
2019-10-17 12:05:38 -07:00
|
|
|
}
|