Merge "Add InsetTransitionController to device search" into ub-launcher3-master
This commit is contained in:
committed by
Android (Google) Code Review
commit
72ffd8ead6
@@ -1550,7 +1550,6 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
|
||||
mOverlayManager.onActivityDestroyed(this);
|
||||
mAppTransitionManager.unregisterRemoteAnimations();
|
||||
mUserChangedCallbackCloseable.close();
|
||||
mAllAppsController.onActivityDestroyed();
|
||||
}
|
||||
|
||||
public LauncherAccessibilityDelegate getAccessibilityDelegate() {
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.allapps;
|
||||
|
||||
import android.graphics.Insets;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.WindowInsets;
|
||||
import android.view.WindowInsetsAnimationControlListener;
|
||||
import android.view.WindowInsetsAnimationController;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.core.os.BuildCompat;
|
||||
|
||||
/**
|
||||
* Handles IME over all apps to be synchronously transitioning along with the passed in
|
||||
* root inset.
|
||||
*/
|
||||
public class AllAppsInsetTransitionController {
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
private static final String TAG = "AllAppsInsetTransitionController";
|
||||
private static final Interpolator LINEAR = new LinearInterpolator();
|
||||
|
||||
private WindowInsetsAnimationController mAnimationController;
|
||||
private WindowInsetsAnimationControlListener mCurrentRequest;
|
||||
|
||||
private float mAllAppsHeight;
|
||||
|
||||
private int mDownInsetBottom;
|
||||
private boolean mShownAtDown;
|
||||
|
||||
private int mHiddenInsetBottom;
|
||||
private int mShownInsetBottom;
|
||||
|
||||
private float mDown, mCurrent;
|
||||
private View mApps;
|
||||
|
||||
public AllAppsInsetTransitionController(float allAppsHeight, View appsView) {
|
||||
mAllAppsHeight = allAppsHeight;
|
||||
mApps = appsView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes member variables and requests for the {@link WindowInsetsAnimationController}
|
||||
* object.
|
||||
*
|
||||
* @param progress value between 0..1
|
||||
*/
|
||||
@RequiresApi(api = Build.VERSION_CODES.R)
|
||||
public void onDragStart(float progress) {
|
||||
if (!BuildCompat.isAtLeastR()) return;
|
||||
onAnimationEnd(progress);
|
||||
|
||||
mDown = progress * mAllAppsHeight;
|
||||
|
||||
// Below two values are sometimes incorrect. Possibly a platform bug
|
||||
mDownInsetBottom = mApps.getRootWindowInsets().getInsets(WindowInsets.Type.ime()).bottom;
|
||||
mShownAtDown = mApps.getRootWindowInsets().isVisible(WindowInsets.Type.ime());
|
||||
|
||||
// override this value based on what it should actually be.
|
||||
mShownAtDown = Float.compare(progress, 1f) == 0 ? false : true;
|
||||
mDownInsetBottom = mShownAtDown ? mShownInsetBottom : mHiddenInsetBottom;
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "\nonDragStart mDownInsets=" + mDownInsetBottom
|
||||
+ " mShownAtDown =" + mShownAtDown);
|
||||
}
|
||||
|
||||
mApps.getWindowInsetsController().controlWindowInsetsAnimation(
|
||||
WindowInsets.Type.ime(), -1 /* no predetermined duration */, LINEAR, null,
|
||||
mCurrentRequest = new WindowInsetsAnimationControlListener() {
|
||||
|
||||
@Override
|
||||
public void onReady(WindowInsetsAnimationController controller, int types) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Listener.onReady " + (mCurrentRequest == this));
|
||||
}
|
||||
if (mCurrentRequest == this) {
|
||||
mAnimationController = controller;
|
||||
} else {
|
||||
controller.finish(mShownAtDown);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinished(WindowInsetsAnimationController controller) {
|
||||
// when screen lock happens, then this method get called
|
||||
mAnimationController.finish(false);
|
||||
mAnimationController = null;
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Listener.onFinished ctrl=" + controller);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancelled(@Nullable WindowInsetsAnimationController controller) {
|
||||
mAnimationController = null;
|
||||
if (controller != null) {
|
||||
controller.finish(mShownAtDown);
|
||||
}
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Listener.onCancelled ctrl=" + controller);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the translation using the progress.
|
||||
*
|
||||
* @param progress value between 0..1
|
||||
*/
|
||||
@RequiresApi(api = 30)
|
||||
public void setProgress(float progress) {
|
||||
if (!BuildCompat.isAtLeastR()) return;
|
||||
// progress that equals to 0 or 1 is error prone. Do not use them.
|
||||
// Instead use onDragStart and onAnimationEnd
|
||||
if (mAnimationController == null || progress <= 0f || progress >= 1f) return;
|
||||
|
||||
mCurrent = progress * mAllAppsHeight;
|
||||
mHiddenInsetBottom = mAnimationController.getHiddenStateInsets().bottom; // 0
|
||||
mShownInsetBottom = mAnimationController.getShownStateInsets().bottom; // 1155
|
||||
|
||||
int shift = mShownAtDown ? 0 : (int) (mAllAppsHeight - mShownInsetBottom);
|
||||
|
||||
int inset = (int) (mDownInsetBottom + (mDown - mCurrent) - shift);
|
||||
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "updateInset mCurrent=" + mCurrent + " mDown="
|
||||
+ mDown + " hidden=" + mHiddenInsetBottom
|
||||
+ " shown=" + mShownInsetBottom
|
||||
+ " mDownInsets.bottom=" + mDownInsetBottom + " inset:" + inset
|
||||
+ " shift: " + shift);
|
||||
}
|
||||
final int start = mShownAtDown ? mShownInsetBottom : mHiddenInsetBottom;
|
||||
final int end = mShownAtDown ? mHiddenInsetBottom : mShownInsetBottom;
|
||||
inset = Math.max(inset, mHiddenInsetBottom);
|
||||
inset = Math.min(inset, mShownInsetBottom);
|
||||
Log.d(TAG, "updateInset inset:" + inset);
|
||||
|
||||
mAnimationController.setInsetsAndAlpha(
|
||||
Insets.of(0, 0, 0, inset),
|
||||
1f, (inset - start) / (float) (end - start));
|
||||
}
|
||||
|
||||
/**
|
||||
* Report to the animation controller that we no longer plan to translate anymore.
|
||||
*
|
||||
* @param progress value between 0..1
|
||||
*/
|
||||
@RequiresApi(api = 30)
|
||||
public void onAnimationEnd(float progress) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "endTranslation progress=" + progress
|
||||
+ " mAnimationController=" + mAnimationController);
|
||||
}
|
||||
|
||||
if (mAnimationController == null) return;
|
||||
|
||||
if (Float.compare(progress, 1f) == 0 /* bottom */) {
|
||||
mAnimationController.finish(false /* gone */);
|
||||
}
|
||||
if (Float.compare(progress, 0f) == 0 /* top */) {
|
||||
mAnimationController.finish(true /* show */);
|
||||
}
|
||||
mAnimationController = null;
|
||||
mCurrentRequest = null;
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,18 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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.allapps;
|
||||
|
||||
import static com.android.launcher3.LauncherState.ALL_APPS_CONTENT;
|
||||
@@ -14,31 +29,28 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FA
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_HEADER_FADE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
|
||||
import static com.android.launcher3.util.SystemUiController.UI_STATE_ALLAPPS;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.Context;
|
||||
import android.util.FloatProperty;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.widget.EditText;
|
||||
|
||||
import androidx.core.os.BuildCompat;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.anim.AnimationSuccessListener;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.anim.PropertySetter;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.statemanager.StateManager.StateHandler;
|
||||
import com.android.launcher3.states.StateAnimationConfig;
|
||||
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
|
||||
import com.android.launcher3.views.ScrimView;
|
||||
import com.android.systemui.plugins.AllAppsSearchPlugin;
|
||||
import com.android.systemui.plugins.PluginListener;
|
||||
|
||||
/**
|
||||
* Handles AllApps view transition.
|
||||
@@ -51,7 +63,7 @@ import com.android.systemui.plugins.PluginListener;
|
||||
* closer to top or closer to the page indicator.
|
||||
*/
|
||||
public class AllAppsTransitionController implements StateHandler<LauncherState>,
|
||||
OnDeviceProfileChangeListener, PluginListener<AllAppsSearchPlugin> {
|
||||
OnDeviceProfileChangeListener {
|
||||
|
||||
public static final FloatProperty<AllAppsTransitionController> ALL_APPS_PROGRESS =
|
||||
new FloatProperty<AllAppsTransitionController>("allAppsProgress") {
|
||||
@@ -85,10 +97,7 @@ public class AllAppsTransitionController implements StateHandler<LauncherState>,
|
||||
private float mProgress; // [0, 1], mShiftRange * mProgress = shiftCurrent
|
||||
|
||||
private float mScrollRangeDelta = 0;
|
||||
|
||||
// plugin related variables
|
||||
private AllAppsSearchPlugin mPlugin;
|
||||
private View mPluginContent;
|
||||
private AllAppsInsetTransitionController mInsetController;
|
||||
|
||||
public AllAppsTransitionController(Launcher l) {
|
||||
mLauncher = l;
|
||||
@@ -103,6 +112,10 @@ public class AllAppsTransitionController implements StateHandler<LauncherState>,
|
||||
return mShiftRange;
|
||||
}
|
||||
|
||||
public AllAppsInsetTransitionController getInsetController() {
|
||||
return mInsetController;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeviceProfileChanged(DeviceProfile dp) {
|
||||
mIsVerticalLayout = dp.isVerticalBarLayout();
|
||||
@@ -130,8 +143,8 @@ public class AllAppsTransitionController implements StateHandler<LauncherState>,
|
||||
float shiftCurrent = progress * mShiftRange;
|
||||
|
||||
mAppsView.setTranslationY(shiftCurrent);
|
||||
if (mPlugin != null) {
|
||||
mPlugin.setProgress(progress);
|
||||
if (FeatureFlags.ENABLE_DEVICE_SEARCH.get()) {
|
||||
mInsetController.setProgress(progress);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,16 +214,12 @@ public class AllAppsTransitionController implements StateHandler<LauncherState>,
|
||||
Interpolator allAppsFade = config.getInterpolator(ANIM_ALL_APPS_FADE, LINEAR);
|
||||
Interpolator headerFade = config.getInterpolator(ANIM_ALL_APPS_HEADER_FADE, allAppsFade);
|
||||
|
||||
if (mPlugin == null) {
|
||||
setter.setViewAlpha(mAppsView.getContentView(), hasAllAppsContent ? 1 : 0, allAppsFade);
|
||||
setter.setViewAlpha(mAppsView.getScrollBar(), hasAllAppsContent ? 1 : 0, allAppsFade);
|
||||
mAppsView.getFloatingHeaderView().setContentVisibility(hasHeaderExtra,
|
||||
hasAllAppsContent, setter, headerFade, allAppsFade);
|
||||
} else {
|
||||
setter.setViewAlpha(mPluginContent, hasAllAppsContent ? 1 : 0, allAppsFade);
|
||||
setter.setViewAlpha(mAppsView.getContentView(), 0, allAppsFade);
|
||||
setter.setViewAlpha(mAppsView.getScrollBar(), 0, allAppsFade);
|
||||
}
|
||||
|
||||
setter.setViewAlpha(mAppsView.getContentView(), hasAllAppsContent ? 1 : 0, allAppsFade);
|
||||
setter.setViewAlpha(mAppsView.getScrollBar(), hasAllAppsContent ? 1 : 0, allAppsFade);
|
||||
mAppsView.getFloatingHeaderView().setContentVisibility(hasHeaderExtra,
|
||||
hasAllAppsContent, setter, headerFade, allAppsFade);
|
||||
|
||||
mAppsView.getSearchUiManager().setContentVisibility(visibleElements, setter, allAppsFade);
|
||||
|
||||
setter.setInt(mScrimView, ScrimView.DRAG_HANDLE_ALPHA,
|
||||
@@ -228,8 +237,12 @@ public class AllAppsTransitionController implements StateHandler<LauncherState>,
|
||||
public void setupViews(AllAppsContainerView appsView, ScrimView scrimView) {
|
||||
mAppsView = appsView;
|
||||
mScrimView = scrimView;
|
||||
PluginManagerWrapper.INSTANCE.get(mLauncher)
|
||||
.addPluginListener(this, AllAppsSearchPlugin.class, false);
|
||||
if (FeatureFlags.ENABLE_DEVICE_SEARCH.get() && BuildCompat.isAtLeastR()) {
|
||||
mInsetController = new AllAppsInsetTransitionController(mShiftRange, mAppsView);
|
||||
mLauncher.getSystemUiController().updateUiState(UI_STATE_ALLAPPS,
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -252,47 +265,11 @@ public class AllAppsTransitionController implements StateHandler<LauncherState>,
|
||||
if (Float.compare(mProgress, 1f) == 0) {
|
||||
mAppsView.reset(false /* animate */);
|
||||
}
|
||||
updatePluginAnimationEnd();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPluginConnected(AllAppsSearchPlugin plugin, Context context) {
|
||||
mPlugin = plugin;
|
||||
mPluginContent = mLauncher.getLayoutInflater().inflate(
|
||||
R.layout.all_apps_content_layout, mAppsView, false);
|
||||
mAppsView.addView(mPluginContent);
|
||||
mPluginContent.setAlpha(0f);
|
||||
mPlugin.setup((ViewGroup) mPluginContent, mLauncher, mShiftRange);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPluginDisconnected(AllAppsSearchPlugin plugin) {
|
||||
mPlugin = null;
|
||||
mAppsView.removeView(mPluginContent);
|
||||
}
|
||||
|
||||
public void onActivityDestroyed() {
|
||||
PluginManagerWrapper.INSTANCE.get(mLauncher).removePluginListener(this);
|
||||
}
|
||||
|
||||
/** Used for the plugin to signal when drag starts happens
|
||||
* @param toAllApps*/
|
||||
public void onDragStart(boolean toAllApps) {
|
||||
if (mPlugin == null) return;
|
||||
|
||||
if (toAllApps) {
|
||||
EditText editText = mAppsView.getSearchUiManager().setTextSearchEnabled(true);
|
||||
mPlugin.setEditText(editText);
|
||||
}
|
||||
mPlugin.onDragStart(toAllApps ? 1f : 0f);
|
||||
}
|
||||
|
||||
private void updatePluginAnimationEnd() {
|
||||
if (mPlugin == null) return;
|
||||
mPlugin.onAnimationEnd(mProgress);
|
||||
if (Float.compare(mProgress, 1f) == 0) {
|
||||
mAppsView.getSearchUiManager().setTextSearchEnabled(false);
|
||||
mPlugin.setEditText(null);
|
||||
if (FeatureFlags.ENABLE_DEVICE_SEARCH.get() && BuildCompat.isAtLeastR()) {
|
||||
mInsetController.onAnimationEnd(mProgress);
|
||||
if (Float.compare(mProgress, 1f) == 0) {
|
||||
mAppsView.getSearchUiManager().setTextSearchEnabled(true).requestFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,8 @@ import android.util.Log;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import androidx.core.os.BuildCompat;
|
||||
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherAnimUtils;
|
||||
import com.android.launcher3.LauncherState;
|
||||
@@ -44,6 +46,7 @@ import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.anim.AnimationSuccessListener;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.logger.LauncherAtom;
|
||||
import com.android.launcher3.logging.StatsLogManager;
|
||||
import com.android.launcher3.states.StateAnimationConfig;
|
||||
@@ -265,8 +268,10 @@ public abstract class AbstractStateChangeTouchController
|
||||
mCanBlockFling = mFromState == NORMAL;
|
||||
mFlingBlockCheck.unblockFling();
|
||||
// Must be called after all the animation controllers have been paused
|
||||
if (mToState == ALL_APPS || mToState == NORMAL) {
|
||||
mLauncher.getAllAppsController().onDragStart(mToState == ALL_APPS);
|
||||
if (FeatureFlags.ENABLE_DEVICE_SEARCH.get() && BuildCompat.isAtLeastR()
|
||||
&& (mToState == ALL_APPS || mToState == NORMAL)) {
|
||||
mLauncher.getAllAppsController().getInsetController().onDragStart(
|
||||
mToState == ALL_APPS ? 0 : 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ public class SystemUiController {
|
||||
public static final int UI_STATE_SCRIM_VIEW = 1;
|
||||
public static final int UI_STATE_WIDGET_BOTTOM_SHEET = 2;
|
||||
public static final int UI_STATE_OVERVIEW = 3;
|
||||
public static final int UI_STATE_ALLAPPS = 4;
|
||||
|
||||
public static final int FLAG_LIGHT_NAV = 1 << 0;
|
||||
public static final int FLAG_DARK_NAV = 1 << 1;
|
||||
@@ -40,7 +41,7 @@ public class SystemUiController {
|
||||
public static final int FLAG_DARK_STATUS = 1 << 3;
|
||||
|
||||
private final Window mWindow;
|
||||
private final int[] mStates = new int[4];
|
||||
private final int[] mStates = new int[5];
|
||||
|
||||
public SystemUiController(Window window) {
|
||||
mWindow = window;
|
||||
|
||||
Reference in New Issue
Block a user