Merging from ub-launcher3-master @ build 6767682
Test: manual, presubmit on the source branch x20/teams/android-launcher/merge/ub-launcher3-master_master_6767682.html Change-Id: I5e9c73a7ac3033fe82006c4bd72824f56b8988f8
This commit is contained in:
+5
-12
@@ -48,7 +48,7 @@ LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/protos/ --proto_path=$(LOCAL_PA
|
||||
LOCAL_PROTO_JAVA_OUTPUT_PARAMS := enum_style=java
|
||||
|
||||
LOCAL_SDK_VERSION := current
|
||||
LOCAL_MIN_SDK_VERSION := 21
|
||||
LOCAL_MIN_SDK_VERSION := 26
|
||||
LOCAL_MODULE := Launcher3CommonDepsLib
|
||||
LOCAL_PRIVILEGED_MODULE := true
|
||||
LOCAL_MANIFEST_FILE := AndroidManifest-common.xml
|
||||
@@ -77,7 +77,7 @@ LOCAL_PROGUARD_FLAG_FILES := proguard.flags
|
||||
LOCAL_PROGUARD_ENABLED := disabled
|
||||
|
||||
LOCAL_SDK_VERSION := current
|
||||
LOCAL_MIN_SDK_VERSION := 21
|
||||
LOCAL_MIN_SDK_VERSION := 26
|
||||
LOCAL_PACKAGE_NAME := Launcher3
|
||||
LOCAL_PRIVILEGED_MODULE := true
|
||||
LOCAL_SYSTEM_EXT_MODULE := true
|
||||
@@ -108,7 +108,7 @@ LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/go/res
|
||||
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
|
||||
|
||||
LOCAL_SDK_VERSION := current
|
||||
LOCAL_MIN_SDK_VERSION := 21
|
||||
LOCAL_MIN_SDK_VERSION := 26
|
||||
LOCAL_PACKAGE_NAME := Launcher3Go
|
||||
LOCAL_PRIVILEGED_MODULE := true
|
||||
LOCAL_SYSTEM_EXT_MODULE := true
|
||||
@@ -149,12 +149,9 @@ LOCAL_STATIC_ANDROID_LIBRARIES := Launcher3CommonDepsLib
|
||||
LOCAL_SRC_FILES := \
|
||||
$(call all-java-files-under, src) \
|
||||
$(call all-java-files-under, quickstep/src) \
|
||||
$(call all-java-files-under, quickstep/recents_ui_overrides/src) \
|
||||
$(call all-java-files-under, src_shortcuts_overrides)
|
||||
|
||||
LOCAL_RESOURCE_DIR := \
|
||||
$(LOCAL_PATH)/quickstep/res \
|
||||
$(LOCAL_PATH)/quickstep/recents_ui_overrides/res
|
||||
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/quickstep/res
|
||||
LOCAL_PROGUARD_ENABLED := disabled
|
||||
|
||||
|
||||
@@ -183,9 +180,7 @@ LOCAL_SYSTEM_EXT_MODULE := true
|
||||
LOCAL_OVERRIDES_PACKAGES := Home Launcher2 Launcher3
|
||||
LOCAL_REQUIRED_MODULES := privapp_whitelist_com.android.launcher3
|
||||
|
||||
LOCAL_RESOURCE_DIR := \
|
||||
$(LOCAL_PATH)/quickstep/res \
|
||||
$(LOCAL_PATH)/quickstep/recents_ui_overrides/res
|
||||
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/quickstep/res
|
||||
|
||||
LOCAL_FULL_LIBS_MANIFEST_FILES := \
|
||||
$(LOCAL_PATH)/quickstep/AndroidManifest-launcher.xml \
|
||||
@@ -220,12 +215,10 @@ LOCAL_STATIC_ANDROID_LIBRARIES := Launcher3CommonDepsLib
|
||||
LOCAL_SRC_FILES := \
|
||||
$(call all-java-files-under, src) \
|
||||
$(call all-java-files-under, quickstep/src) \
|
||||
$(call all-java-files-under, quickstep/recents_ui_overrides/src) \
|
||||
$(call all-java-files-under, go/src)
|
||||
|
||||
LOCAL_RESOURCE_DIR := \
|
||||
$(LOCAL_PATH)/quickstep/res \
|
||||
$(LOCAL_PATH)/quickstep/recents_ui_overrides/res \
|
||||
$(LOCAL_PATH)/go/res
|
||||
|
||||
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
|
||||
|
||||
@@ -29,12 +29,6 @@
|
||||
at compile time. Note that the components defined in AndroidManifest.xml are also required,
|
||||
with some minor changed based on the derivative app.
|
||||
-->
|
||||
<permission
|
||||
android:name="com.android.launcher.permission.INSTALL_SHORTCUT"
|
||||
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
|
||||
android:protectionLevel="dangerous"
|
||||
android:label="@string/permlab_install_shortcut"
|
||||
android:description="@string/permdesc_install_shortcut" />
|
||||
|
||||
<uses-permission android:name="android.permission.CALL_PHONE" />
|
||||
<uses-permission android:name="android.permission.SET_WALLPAPER" />
|
||||
@@ -79,17 +73,6 @@
|
||||
android:restoreAnyVersion="true"
|
||||
android:supportsRtl="true" >
|
||||
|
||||
<!-- Intent received used to install shortcuts from other applications -->
|
||||
<receiver
|
||||
android:name="com.android.launcher3.InstallShortcutReceiver"
|
||||
android:permission="com.android.launcher.permission.INSTALL_SHORTCUT"
|
||||
android:exported="true"
|
||||
android:enabled="@bool/enable_install_shortcut_api" >
|
||||
<intent-filter>
|
||||
<action android:name="com.android.launcher.action.INSTALL_SHORTCUT" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<!-- Intent received when a session is committed -->
|
||||
<receiver
|
||||
android:name="com.android.launcher3.SessionCommitReceiver"
|
||||
@@ -116,7 +99,6 @@
|
||||
<service
|
||||
android:name="com.android.launcher3.notification.NotificationListener"
|
||||
android:label="@string/notification_dots_service_title"
|
||||
android:enabled="@bool/notification_dots_enabled"
|
||||
android:exported="true"
|
||||
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
|
||||
<intent-filter>
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@
|
||||
<manifest
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.android.launcher3">
|
||||
<uses-sdk android:targetSdkVersion="29" android:minSdkVersion="25"/>
|
||||
<uses-sdk android:targetSdkVersion="29" android:minSdkVersion="26"/>
|
||||
<!--
|
||||
Manifest entries specific to Launcher3. This is merged with AndroidManifest-common.xml.
|
||||
Refer comments around specific entries on how to extend individual components.
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
160759508
|
||||
144170434
|
||||
144170434
|
||||
161801331
|
||||
162564471
|
||||
160361464
|
||||
161901771
|
||||
160568387
|
||||
162623012
|
||||
162012217
|
||||
160718310
|
||||
160361464
|
||||
160718310
|
||||
162012217
|
||||
160748731
|
||||
154951045
|
||||
162861289
|
||||
149934536
|
||||
149934536
|
||||
144170434
|
||||
144170434
|
||||
162454040
|
||||
161273376
|
||||
149934536
|
||||
149934536
|
||||
158701272
|
||||
162871508
|
||||
149934536
|
||||
161939759
|
||||
154964045
|
||||
161536946
|
||||
149934536
|
||||
161685099
|
||||
162812884
|
||||
162480567
|
||||
162480567
|
||||
149934536
|
||||
149934536
|
||||
@@ -0,0 +1,24 @@
|
||||
144170434
|
||||
149934536
|
||||
154951045
|
||||
154964045
|
||||
158701272
|
||||
160361464
|
||||
160568387
|
||||
160718310
|
||||
160748731
|
||||
160759508
|
||||
161273376
|
||||
161536946
|
||||
161685099
|
||||
161801331
|
||||
161901771
|
||||
161939759
|
||||
162012217
|
||||
162454040
|
||||
162480567
|
||||
162564471
|
||||
162623012
|
||||
162812884
|
||||
162861289
|
||||
162871508
|
||||
@@ -0,0 +1,24 @@
|
||||
144170434 twickham P1 FIXED Improve Overview -> Home transition ----
|
||||
149934536 twickham P2 FIXED Update gesture nav pullback logic ----
|
||||
154951045 peanutbutter P1 FIXED Odd animation occuring at times when swiping to home ----
|
||||
154964045 awickham P2 FIXED "Clear all" text is not in the middle of app's window vertically ----
|
||||
158701272 twickham P4 FIXED Discontinuities when long-swiping to home ----
|
||||
160361464 tracyzhou P2 FIXED Place launcher above the target app in live tile mode ----
|
||||
160568387 twickham P2 FIXED Can't get to app switcher by swiping up (motion pause not detected) ----
|
||||
160718310 xuqiu P1 FIXED With "Select" overview action selected, App icon is missing in other overview apps after orientation change ----
|
||||
160748731 sunnygoyal P2 ASSIGNED Unify prediction model with Launcher model ----
|
||||
160759508 twickham P2 FIXED Swipe up cannot back to home screen in overview. ----
|
||||
161273376 xuqiu P2 FIXED [Overview Actions] Add logging and helpful messages ----
|
||||
161536946 twickham P2 FIXED Haptics don't indicate snap-to in overview, ----
|
||||
161685099 winsonc P2 FIXED Screen still stay at the quick settings/notification when I swipe up with 3 finger to check the all apps. ----
|
||||
161801331 hyunyoungs P2 FIXED Change AllAppsSearch plugin to support only data fetch ----
|
||||
161901771 xuqiu P1 FIXED Overlapping layer of highlights with app layout getting darker when keep rotating the device from "Feedback" viewpoint in split screen ----
|
||||
161939759 sunnygoyal P2 FIXED RD1A: Going to overview in landscape mode clips the screen content ----
|
||||
162012217 perumaal P2 ASSIGNED Leaked Activity Caused by Gleams ----
|
||||
162454040 bookatz P2 ASSIGNED Create multiuser test that checks that opening an app works properly ----
|
||||
162480567 sfufa P4 FIXED Enable Item Decorations for search items ----
|
||||
162564471 tracyzhou P2 FIXED [Live tile] Handle tapping overview actions in live tile mode ----
|
||||
162623012 zakcohen P1 ASSIGNED Enable chips flag ----
|
||||
162812884 winsonc P2 ASSIGNED [R]The color have not changed in some page after turning on the dark theme. ----
|
||||
162861289 hyunyoungs P2 FIXED Add FocusIndicator support to DEVICE_SEARCH feature in S ----
|
||||
162871508 sfufa P2 ASSIGNED Introduce support for Hero app section ----
|
||||
+1133
File diff suppressed because it is too large
Load Diff
@@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2017 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.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<!-- Dynamic Grid -->
|
||||
<dimen name="dynamic_grid_hotseat_size">60dp</dimen>
|
||||
</resources>
|
||||
@@ -20,7 +20,6 @@ import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.model.BgDataModel.Callbacks;
|
||||
import com.android.launcher3.util.LooperExecutor;
|
||||
|
||||
/**
|
||||
* Helper class to handle results of {@link com.android.launcher3.model.LoaderTask}.
|
||||
@@ -29,12 +28,7 @@ public class LoaderResults extends BaseLoaderResults {
|
||||
|
||||
public LoaderResults(LauncherAppState app, BgDataModel dataModel,
|
||||
AllAppsList allAppsList, Callbacks[] callbacks) {
|
||||
this(app, dataModel, allAppsList, callbacks, MAIN_EXECUTOR);
|
||||
}
|
||||
|
||||
public LoaderResults(LauncherAppState app, BgDataModel dataModel,
|
||||
AllAppsList allAppsList, Callbacks[] callbacks, LooperExecutor executor) {
|
||||
super(app, dataModel, allAppsList, callbacks, executor);
|
||||
super(app, dataModel, allAppsList, callbacks, MAIN_EXECUTOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
<resources>
|
||||
<color name="chip_hint_foreground_color">#fff</color>
|
||||
<color name="chip_scrim_start_color">#39000000</color>
|
||||
|
||||
<color name="all_apps_label_text">#61000000</color>
|
||||
<color name="all_apps_label_text_dark">#61FFFFFF</color>
|
||||
<color name="all_apps_prediction_row_separator">#3c000000</color>
|
||||
<color name="all_apps_prediction_row_separator_dark">#3cffffff</color>
|
||||
</resources>
|
||||
@@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
<resources>
|
||||
<integer name="max_depth_blur_radius">150</integer>
|
||||
</resources>
|
||||
@@ -1,38 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
<resources>
|
||||
<dimen name="chip_hint_border_width">1dp</dimen>
|
||||
<dimen name="chip_hint_corner_radius">20dp</dimen>
|
||||
<dimen name="chip_hint_outer_padding">20dp</dimen>
|
||||
<dimen name="chip_hint_start_padding">10dp</dimen>
|
||||
<dimen name="chip_hint_end_padding">12dp</dimen>
|
||||
<dimen name="chip_hint_horizontal_margin">20dp</dimen>
|
||||
<dimen name="chip_hint_vertical_offset">16dp</dimen>
|
||||
<dimen name="chip_hint_elevation">2dp</dimen>
|
||||
<dimen name="chip_icon_size">16dp</dimen>
|
||||
<dimen name="chip_text_height">26dp</dimen>
|
||||
<dimen name="chip_text_top_padding">4dp</dimen>
|
||||
<dimen name="chip_text_start_padding">10dp</dimen>
|
||||
<dimen name="chip_text_size">14sp</dimen>
|
||||
|
||||
<dimen name="all_apps_prediction_row_divider_height">17dp</dimen>
|
||||
<dimen name="all_apps_label_top_padding">16dp</dimen>
|
||||
<dimen name="all_apps_label_bottom_padding">8dp</dimen>
|
||||
<dimen name="all_apps_label_text_size">14sp</dimen>
|
||||
|
||||
<!-- Minimum distance to swipe to trigger accessibility gesture -->
|
||||
<dimen name="accessibility_gesture_min_swipe_distance">80dp</dimen>
|
||||
</resources>
|
||||
@@ -0,0 +1,2 @@
|
||||
Temp file to prevent build breakage.
|
||||
Will be removed in followup cl.
|
||||
-138
@@ -1,138 +0,0 @@
|
||||
/*
|
||||
* 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.model;
|
||||
|
||||
import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_GRID;
|
||||
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_PREDICTION;
|
||||
|
||||
import android.app.prediction.AppPredictionContext;
|
||||
import android.app.prediction.AppPredictionManager;
|
||||
import android.app.prediction.AppPredictor;
|
||||
import android.app.prediction.AppTarget;
|
||||
import android.app.prediction.AppTargetEvent;
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.WorkerThread;
|
||||
|
||||
import com.android.launcher3.InvariantDeviceProfile;
|
||||
import com.android.launcher3.InvariantDeviceProfile.OnIDPChangeListener;
|
||||
import com.android.launcher3.model.BgDataModel.FixedContainerItems;
|
||||
import com.android.launcher3.util.Executors;
|
||||
import com.android.quickstep.logging.StatsLogCompatManager;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Model delegate which loads prediction items
|
||||
*/
|
||||
public class QuickstepModelDelegate extends ModelDelegate implements OnIDPChangeListener {
|
||||
|
||||
public static final String LAST_PREDICTION_ENABLED_STATE = "last_prediction_enabled_state";
|
||||
|
||||
private final InvariantDeviceProfile mIDP;
|
||||
private final AppEventProducer mAppEventProducer;
|
||||
|
||||
private AppPredictor mAllAppsPredictor;
|
||||
private boolean mActive = false;
|
||||
|
||||
public QuickstepModelDelegate(Context context) {
|
||||
mAppEventProducer = new AppEventProducer(context, this::onAppTargetEvent);
|
||||
|
||||
mIDP = InvariantDeviceProfile.INSTANCE.get(context);
|
||||
mIDP.addOnChangeListener(this);
|
||||
StatsLogCompatManager.LOGS_CONSUMER.add(mAppEventProducer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadItems() {
|
||||
// TODO: Implement caching and preloading
|
||||
super.loadItems();
|
||||
mDataModel.extraItems.put(
|
||||
CONTAINER_PREDICTION, new FixedContainerItems(CONTAINER_PREDICTION));
|
||||
|
||||
mActive = true;
|
||||
recreatePredictors();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateData() {
|
||||
super.validateData();
|
||||
if (mAllAppsPredictor != null) {
|
||||
mAllAppsPredictor.requestPredictionUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
super.destroy();
|
||||
mActive = false;
|
||||
StatsLogCompatManager.LOGS_CONSUMER.remove(mAppEventProducer);
|
||||
|
||||
destroyPredictors();
|
||||
mIDP.removeOnChangeListener(this);
|
||||
}
|
||||
|
||||
private void destroyPredictors() {
|
||||
if (mAllAppsPredictor != null) {
|
||||
mAllAppsPredictor.destroy();
|
||||
mAllAppsPredictor = null;
|
||||
}
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
private void recreatePredictors() {
|
||||
destroyPredictors();
|
||||
if (!mActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
Context context = mApp.getContext();
|
||||
AppPredictionManager apm = context.getSystemService(AppPredictionManager.class);
|
||||
if (apm == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int count = mIDP.numAllAppsColumns;
|
||||
|
||||
mAllAppsPredictor = apm.createAppPredictionSession(
|
||||
new AppPredictionContext.Builder(context)
|
||||
.setUiSurface("home")
|
||||
.setPredictedTargetCount(count)
|
||||
.build());
|
||||
mAllAppsPredictor.registerPredictionUpdates(
|
||||
Executors.MODEL_EXECUTOR, this::onAllAppsPredictionChanged);
|
||||
mAllAppsPredictor.requestPredictionUpdate();
|
||||
}
|
||||
|
||||
private void onAllAppsPredictionChanged(List<AppTarget> targets) {
|
||||
mApp.getModel().enqueueModelUpdateTask(
|
||||
new PredictionUpdateTask(CONTAINER_PREDICTION, targets));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onIdpChanged(int changeFlags, InvariantDeviceProfile profile) {
|
||||
if ((changeFlags & CHANGE_FLAG_GRID) != 0) {
|
||||
// Reinitialize everything
|
||||
Executors.MODEL_EXECUTOR.execute(this::recreatePredictors);
|
||||
}
|
||||
}
|
||||
|
||||
private void onAppTargetEvent(AppTargetEvent event) {
|
||||
if (mAllAppsPredictor != null) {
|
||||
mAllAppsPredictor.notifyAppTargetEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* 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.uioverrides.states;
|
||||
|
||||
import com.android.launcher3.Launcher;
|
||||
|
||||
public class OverviewPeekState extends OverviewState {
|
||||
private static final float OVERVIEW_OFFSET = 0.7f;
|
||||
|
||||
public OverviewPeekState(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float[] getOverviewScaleAndOffset(Launcher launcher) {
|
||||
return new float[] {NO_SCALE, OVERVIEW_OFFSET};
|
||||
}
|
||||
}
|
||||
-279
@@ -1,279 +0,0 @@
|
||||
/*
|
||||
* 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.uioverrides.touchcontrollers;
|
||||
|
||||
import static com.android.launcher3.LauncherState.ALL_APPS;
|
||||
import static com.android.launcher3.LauncherState.NORMAL;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW_PEEK;
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_HEADER_FADE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_SCALE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_TRANSLATE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.PLAY_ATOMIC_OVERVIEW_PEEK;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
|
||||
import static com.android.launcher3.uioverrides.states.QuickstepAtomicAnimationFactory.INDEX_PAUSE_TO_OVERVIEW_ANIM;
|
||||
import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.anim.AnimationSuccessListener;
|
||||
import com.android.launcher3.anim.Interpolators;
|
||||
import com.android.launcher3.states.StateAnimationConfig;
|
||||
import com.android.launcher3.states.StateAnimationConfig.AnimationFlags;
|
||||
import com.android.launcher3.testing.TestProtocol;
|
||||
import com.android.launcher3.uioverrides.states.QuickstepAtomicAnimationFactory;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
|
||||
import com.android.launcher3.util.VibratorWrapper;
|
||||
import com.android.quickstep.SystemUiProxy;
|
||||
import com.android.quickstep.util.MotionPauseDetector;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
|
||||
/**
|
||||
* Touch controller which handles swipe and hold to go to Overview
|
||||
*/
|
||||
public class FlingAndHoldTouchController extends PortraitStatesTouchController {
|
||||
|
||||
private static final long PEEK_IN_ANIM_DURATION = 240;
|
||||
private static final long PEEK_OUT_ANIM_DURATION = 100;
|
||||
private static final float MAX_DISPLACEMENT_PERCENT = 0.75f;
|
||||
|
||||
protected final MotionPauseDetector mMotionPauseDetector;
|
||||
private final float mMotionPauseMinDisplacement;
|
||||
private final float mMotionPauseMaxDisplacement;
|
||||
|
||||
private AnimatorSet mPeekAnim;
|
||||
|
||||
public FlingAndHoldTouchController(Launcher l) {
|
||||
super(l, false /* allowDragToOverview */);
|
||||
mMotionPauseDetector = new MotionPauseDetector(l);
|
||||
mMotionPauseMinDisplacement = ViewConfiguration.get(l).getScaledTouchSlop();
|
||||
mMotionPauseMaxDisplacement = getMotionPauseMaxDisplacement();
|
||||
}
|
||||
|
||||
protected float getMotionPauseMaxDisplacement() {
|
||||
return getShiftRange() * MAX_DISPLACEMENT_PERCENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long getAtomicDuration() {
|
||||
return QuickstepAtomicAnimationFactory.ATOMIC_DURATION_FROM_PAUSED_TO_OVERVIEW;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDragStart(boolean start, float startDisplacement) {
|
||||
mMotionPauseDetector.clear();
|
||||
|
||||
super.onDragStart(start, startDisplacement);
|
||||
|
||||
if (handlingOverviewAnim()) {
|
||||
mMotionPauseDetector.setOnMotionPauseListener(this::onMotionPauseChanged);
|
||||
}
|
||||
|
||||
if (mAtomicAnim != null) {
|
||||
mAtomicAnim.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
protected void onMotionPauseChanged(boolean isPaused) {
|
||||
RecentsView recentsView = mLauncher.getOverviewPanel();
|
||||
recentsView.setOverviewStateEnabled(isPaused);
|
||||
if (mPeekAnim != null) {
|
||||
mPeekAnim.cancel();
|
||||
}
|
||||
LauncherState fromState = isPaused ? NORMAL : OVERVIEW_PEEK;
|
||||
LauncherState toState = isPaused ? OVERVIEW_PEEK : NORMAL;
|
||||
long peekDuration = isPaused ? PEEK_IN_ANIM_DURATION : PEEK_OUT_ANIM_DURATION;
|
||||
|
||||
StateAnimationConfig config = new StateAnimationConfig();
|
||||
config.duration = peekDuration;
|
||||
config.animFlags = PLAY_ATOMIC_OVERVIEW_PEEK;
|
||||
mPeekAnim = mLauncher.getStateManager().createAtomicAnimation(
|
||||
fromState, toState, config);
|
||||
mPeekAnim.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
mPeekAnim = null;
|
||||
}
|
||||
});
|
||||
mPeekAnim.start();
|
||||
VibratorWrapper.INSTANCE.get(mLauncher).vibrate(OVERVIEW_HAPTIC);
|
||||
|
||||
mLauncher.getDragLayer().getScrim().createSysuiMultiplierAnim(isPaused ? 0 : 1)
|
||||
.setDuration(peekDuration).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether we are handling the overview animation, rather than
|
||||
* having it as part of the existing animation to the target state.
|
||||
*/
|
||||
protected boolean handlingOverviewAnim() {
|
||||
int stateFlags = SystemUiProxy.INSTANCE.get(mLauncher).getLastSystemUiStateFlags();
|
||||
return mStartState == NORMAL && (stateFlags & SYSUI_STATE_OVERVIEW_DISABLED) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StateAnimationConfig getConfigForStates(
|
||||
LauncherState fromState, LauncherState toState) {
|
||||
if (fromState == NORMAL && toState == ALL_APPS) {
|
||||
StateAnimationConfig builder = new StateAnimationConfig();
|
||||
// Fade in prediction icons quickly, then rest of all apps after reaching overview.
|
||||
float progressToReachOverview = NORMAL.getVerticalProgress(mLauncher)
|
||||
- OVERVIEW.getVerticalProgress(mLauncher);
|
||||
builder.setInterpolator(ANIM_ALL_APPS_HEADER_FADE, Interpolators.clampToProgress(
|
||||
ACCEL,
|
||||
0,
|
||||
ALL_APPS_CONTENT_FADE_THRESHOLD));
|
||||
builder.setInterpolator(ANIM_ALL_APPS_FADE, Interpolators.clampToProgress(
|
||||
ACCEL,
|
||||
progressToReachOverview,
|
||||
progressToReachOverview + ALL_APPS_CONTENT_FADE_THRESHOLD));
|
||||
|
||||
// Get workspace out of the way quickly, to prepare for potential pause.
|
||||
builder.setInterpolator(ANIM_WORKSPACE_SCALE, DEACCEL_3);
|
||||
builder.setInterpolator(ANIM_WORKSPACE_TRANSLATE, DEACCEL_3);
|
||||
builder.setInterpolator(ANIM_WORKSPACE_FADE, DEACCEL_3);
|
||||
return builder;
|
||||
} else if (fromState == ALL_APPS && toState == NORMAL) {
|
||||
StateAnimationConfig builder = new StateAnimationConfig();
|
||||
// Keep all apps/predictions opaque until the very end of the transition.
|
||||
float progressToReachOverview = OVERVIEW.getVerticalProgress(mLauncher);
|
||||
builder.setInterpolator(ANIM_ALL_APPS_FADE, Interpolators.clampToProgress(
|
||||
DEACCEL,
|
||||
progressToReachOverview - ALL_APPS_CONTENT_FADE_THRESHOLD,
|
||||
progressToReachOverview));
|
||||
builder.setInterpolator(ANIM_ALL_APPS_HEADER_FADE, Interpolators.clampToProgress(
|
||||
DEACCEL,
|
||||
1 - ALL_APPS_CONTENT_FADE_THRESHOLD,
|
||||
1));
|
||||
return builder;
|
||||
}
|
||||
return super.getConfigForStates(fromState, toState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDrag(float displacement, MotionEvent event) {
|
||||
if (TestProtocol.sDebugTracing) {
|
||||
Log.d(TestProtocol.PAUSE_NOT_DETECTED, "FlingAndHoldTouchController");
|
||||
}
|
||||
float upDisplacement = -displacement;
|
||||
mMotionPauseDetector.setDisallowPause(!handlingOverviewAnim()
|
||||
|| upDisplacement < mMotionPauseMinDisplacement
|
||||
|| upDisplacement > mMotionPauseMaxDisplacement);
|
||||
mMotionPauseDetector.addPosition(event);
|
||||
return super.onDrag(displacement, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDragEnd(float velocity) {
|
||||
if (mMotionPauseDetector.isPaused() && handlingOverviewAnim()) {
|
||||
goToOverviewOnDragEnd(velocity);
|
||||
} else {
|
||||
super.onDragEnd(velocity);
|
||||
}
|
||||
|
||||
View searchView = mLauncher.getAppsView().getSearchView();
|
||||
if (searchView instanceof FeedbackHandler) {
|
||||
((FeedbackHandler) searchView).resetFeedback();
|
||||
}
|
||||
mMotionPauseDetector.clear();
|
||||
}
|
||||
|
||||
protected void goToOverviewOnDragEnd(float velocity) {
|
||||
if (mPeekAnim != null) {
|
||||
mPeekAnim.cancel();
|
||||
}
|
||||
|
||||
Animator overviewAnim = mLauncher.createAtomicAnimationFactory()
|
||||
.createStateElementAnimation(INDEX_PAUSE_TO_OVERVIEW_ANIM);
|
||||
mAtomicAnim = new AnimatorSet();
|
||||
mAtomicAnim.addListener(new AnimationSuccessListener() {
|
||||
@Override
|
||||
public void onAnimationSuccess(Animator animator) {
|
||||
onSwipeInteractionCompleted(OVERVIEW, Touch.SWIPE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
super.onAnimationEnd(animation);
|
||||
if (mCancelled) {
|
||||
StateAnimationConfig config = new StateAnimationConfig();
|
||||
config.animFlags = PLAY_ATOMIC_OVERVIEW_PEEK;
|
||||
config.duration = PEEK_OUT_ANIM_DURATION;
|
||||
mPeekAnim = mLauncher.getStateManager().createAtomicAnimation(
|
||||
mFromState, mToState, config);
|
||||
mPeekAnim.start();
|
||||
}
|
||||
mAtomicAnim = null;
|
||||
}
|
||||
});
|
||||
mAtomicAnim.play(overviewAnim);
|
||||
mAtomicAnim.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void goToTargetState(LauncherState targetState, int logAction) {
|
||||
if (mPeekAnim != null && mPeekAnim.isStarted()) {
|
||||
// Don't jump to the target state until overview is no longer peeking.
|
||||
mPeekAnim.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
FlingAndHoldTouchController.super.goToTargetState(targetState, logAction);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
super.goToTargetState(targetState, logAction);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@AnimationFlags
|
||||
protected int updateAnimComponentsOnReinit(@AnimationFlags int animComponents) {
|
||||
if (handlingOverviewAnim()) {
|
||||
// We don't want the state transition to all apps to animate overview,
|
||||
// as that will cause a jump after our atomic animation.
|
||||
return animComponents | SKIP_OVERVIEW;
|
||||
} else {
|
||||
return animComponents;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for views with feedback animation requiring reset
|
||||
*/
|
||||
public interface FeedbackHandler {
|
||||
|
||||
/**
|
||||
* reset searchWidget feedback
|
||||
*/
|
||||
void resetFeedback();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
/*
|
||||
* 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.quickstep.util;
|
||||
|
||||
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
|
||||
import static com.android.launcher3.uioverrides.states.QuickstepAtomicAnimationFactory.INDEX_SHELF_ANIM;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.uioverrides.states.OverviewState;
|
||||
|
||||
/**
|
||||
* Animates the shelf between states HIDE, PEEK, and OVERVIEW.
|
||||
*/
|
||||
public class ShelfPeekAnim {
|
||||
|
||||
public static final Interpolator INTERPOLATOR = OVERSHOOT_1_2;
|
||||
public static final long DURATION = 240;
|
||||
|
||||
private final Launcher mLauncher;
|
||||
|
||||
private ShelfAnimState mShelfState;
|
||||
private boolean mIsPeeking;
|
||||
|
||||
public ShelfPeekAnim(Launcher launcher) {
|
||||
mLauncher = launcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* Animates to the given state, canceling the previous animation if it was still running.
|
||||
*/
|
||||
public void setShelfState(ShelfAnimState shelfState, Interpolator interpolator, long duration) {
|
||||
if (mShelfState == shelfState || FeatureFlags.ENABLE_OVERVIEW_ACTIONS.get()) {
|
||||
return;
|
||||
}
|
||||
mLauncher.getStateManager().cancelStateElementAnimation(INDEX_SHELF_ANIM);
|
||||
mShelfState = shelfState;
|
||||
mIsPeeking = mShelfState == ShelfAnimState.PEEK || mShelfState == ShelfAnimState.HIDE;
|
||||
if (mShelfState == ShelfAnimState.CANCEL) {
|
||||
return;
|
||||
}
|
||||
float shelfHiddenProgress = BACKGROUND_APP.getVerticalProgress(mLauncher);
|
||||
float shelfOverviewProgress = OVERVIEW.getVerticalProgress(mLauncher);
|
||||
// Peek based on default overview progress so we can see hotseat if we're showing
|
||||
// that instead of predictions in overview.
|
||||
float defaultOverviewProgress = OverviewState.getDefaultVerticalProgress(mLauncher);
|
||||
float shelfPeekingProgress = shelfHiddenProgress
|
||||
- (shelfHiddenProgress - defaultOverviewProgress) * 0.25f;
|
||||
float toProgress = mShelfState == ShelfAnimState.HIDE
|
||||
? shelfHiddenProgress
|
||||
: mShelfState == ShelfAnimState.PEEK
|
||||
? shelfPeekingProgress
|
||||
: shelfOverviewProgress;
|
||||
Animator shelfAnim = mLauncher.getStateManager()
|
||||
.createStateElementAnimation(INDEX_SHELF_ANIM, toProgress);
|
||||
shelfAnim.setInterpolator(interpolator);
|
||||
shelfAnim.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
mShelfState = ShelfAnimState.CANCEL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animator) {
|
||||
mIsPeeking = mShelfState == ShelfAnimState.PEEK;
|
||||
}
|
||||
});
|
||||
shelfAnim.setDuration(duration).start();
|
||||
}
|
||||
|
||||
/** @return Whether the shelf is currently peeking or animating to or from peeking. */
|
||||
public boolean isPeeking() {
|
||||
return mIsPeeking;
|
||||
}
|
||||
|
||||
/** The various shelf states we can animate to. */
|
||||
public enum ShelfAnimState {
|
||||
HIDE(true), PEEK(true), OVERVIEW(false), CANCEL(false);
|
||||
|
||||
ShelfAnimState(boolean shouldPreformHaptic) {
|
||||
this.shouldPreformHaptic = shouldPreformHaptic;
|
||||
}
|
||||
|
||||
public final boolean shouldPreformHaptic;
|
||||
}
|
||||
}
|
||||
@@ -23,5 +23,4 @@
|
||||
android:text="@string/recents_clear_all"
|
||||
android:textColor="?attr/workspaceTextColor"
|
||||
android:textSize="14sp"
|
||||
android:translationY="@dimen/task_thumbnail_half_top_margin"
|
||||
/>
|
||||
android:translationY="@dimen/task_thumbnail_half_top_margin" />
|
||||
@@ -16,4 +16,12 @@
|
||||
<resources>
|
||||
<color name="back_arrow_color_light">#FFFFFFFF</color>
|
||||
<color name="back_arrow_color_dark">#99000000</color>
|
||||
|
||||
<color name="chip_hint_foreground_color">#fff</color>
|
||||
<color name="chip_scrim_start_color">#39000000</color>
|
||||
|
||||
<color name="all_apps_label_text">#61000000</color>
|
||||
<color name="all_apps_label_text_dark">#61FFFFFF</color>
|
||||
<color name="all_apps_prediction_row_separator">#3c000000</color>
|
||||
<color name="all_apps_prediction_row_separator_dark">#3cffffff</color>
|
||||
</resources>
|
||||
@@ -16,6 +16,8 @@
|
||||
<resources>
|
||||
<string name="task_overlay_factory_class" translatable="false"/>
|
||||
|
||||
<string name="overscroll_plugin_factory_class" translatable="false" />
|
||||
|
||||
<!-- Activities which block home gesture -->
|
||||
<string-array name="gesture_blocking_activities" translatable="false">
|
||||
<item>com.android.launcher3/com.android.quickstep.interaction.GestureSandboxActivity</item>
|
||||
@@ -35,4 +37,6 @@
|
||||
<integer name="assistant_gesture_corner_deg_threshold">20</integer>
|
||||
|
||||
<string name="wellbeing_provider_pkg" translatable="false"/>
|
||||
|
||||
<integer name="max_depth_blur_radius">150</integer>
|
||||
</resources>
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
|
||||
<dimen name="recents_page_spacing">10dp</dimen>
|
||||
<dimen name="recents_clear_all_deadzone_vertical_margin">70dp</dimen>
|
||||
<dimen name="overview_peek_distance">96dp</dimen>
|
||||
|
||||
<!-- The speed in dp/s at which the user needs to be scrolling in recents such that we start
|
||||
loading full resolution screenshots. -->
|
||||
@@ -102,4 +101,26 @@
|
||||
<dimen name="swipe_edu_circle_size">64dp</dimen>
|
||||
<dimen name="swipe_edu_width">80dp</dimen>
|
||||
<dimen name="swipe_edu_max_height">184dp</dimen>
|
||||
|
||||
<dimen name="chip_hint_border_width">1dp</dimen>
|
||||
<dimen name="chip_hint_corner_radius">20dp</dimen>
|
||||
<dimen name="chip_hint_outer_padding">20dp</dimen>
|
||||
<dimen name="chip_hint_start_padding">10dp</dimen>
|
||||
<dimen name="chip_hint_end_padding">12dp</dimen>
|
||||
<dimen name="chip_hint_horizontal_margin">20dp</dimen>
|
||||
<dimen name="chip_hint_vertical_offset">16dp</dimen>
|
||||
<dimen name="chip_hint_elevation">2dp</dimen>
|
||||
<dimen name="chip_icon_size">16dp</dimen>
|
||||
<dimen name="chip_text_height">26dp</dimen>
|
||||
<dimen name="chip_text_top_padding">4dp</dimen>
|
||||
<dimen name="chip_text_start_padding">10dp</dimen>
|
||||
<dimen name="chip_text_size">14sp</dimen>
|
||||
|
||||
<dimen name="all_apps_prediction_row_divider_height">17dp</dimen>
|
||||
<dimen name="all_apps_label_top_padding">16dp</dimen>
|
||||
<dimen name="all_apps_label_bottom_padding">8dp</dimen>
|
||||
<dimen name="all_apps_label_text_size">14sp</dimen>
|
||||
|
||||
<!-- Minimum distance to swipe to trigger accessibility gesture -->
|
||||
<dimen name="accessibility_gesture_min_swipe_distance">80dp</dimen>
|
||||
</resources>
|
||||
|
||||
-1
@@ -32,4 +32,3 @@
|
||||
<string name="model_delegate_class" translatable="false">com.android.launcher3.model.QuickstepModelDelegate</string>
|
||||
|
||||
</resources>
|
||||
|
||||
+4
-4
@@ -32,7 +32,7 @@ import android.view.MotionEvent;
|
||||
import android.view.Surface;
|
||||
|
||||
import com.android.launcher3.ResourceUtils;
|
||||
import com.android.launcher3.util.DefaultDisplay;
|
||||
import com.android.launcher3.util.DisplayController;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
@@ -50,7 +50,7 @@ public class OrientationTouchTransformerTest {
|
||||
private OrientationTouchTransformer mTouchTransformer;
|
||||
|
||||
Resources mResources;
|
||||
private DefaultDisplay.Info mInfo;
|
||||
private DisplayController.Info mInfo;
|
||||
|
||||
|
||||
@Before
|
||||
@@ -231,12 +231,12 @@ public class OrientationTouchTransformerTest {
|
||||
assertTrue(mTouchTransformer.touchInValidSwipeRegions(inRegion2.getX(), inRegion2.getY()));
|
||||
}
|
||||
|
||||
private DefaultDisplay.Info createDisplayInfo(int rotation) {
|
||||
private DisplayController.Info createDisplayInfo(int rotation) {
|
||||
Point p = new Point(SIZE_WIDTH, SIZE_HEIGHT);
|
||||
if (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) {
|
||||
p = new Point(SIZE_HEIGHT, SIZE_WIDTH);
|
||||
}
|
||||
return new DefaultDisplay.Info(0, rotation, 0, p, p, p, null);
|
||||
return new DisplayController.Info(0, rotation, 0, p, p, p, null);
|
||||
}
|
||||
|
||||
private float generateTouchRegionHeight(int rotation) {
|
||||
|
||||
@@ -60,9 +60,9 @@ public class RecentsActivityTest {
|
||||
|
||||
FallbackRecentsView frv = activity.getOverviewPanel();
|
||||
|
||||
RunningTaskInfo dummyTask = new RunningTaskInfo();
|
||||
dummyTask.taskId = 22;
|
||||
frv.showCurrentTask(dummyTask);
|
||||
RunningTaskInfo placeholderTask = new RunningTaskInfo();
|
||||
placeholderTask.taskId = 22;
|
||||
frv.showCurrentTask(placeholderTask);
|
||||
doLayout(activity);
|
||||
|
||||
ThumbnailData thumbnailData = new ThumbnailData();
|
||||
|
||||
+2
-2
@@ -27,7 +27,7 @@ import android.view.SurfaceControl;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.InvariantDeviceProfile;
|
||||
import com.android.launcher3.shadows.LShadowDisplay;
|
||||
import com.android.launcher3.util.DefaultDisplay;
|
||||
import com.android.launcher3.util.DisplayController;
|
||||
import com.android.quickstep.LauncherActivityInterface;
|
||||
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
|
||||
|
||||
@@ -144,7 +144,7 @@ public class TaskViewSimulatorTest {
|
||||
LauncherActivityInterface.INSTANCE);
|
||||
tvs.setDp(mDeviceProfile);
|
||||
|
||||
int launcherRotation = DefaultDisplay.INSTANCE.get(mContext).getInfo().rotation;
|
||||
int launcherRotation = DisplayController.INSTANCE.get(mContext).getInfo().rotation;
|
||||
if (mAppRotation < 0) {
|
||||
mAppRotation = launcherRotation;
|
||||
}
|
||||
|
||||
@@ -50,7 +50,6 @@ import com.android.quickstep.SystemUiProxy;
|
||||
import com.android.quickstep.util.QuickstepOnboardingPrefs;
|
||||
import com.android.quickstep.util.RemoteAnimationProvider;
|
||||
import com.android.quickstep.util.RemoteFadeOutAnimationListener;
|
||||
import com.android.quickstep.util.ShelfPeekAnim;
|
||||
import com.android.quickstep.views.OverviewActionsView;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
@@ -73,8 +72,6 @@ public abstract class BaseQuickstepLauncher extends Launcher
|
||||
(context, arg1, arg2) -> SystemUiProxy.INSTANCE.get(context).setBackButtonAlpha(
|
||||
Float.intBitsToFloat(arg1), arg2 != 0);
|
||||
|
||||
private final ShelfPeekAnim mShelfPeekAnim = new ShelfPeekAnim(this);
|
||||
|
||||
private OverviewActionsView mActionsView;
|
||||
protected HotseatPredictionController mHotseatPredictionController;
|
||||
|
||||
@@ -196,7 +193,7 @@ public abstract class BaseQuickstepLauncher extends Launcher
|
||||
}
|
||||
|
||||
private boolean isOverviewActionsEnabled() {
|
||||
return FeatureFlags.ENABLE_OVERVIEW_ACTIONS.get() && removeShelfFromOverview(this);
|
||||
return removeShelfFromOverview(this);
|
||||
}
|
||||
|
||||
public <T extends OverviewActionsView> T getActionsView() {
|
||||
@@ -317,10 +314,6 @@ public abstract class BaseQuickstepLauncher extends Launcher
|
||||
Stream.of(WellbeingModel.SHORTCUT_FACTORY));
|
||||
}
|
||||
|
||||
public ShelfPeekAnim getShelfPeekAnim() {
|
||||
return mShelfPeekAnim;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Prediction controller for hybrid hotseat
|
||||
*/
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
package com.android.launcher3;
|
||||
|
||||
import static com.android.launcher3.Utilities.postAsyncCallback;
|
||||
import static com.android.launcher3.util.DefaultDisplay.getSingleFrameMs;
|
||||
import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
|
||||
import static com.android.systemui.shared.recents.utilities.Utilities.postAtFrontOfQueueAsynchronously;
|
||||
|
||||
import android.animation.Animator;
|
||||
|
||||
@@ -45,7 +45,6 @@ import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.ActivityOptions;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
@@ -55,7 +54,6 @@ import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.CancellationSignal;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
@@ -94,7 +92,6 @@ import com.android.systemui.shared.system.WindowManagerWrapper;
|
||||
* {@link LauncherAppTransitionManager} with Quickstep-specific app transitions for launching from
|
||||
* home and/or all-apps. Not used for 3p launchers.
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.O)
|
||||
@SuppressWarnings("unused")
|
||||
public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTransitionManager
|
||||
implements OnDeviceProfileChangeListener {
|
||||
|
||||
+15
-3
@@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -42,6 +42,7 @@ import com.android.launcher3.R;
|
||||
import com.android.launcher3.allapps.FloatingHeaderRow;
|
||||
import com.android.launcher3.allapps.FloatingHeaderView;
|
||||
import com.android.launcher3.anim.PropertySetter;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.statemanager.StateManager.StateListener;
|
||||
import com.android.launcher3.util.Themes;
|
||||
|
||||
@@ -90,7 +91,8 @@ public class AppsDividerView extends View implements StateListener<LauncherState
|
||||
mLauncher = Launcher.getLauncher(context);
|
||||
|
||||
boolean isMainColorDark = Themes.getAttrBoolean(context, R.attr.isMainColorDark);
|
||||
mPaint.setStrokeWidth(getResources().getDimensionPixelSize(R.dimen.all_apps_divider_height));
|
||||
mPaint.setStrokeWidth(
|
||||
getResources().getDimensionPixelSize(R.dimen.all_apps_divider_height));
|
||||
|
||||
mStrokeColor = ContextCompat.getColor(context, isMainColorDark
|
||||
? R.color.all_apps_prediction_row_separator_dark
|
||||
@@ -134,7 +136,7 @@ public class AppsDividerView extends View implements StateListener<LauncherState
|
||||
if (row == this) {
|
||||
break;
|
||||
} else if (row.shouldDraw()) {
|
||||
sectionCount ++;
|
||||
sectionCount++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,6 +183,11 @@ public class AppsDividerView extends View implements StateListener<LauncherState
|
||||
}
|
||||
|
||||
private void updateViewVisibility() {
|
||||
// hide divider since we have item decoration for prediction row
|
||||
if (FeatureFlags.ENABLE_DEVICE_SEARCH.get()) {
|
||||
setVisibility(GONE);
|
||||
return;
|
||||
}
|
||||
setVisibility(mDividerType == DividerType.NONE
|
||||
? GONE
|
||||
: (mIsScrolledOut ? INVISIBLE : VISIBLE));
|
||||
@@ -303,4 +310,9 @@ public class AppsDividerView extends View implements StateListener<LauncherState
|
||||
public Class<AppsDividerView> getTypeClass() {
|
||||
return AppsDividerView.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getFocusedChild() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+24
-1
@@ -45,10 +45,12 @@ import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.allapps.AllAppsSectionDecorator;
|
||||
import com.android.launcher3.allapps.FloatingHeaderRow;
|
||||
import com.android.launcher3.allapps.FloatingHeaderView;
|
||||
import com.android.launcher3.anim.AlphaUpdateListener;
|
||||
import com.android.launcher3.anim.PropertySetter;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.keyboard.FocusIndicatorHelper;
|
||||
import com.android.launcher3.keyboard.FocusIndicatorHelper.SimpleFocusIndicatorHelper;
|
||||
import com.android.launcher3.logging.StatsLogUtils.LogContainerProvider;
|
||||
@@ -110,6 +112,8 @@ public class PredictionRowView extends LinearLayout implements
|
||||
|
||||
private boolean mPredictionsEnabled = false;
|
||||
|
||||
AllAppsSectionDecorator.SectionDecorationHandler mDecorationHandler;
|
||||
|
||||
public PredictionRowView(@NonNull Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
@@ -128,6 +132,11 @@ public class PredictionRowView extends LinearLayout implements
|
||||
mIconFullTextAlpha = Color.alpha(mIconTextColor);
|
||||
mIconCurrentTextAlpha = mIconFullTextAlpha;
|
||||
|
||||
if (FeatureFlags.ENABLE_DEVICE_SEARCH.get()) {
|
||||
mDecorationHandler = new AllAppsSectionDecorator.SectionDecorationHandler(getContext(),
|
||||
false);
|
||||
}
|
||||
|
||||
updateVisibility();
|
||||
}
|
||||
|
||||
@@ -153,6 +162,15 @@ public class PredictionRowView extends LinearLayout implements
|
||||
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
if (mDecorationHandler != null) {
|
||||
mDecorationHandler.reset();
|
||||
int childrenCount = getChildCount();
|
||||
for (int i = 0; i < childrenCount; i++) {
|
||||
mDecorationHandler.extendBounds(getChildAt(i));
|
||||
}
|
||||
mDecorationHandler.onDraw(canvas);
|
||||
mDecorationHandler.onFocusDraw(canvas, getFocusedChild());
|
||||
}
|
||||
mFocusHelper.draw(canvas);
|
||||
super.dispatchDraw(canvas);
|
||||
}
|
||||
@@ -166,7 +184,7 @@ public class PredictionRowView extends LinearLayout implements
|
||||
|
||||
@Override
|
||||
public boolean shouldDraw() {
|
||||
return getVisibility() != GONE;
|
||||
return getVisibility() == VISIBLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -347,4 +365,9 @@ public class PredictionRowView extends LinearLayout implements
|
||||
public Class<PredictionRowView> getTypeClass() {
|
||||
return PredictionRowView.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getFocusedChild() {
|
||||
return getChildAt(0);
|
||||
}
|
||||
}
|
||||
-1
@@ -284,4 +284,3 @@ public class HotseatEduController {
|
||||
return new Intent(SETTINGS_ACTION).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
}
|
||||
}
|
||||
|
||||
+21
-19
@@ -21,6 +21,7 @@ import static com.android.quickstep.InstantAppResolverImpl.COMPONENT_CLASS_MARKE
|
||||
|
||||
import android.app.prediction.AppTarget;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.LauncherActivityInfo;
|
||||
import android.content.pm.LauncherApps;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
@@ -29,6 +30,7 @@ import android.os.UserHandle;
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.model.BgDataModel.FixedContainerItems;
|
||||
import com.android.launcher3.model.QuickstepModelDelegate.PredictorState;
|
||||
import com.android.launcher3.model.data.AppInfo;
|
||||
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
||||
|
||||
@@ -43,27 +45,22 @@ import java.util.stream.Collectors;
|
||||
public class PredictionUpdateTask extends BaseModelUpdateTask {
|
||||
|
||||
private final List<AppTarget> mTargets;
|
||||
private final int mContainerId;
|
||||
private final PredictorState mPredictorState;
|
||||
|
||||
PredictionUpdateTask(int containerId, List<AppTarget> targets) {
|
||||
mContainerId = containerId;
|
||||
PredictionUpdateTask(PredictorState predictorState, List<AppTarget> targets) {
|
||||
mPredictorState = predictorState;
|
||||
mTargets = targets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) {
|
||||
// TODO: persist the whole list
|
||||
Utilities.getDevicePrefs(app.getContext()).edit()
|
||||
Context context = app.getContext();
|
||||
|
||||
// TODO: remove this
|
||||
Utilities.getDevicePrefs(context).edit()
|
||||
.putBoolean(LAST_PREDICTION_ENABLED_STATE, !mTargets.isEmpty()).apply();
|
||||
|
||||
FixedContainerItems fci;
|
||||
synchronized (dataModel) {
|
||||
fci = dataModel.extraItems.get(mContainerId);
|
||||
if (fci == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
FixedContainerItems fci = mPredictorState.items;
|
||||
Set<UserHandle> usersForChangedShortcuts = new HashSet<>(fci.items.stream()
|
||||
.filter(info -> info.itemType == ITEM_TYPE_DEEP_SHORTCUT)
|
||||
.map(info -> info.user)
|
||||
@@ -75,7 +72,7 @@ public class PredictionUpdateTask extends BaseModelUpdateTask {
|
||||
ShortcutInfo si = target.getShortcutInfo();
|
||||
if (si != null) {
|
||||
usersForChangedShortcuts.add(si.getUserHandle());
|
||||
itemInfo = new WorkspaceItemInfo(si, app.getContext());
|
||||
itemInfo = new WorkspaceItemInfo(si, context);
|
||||
app.getIconCache().getShortcutIcon(itemInfo, si);
|
||||
} else {
|
||||
String className = target.getClassName();
|
||||
@@ -87,16 +84,18 @@ public class PredictionUpdateTask extends BaseModelUpdateTask {
|
||||
UserHandle user = target.getUser();
|
||||
itemInfo = apps.data.stream()
|
||||
.filter(info -> user.equals(info.user) && cn.equals(info.componentName))
|
||||
.map(AppInfo::makeWorkspaceItem)
|
||||
.map(ai -> {
|
||||
app.getIconCache().getTitleAndIcon(ai, false);
|
||||
return ai.makeWorkspaceItem();
|
||||
})
|
||||
.findAny()
|
||||
.orElseGet(() -> {
|
||||
LauncherActivityInfo lai = app.getContext()
|
||||
.getSystemService(LauncherApps.class)
|
||||
LauncherActivityInfo lai = context.getSystemService(LauncherApps.class)
|
||||
.resolveActivity(AppInfo.makeLaunchIntent(cn), user);
|
||||
if (lai == null) {
|
||||
return null;
|
||||
}
|
||||
AppInfo ai = new AppInfo(app.getContext(), lai, user);
|
||||
AppInfo ai = new AppInfo(context, lai, user);
|
||||
app.getIconCache().getTitleAndIcon(ai, lai, false);
|
||||
return ai.makeWorkspaceItem();
|
||||
});
|
||||
@@ -106,12 +105,15 @@ public class PredictionUpdateTask extends BaseModelUpdateTask {
|
||||
}
|
||||
}
|
||||
|
||||
itemInfo.container = mContainerId;
|
||||
itemInfo.container = fci.containerId;
|
||||
fci.items.add(itemInfo);
|
||||
}
|
||||
|
||||
bindExtraContainerItems(fci);
|
||||
usersForChangedShortcuts.forEach(
|
||||
u -> dataModel.updateShortcutPinnedState(app.getContext(), u));
|
||||
|
||||
// Save to disk
|
||||
mPredictorState.storage.write(context, fci.items);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,273 @@
|
||||
/*
|
||||
* 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.model;
|
||||
|
||||
import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_GRID;
|
||||
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_PREDICTION;
|
||||
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
|
||||
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
|
||||
|
||||
import android.app.prediction.AppPredictionContext;
|
||||
import android.app.prediction.AppPredictionManager;
|
||||
import android.app.prediction.AppPredictor;
|
||||
import android.app.prediction.AppTarget;
|
||||
import android.app.prediction.AppTargetEvent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.LauncherActivityInfo;
|
||||
import android.content.pm.LauncherApps;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.os.UserHandle;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.WorkerThread;
|
||||
|
||||
import com.android.launcher3.InvariantDeviceProfile;
|
||||
import com.android.launcher3.InvariantDeviceProfile.OnIDPChangeListener;
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.model.BgDataModel.FixedContainerItems;
|
||||
import com.android.launcher3.model.data.AppInfo;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
||||
import com.android.launcher3.shortcuts.ShortcutKey;
|
||||
import com.android.launcher3.util.Executors;
|
||||
import com.android.launcher3.util.PersistedItemArray;
|
||||
import com.android.quickstep.logging.StatsLogCompatManager;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
/**
|
||||
* Model delegate which loads prediction items
|
||||
*/
|
||||
public class QuickstepModelDelegate extends ModelDelegate implements OnIDPChangeListener {
|
||||
|
||||
public static final String LAST_PREDICTION_ENABLED_STATE = "last_prediction_enabled_state";
|
||||
|
||||
private final PredictorState mAllAppsState =
|
||||
new PredictorState(CONTAINER_PREDICTION, "all_apps_predictions");
|
||||
|
||||
private final InvariantDeviceProfile mIDP;
|
||||
private final AppEventProducer mAppEventProducer;
|
||||
|
||||
private boolean mActive = false;
|
||||
|
||||
public QuickstepModelDelegate(Context context) {
|
||||
mAppEventProducer = new AppEventProducer(context, this::onAppTargetEvent);
|
||||
|
||||
mIDP = InvariantDeviceProfile.INSTANCE.get(context);
|
||||
mIDP.addOnChangeListener(this);
|
||||
StatsLogCompatManager.LOGS_CONSUMER.add(mAppEventProducer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadItems(UserManagerState ums, Map<ShortcutKey, ShortcutInfo> pinnedShortcuts) {
|
||||
// TODO: Implement caching and preloading
|
||||
super.loadItems(ums, pinnedShortcuts);
|
||||
|
||||
WorkspaceItemFactory factory =
|
||||
new WorkspaceItemFactory(mApp, ums, pinnedShortcuts, mIDP.numAllAppsColumns);
|
||||
mAllAppsState.items.setItems(
|
||||
mAllAppsState.storage.read(mApp.getContext(), factory, ums.allUsers::get));
|
||||
mDataModel.extraItems.put(CONTAINER_PREDICTION, mAllAppsState.items);
|
||||
|
||||
mActive = true;
|
||||
recreatePredictors();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateData() {
|
||||
super.validateData();
|
||||
if (mAllAppsState.predictor != null) {
|
||||
mAllAppsState.predictor.requestPredictionUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
super.destroy();
|
||||
mActive = false;
|
||||
StatsLogCompatManager.LOGS_CONSUMER.remove(mAppEventProducer);
|
||||
|
||||
destroyPredictors();
|
||||
mIDP.removeOnChangeListener(this);
|
||||
}
|
||||
|
||||
private void destroyPredictors() {
|
||||
mAllAppsState.destroyPredictor();
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
private void recreatePredictors() {
|
||||
destroyPredictors();
|
||||
if (!mActive) {
|
||||
return;
|
||||
}
|
||||
Context context = mApp.getContext();
|
||||
AppPredictionManager apm = context.getSystemService(AppPredictionManager.class);
|
||||
if (apm == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int count = mIDP.numAllAppsColumns;
|
||||
|
||||
mAllAppsState.predictor = apm.createAppPredictionSession(
|
||||
new AppPredictionContext.Builder(context)
|
||||
.setUiSurface("home")
|
||||
.setPredictedTargetCount(count)
|
||||
.build());
|
||||
mAllAppsState.predictor.registerPredictionUpdates(
|
||||
Executors.MODEL_EXECUTOR, t -> handleUpdate(mAllAppsState, t));
|
||||
mAllAppsState.predictor.requestPredictionUpdate();
|
||||
}
|
||||
|
||||
|
||||
private void handleUpdate(PredictorState state, List<AppTarget> targets) {
|
||||
if (state.setTargets(targets)) {
|
||||
// No diff, skip
|
||||
return;
|
||||
}
|
||||
mApp.getModel().enqueueModelUpdateTask(new PredictionUpdateTask(state, targets));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onIdpChanged(int changeFlags, InvariantDeviceProfile profile) {
|
||||
if ((changeFlags & CHANGE_FLAG_GRID) != 0) {
|
||||
// Reinitialize everything
|
||||
Executors.MODEL_EXECUTOR.execute(this::recreatePredictors);
|
||||
}
|
||||
}
|
||||
|
||||
private void onAppTargetEvent(AppTargetEvent event) {
|
||||
if (mAllAppsState.predictor != null) {
|
||||
mAllAppsState.predictor.notifyAppTargetEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
static class PredictorState {
|
||||
|
||||
public final FixedContainerItems items;
|
||||
public final PersistedItemArray storage;
|
||||
public AppPredictor predictor;
|
||||
|
||||
private List<AppTarget> mLastTargets;
|
||||
|
||||
PredictorState(int container, String storageName) {
|
||||
items = new FixedContainerItems(container);
|
||||
storage = new PersistedItemArray(storageName);
|
||||
mLastTargets = Collections.emptyList();
|
||||
}
|
||||
|
||||
public void destroyPredictor() {
|
||||
if (predictor != null) {
|
||||
predictor.destroy();
|
||||
predictor = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the new targets and returns true if it was different than before.
|
||||
*/
|
||||
boolean setTargets(List<AppTarget> newTargets) {
|
||||
List<AppTarget> oldTargets = mLastTargets;
|
||||
mLastTargets = newTargets;
|
||||
|
||||
int size = oldTargets.size();
|
||||
return size == newTargets.size() && IntStream.range(0, size)
|
||||
.allMatch(i -> areAppTargetsSame(oldTargets.get(i), newTargets.get(i)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two targets for the properties which we care about
|
||||
*/
|
||||
private static boolean areAppTargetsSame(AppTarget t1, AppTarget t2) {
|
||||
if (!Objects.equals(t1.getPackageName(), t2.getPackageName())
|
||||
|| !Objects.equals(t1.getUser(), t2.getUser())
|
||||
|| !Objects.equals(t1.getClassName(), t2.getClassName())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ShortcutInfo s1 = t1.getShortcutInfo();
|
||||
ShortcutInfo s2 = t2.getShortcutInfo();
|
||||
if (s1 != null) {
|
||||
if (s2 == null || !Objects.equals(s1.getId(), s2.getId())) {
|
||||
return false;
|
||||
}
|
||||
} else if (s2 != null) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static class WorkspaceItemFactory implements PersistedItemArray.ItemFactory {
|
||||
|
||||
private final LauncherAppState mAppState;
|
||||
private final UserManagerState mUMS;
|
||||
private final Map<ShortcutKey, ShortcutInfo> mPinnedShortcuts;
|
||||
private final int mMaxCount;
|
||||
|
||||
private int mReadCount = 0;
|
||||
|
||||
protected WorkspaceItemFactory(LauncherAppState appState, UserManagerState ums,
|
||||
Map<ShortcutKey, ShortcutInfo> pinnedShortcuts, int maxCount) {
|
||||
mAppState = appState;
|
||||
mUMS = ums;
|
||||
mPinnedShortcuts = pinnedShortcuts;
|
||||
mMaxCount = maxCount;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ItemInfo createInfo(int itemType, UserHandle user, Intent intent) {
|
||||
if (mReadCount >= mMaxCount) {
|
||||
return null;
|
||||
}
|
||||
switch (itemType) {
|
||||
case ITEM_TYPE_APPLICATION: {
|
||||
LauncherActivityInfo lai = mAppState.getContext()
|
||||
.getSystemService(LauncherApps.class)
|
||||
.resolveActivity(intent, user);
|
||||
if (lai == null) {
|
||||
return null;
|
||||
}
|
||||
AppInfo info = new AppInfo(lai, user, mUMS.isUserQuiet(user));
|
||||
mAppState.getIconCache().getTitleAndIcon(info, lai, false);
|
||||
mReadCount++;
|
||||
return info.makeWorkspaceItem();
|
||||
}
|
||||
case ITEM_TYPE_DEEP_SHORTCUT: {
|
||||
ShortcutKey key = ShortcutKey.fromIntent(intent, user);
|
||||
if (key == null) {
|
||||
return null;
|
||||
}
|
||||
ShortcutInfo si = mPinnedShortcuts.get(key);
|
||||
if (si == null) {
|
||||
return null;
|
||||
}
|
||||
WorkspaceItemInfo wii = new WorkspaceItemInfo(si, mAppState.getContext());
|
||||
mAppState.getIconCache().getShortcutIcon(wii, si);
|
||||
mReadCount++;
|
||||
return wii;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,11 +24,13 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_MO
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCRIM_FADE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.PLAY_ATOMIC_OVERVIEW_PEEK;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.PLAY_ATOMIC_OVERVIEW_SCALE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
|
||||
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET;
|
||||
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
|
||||
import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
|
||||
|
||||
import android.util.FloatProperty;
|
||||
|
||||
@@ -63,6 +65,7 @@ public abstract class BaseRecentsViewStateController<T extends RecentsView>
|
||||
float[] scaleAndOffset = state.getOverviewScaleAndOffset(mLauncher);
|
||||
RECENTS_SCALE_PROPERTY.set(mRecentsView, scaleAndOffset[0]);
|
||||
ADJACENT_PAGE_OFFSET.set(mRecentsView, scaleAndOffset[1]);
|
||||
TASK_SECONDARY_TRANSLATION.set(mRecentsView, 0f);
|
||||
|
||||
getContentAlphaProperty().set(mRecentsView, state.overviewUi ? 1f : 0);
|
||||
OverviewScrim scrim = mLauncher.getDragLayer().getOverviewScrim();
|
||||
@@ -97,6 +100,8 @@ public abstract class BaseRecentsViewStateController<T extends RecentsView>
|
||||
config.getInterpolator(ANIM_OVERVIEW_SCALE, LINEAR));
|
||||
setter.setFloat(mRecentsView, ADJACENT_PAGE_OFFSET, scaleAndOffset[1],
|
||||
config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_X, LINEAR));
|
||||
setter.setFloat(mRecentsView, TASK_SECONDARY_TRANSLATION, 0f,
|
||||
config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, LINEAR));
|
||||
|
||||
setter.setFloat(mRecentsView, getContentAlphaProperty(), toState.overviewUi ? 1 : 0,
|
||||
config.getInterpolator(ANIM_OVERVIEW_FADE, AGGRESSIVE_EASE_IN_OUT));
|
||||
|
||||
+10
-9
@@ -30,6 +30,7 @@ import static com.android.launcher3.testing.TestProtocol.OVERVIEW_STATE_ORDINAL;
|
||||
import static com.android.launcher3.testing.TestProtocol.QUICK_SWITCH_STATE_ORDINAL;
|
||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||
import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
|
||||
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
@@ -59,7 +60,6 @@ import com.android.launcher3.popup.SystemShortcut;
|
||||
import com.android.launcher3.statemanager.StateManager.AtomicAnimationFactory;
|
||||
import com.android.launcher3.testing.TestProtocol;
|
||||
import com.android.launcher3.uioverrides.states.QuickstepAtomicAnimationFactory;
|
||||
import com.android.launcher3.uioverrides.touchcontrollers.FlingAndHoldTouchController;
|
||||
import com.android.launcher3.uioverrides.touchcontrollers.LandscapeEdgeSwipeController;
|
||||
import com.android.launcher3.uioverrides.touchcontrollers.NavBarToHomeTouchController;
|
||||
import com.android.launcher3.uioverrides.touchcontrollers.NoButtonNavbarToOverviewTouchController;
|
||||
@@ -79,6 +79,7 @@ import com.android.quickstep.SysUINavigationMode.Mode;
|
||||
import com.android.quickstep.SystemUiProxy;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
@@ -170,6 +171,13 @@ public class QuickstepLauncher extends BaseQuickstepLauncher {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void showAllAppsFromIntent(boolean alreadyOnHome) {
|
||||
ActivityManagerWrapper.getInstance().closeSystemWindows(
|
||||
CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY);
|
||||
super.showAllAppsFromIntent(alreadyOnHome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void folderCreatedFromItem(Folder folder, WorkspaceItemInfo itemInfo) {
|
||||
super.folderCreatedFromItem(folder, itemInfo);
|
||||
@@ -298,14 +306,7 @@ public class QuickstepLauncher extends BaseQuickstepLauncher {
|
||||
if (TestProtocol.sDebugTracing) {
|
||||
Log.d(TestProtocol.PAUSE_NOT_DETECTED, "createTouchControllers.2");
|
||||
}
|
||||
if (FeatureFlags.ENABLE_OVERVIEW_ACTIONS.get()) {
|
||||
if (TestProtocol.sDebugTracing) {
|
||||
Log.d(TestProtocol.PAUSE_NOT_DETECTED, "createTouchControllers.3");
|
||||
}
|
||||
list.add(new NoButtonNavbarToOverviewTouchController(this));
|
||||
} else {
|
||||
list.add(new FlingAndHoldTouchController(this));
|
||||
}
|
||||
list.add(new NoButtonNavbarToOverviewTouchController(this));
|
||||
} else {
|
||||
if (getDeviceProfile().isVerticalBarLayout()) {
|
||||
list.add(new OverviewToAllAppsTouchController(this));
|
||||
+7
-4
@@ -17,6 +17,7 @@ package com.android.launcher3.uioverrides;
|
||||
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW_BUTTONS;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_ACTIONS_FADE;
|
||||
import static com.android.quickstep.views.RecentsView.CONTENT_ALPHA;
|
||||
import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS;
|
||||
import static com.android.quickstep.views.RecentsView.TASK_MODALNESS;
|
||||
@@ -57,7 +58,7 @@ public final class RecentsViewStateController extends
|
||||
mRecentsView.updateEmptyMessage();
|
||||
mRecentsView.resetTaskVisuals();
|
||||
}
|
||||
setAlphas(PropertySetter.NO_ANIM_PROPERTY_SETTER, state);
|
||||
setAlphas(PropertySetter.NO_ANIM_PROPERTY_SETTER, new StateAnimationConfig(), state);
|
||||
mRecentsView.setFullscreenProgress(state.getOverviewFullscreenProgress());
|
||||
}
|
||||
|
||||
@@ -75,17 +76,19 @@ public final class RecentsViewStateController extends
|
||||
AnimationSuccessListener.forRunnable(mRecentsView::resetTaskVisuals));
|
||||
}
|
||||
|
||||
setAlphas(builder, toState);
|
||||
setAlphas(builder, config, toState);
|
||||
builder.setFloat(mRecentsView, FULLSCREEN_PROGRESS,
|
||||
toState.getOverviewFullscreenProgress(), LINEAR);
|
||||
}
|
||||
|
||||
private void setAlphas(PropertySetter propertySetter, LauncherState state) {
|
||||
private void setAlphas(PropertySetter propertySetter, StateAnimationConfig config,
|
||||
LauncherState state) {
|
||||
float buttonAlpha = (state.getVisibleElements(mLauncher) & OVERVIEW_BUTTONS) != 0 ? 1 : 0;
|
||||
propertySetter.setFloat(mRecentsView.getClearAllButton(), ClearAllButton.VISIBILITY_ALPHA,
|
||||
buttonAlpha, LINEAR);
|
||||
propertySetter.setFloat(mLauncher.getActionsView().getVisibilityAlpha(),
|
||||
MultiValueAlpha.VALUE, buttonAlpha, LINEAR);
|
||||
MultiValueAlpha.VALUE, buttonAlpha, config.getInterpolator(
|
||||
ANIM_OVERVIEW_ACTIONS_FADE, LINEAR));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -16,8 +16,7 @@
|
||||
package com.android.launcher3.uioverrides.states;
|
||||
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_ACTIONS;
|
||||
import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
|
||||
import static com.android.quickstep.SysUINavigationMode.removeShelfFromOverview;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
@@ -25,7 +24,6 @@ import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.allapps.AllAppsContainerView;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
|
||||
import com.android.quickstep.SysUINavigationMode;
|
||||
|
||||
/**
|
||||
* Definition for AllApps state
|
||||
@@ -65,13 +63,7 @@ public class AllAppsState extends LauncherState {
|
||||
public ScaleAndTranslation getWorkspaceScaleAndTranslation(Launcher launcher) {
|
||||
ScaleAndTranslation scaleAndTranslation = LauncherState.OVERVIEW
|
||||
.getWorkspaceScaleAndTranslation(launcher);
|
||||
if (SysUINavigationMode.getMode(launcher) == NO_BUTTON && !ENABLE_OVERVIEW_ACTIONS.get()) {
|
||||
float normalScale = 1;
|
||||
// Scale down halfway to where we'd be in overview, to prepare for a potential pause.
|
||||
scaleAndTranslation.scale = (scaleAndTranslation.scale + normalScale) / 2;
|
||||
} else {
|
||||
scaleAndTranslation.scale = 1;
|
||||
}
|
||||
scaleAndTranslation.scale = 1;
|
||||
return scaleAndTranslation;
|
||||
}
|
||||
|
||||
@@ -92,7 +84,8 @@ public class AllAppsState extends LauncherState {
|
||||
|
||||
@Override
|
||||
public float[] getOverviewScaleAndOffset(Launcher launcher) {
|
||||
return new float[] {0.9f, 0};
|
||||
float offset = removeShelfFromOverview(launcher) ? 1 : 0;
|
||||
return new float[] {0.9f, offset};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+3
-9
@@ -16,7 +16,6 @@
|
||||
package com.android.launcher3.uioverrides.states;
|
||||
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_ACTIONS;
|
||||
import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
|
||||
import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
|
||||
import static com.android.quickstep.SysUINavigationMode.hideShelfInTwoButtonLandscape;
|
||||
@@ -65,7 +64,7 @@ public class OverviewState extends LauncherState {
|
||||
public int getTransitionDuration(Context context) {
|
||||
// In no-button mode, overview comes in all the way from the left, so give it more time.
|
||||
boolean isNoButtonMode = SysUINavigationMode.INSTANCE.get(context).getMode() == NO_BUTTON;
|
||||
return isNoButtonMode && ENABLE_OVERVIEW_ACTIONS.get() ? 380 : 250;
|
||||
return isNoButtonMode ? 380 : 250;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -108,8 +107,7 @@ public class OverviewState extends LauncherState {
|
||||
|
||||
@Override
|
||||
public ScaleAndTranslation getQsbScaleAndTranslation(Launcher launcher) {
|
||||
if (this == OVERVIEW && ENABLE_OVERVIEW_ACTIONS.get()
|
||||
&& removeShelfFromOverview(launcher)) {
|
||||
if (this == OVERVIEW && removeShelfFromOverview(launcher)) {
|
||||
// Treat the QSB as part of the hotseat so they move together.
|
||||
return getHotseatScaleAndTranslation(launcher);
|
||||
}
|
||||
@@ -129,7 +127,7 @@ public class OverviewState extends LauncherState {
|
||||
@Override
|
||||
public int getVisibleElements(Launcher launcher) {
|
||||
RecentsView recentsView = launcher.getOverviewPanel();
|
||||
if (ENABLE_OVERVIEW_ACTIONS.get() && removeShelfFromOverview(launcher) ||
|
||||
if (removeShelfFromOverview(launcher) ||
|
||||
hideShelfInTwoButtonLandscape(launcher, recentsView.getPagedOrientationHandler())) {
|
||||
return OVERVIEW_BUTTONS;
|
||||
} else if (launcher.getDeviceProfile().isVerticalBarLayout()) {
|
||||
@@ -191,10 +189,6 @@ public class OverviewState extends LauncherState {
|
||||
return new BackgroundAppState(id);
|
||||
}
|
||||
|
||||
public static OverviewState newPeekState(int id) {
|
||||
return new OverviewPeekState(id);
|
||||
}
|
||||
|
||||
public static OverviewState newSwitchState(int id) {
|
||||
return new QuickSwitchState(id);
|
||||
}
|
||||
+18
-25
@@ -22,27 +22,24 @@ import static com.android.launcher3.LauncherState.HINT_STATE;
|
||||
import static com.android.launcher3.LauncherState.HOTSEAT_ICONS;
|
||||
import static com.android.launcher3.LauncherState.NORMAL;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW_PEEK;
|
||||
import static com.android.launcher3.WorkspaceStateTransitionAnimation.getSpringScaleAnimator;
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL_1_7;
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
|
||||
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
|
||||
import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
|
||||
import static com.android.launcher3.anim.Interpolators.INSTANT;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
|
||||
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_7;
|
||||
import static com.android.launcher3.anim.Interpolators.clampToProgress;
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_ACTIONS;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_DEPTH;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_SCALE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_TRANSLATE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FADE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCRIM_FADE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
|
||||
@@ -163,10 +160,15 @@ public class QuickstepAtomicAnimationFactory extends
|
||||
config.setInterpolator(ANIM_WORKSPACE_FADE, ACCEL);
|
||||
config.setInterpolator(ANIM_ALL_APPS_FADE, ACCEL);
|
||||
config.setInterpolator(ANIM_OVERVIEW_SCALE, clampToProgress(ACCEL, 0, 0.9f));
|
||||
config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, ACCEL);
|
||||
config.setInterpolator(ANIM_OVERVIEW_FADE, DEACCEL_1_7);
|
||||
Workspace workspace = mActivity.getWorkspace();
|
||||
config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, ACCEL_DEACCEL);
|
||||
|
||||
if (SysUINavigationMode.getMode(mActivity) == NO_BUTTON) {
|
||||
config.setInterpolator(ANIM_OVERVIEW_FADE, FINAL_FRAME);
|
||||
} else {
|
||||
config.setInterpolator(ANIM_OVERVIEW_FADE, DEACCEL_1_7);
|
||||
}
|
||||
|
||||
Workspace workspace = mActivity.getWorkspace();
|
||||
// Start from a higher workspace scale, but only if we're invisible so we don't jump.
|
||||
boolean isWorkspaceVisible = workspace.getVisibility() == VISIBLE;
|
||||
if (isWorkspaceVisible) {
|
||||
@@ -184,30 +186,23 @@ public class QuickstepAtomicAnimationFactory extends
|
||||
if (!isHotseatVisible) {
|
||||
hotseat.setScaleX(0.92f);
|
||||
hotseat.setScaleY(0.92f);
|
||||
if (ENABLE_OVERVIEW_ACTIONS.get()) {
|
||||
AllAppsContainerView qsbContainer = mActivity.getAppsView();
|
||||
View qsb = qsbContainer.getSearchView();
|
||||
boolean qsbVisible = qsb.getVisibility() == VISIBLE && qsb.getAlpha() > 0;
|
||||
if (!qsbVisible) {
|
||||
qsbContainer.setScaleX(0.92f);
|
||||
qsbContainer.setScaleY(0.92f);
|
||||
}
|
||||
AllAppsContainerView qsbContainer = mActivity.getAppsView();
|
||||
View qsb = qsbContainer.getSearchView();
|
||||
boolean qsbVisible = qsb.getVisibility() == VISIBLE && qsb.getAlpha() > 0;
|
||||
if (!qsbVisible) {
|
||||
qsbContainer.setScaleX(0.92f);
|
||||
qsbContainer.setScaleY(0.92f);
|
||||
}
|
||||
}
|
||||
} else if (toState == NORMAL && fromState == OVERVIEW_PEEK) {
|
||||
// Keep fully visible until the very end (when overview is offscreen) to make invisible.
|
||||
config.setInterpolator(ANIM_OVERVIEW_FADE, FINAL_FRAME);
|
||||
} else if (toState == OVERVIEW_PEEK && fromState == NORMAL) {
|
||||
config.setInterpolator(ANIM_OVERVIEW_FADE, INSTANT);
|
||||
config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, OVERSHOOT_1_7);
|
||||
config.setInterpolator(ANIM_OVERVIEW_SCRIM_FADE, FAST_OUT_SLOW_IN);
|
||||
} else if ((fromState == NORMAL || fromState == HINT_STATE) && toState == OVERVIEW) {
|
||||
if (SysUINavigationMode.getMode(mActivity) == NO_BUTTON) {
|
||||
config.setInterpolator(ANIM_WORKSPACE_SCALE,
|
||||
fromState == NORMAL ? ACCEL : OVERSHOOT_1_2);
|
||||
config.setInterpolator(ANIM_WORKSPACE_TRANSLATE, ACCEL);
|
||||
config.setInterpolator(ANIM_OVERVIEW_FADE, INSTANT);
|
||||
} else {
|
||||
config.setInterpolator(ANIM_WORKSPACE_SCALE, OVERSHOOT_1_2);
|
||||
config.setInterpolator(ANIM_OVERVIEW_FADE, OVERSHOOT_1_2);
|
||||
|
||||
// Scale up the recents, if it is not coming from the side
|
||||
RecentsView overview = mActivity.getOverviewPanel();
|
||||
@@ -219,13 +214,11 @@ public class QuickstepAtomicAnimationFactory extends
|
||||
config.setInterpolator(ANIM_ALL_APPS_FADE, OVERSHOOT_1_2);
|
||||
config.setInterpolator(ANIM_OVERVIEW_SCALE, OVERSHOOT_1_2);
|
||||
config.setInterpolator(ANIM_DEPTH, OVERSHOOT_1_2);
|
||||
Interpolator translationInterpolator = ENABLE_OVERVIEW_ACTIONS.get()
|
||||
&& removeShelfFromOverview(mActivity)
|
||||
Interpolator translationInterpolator = removeShelfFromOverview(mActivity)
|
||||
? OVERSHOOT_1_2
|
||||
: OVERSHOOT_1_7;
|
||||
config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, translationInterpolator);
|
||||
config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, translationInterpolator);
|
||||
config.setInterpolator(ANIM_OVERVIEW_FADE, OVERSHOOT_1_2);
|
||||
} else if (fromState == HINT_STATE && toState == NORMAL) {
|
||||
config.setInterpolator(ANIM_DEPTH, DEACCEL_3);
|
||||
if (mHintToNormalDuration == -1) {
|
||||
+20
-5
@@ -19,13 +19,13 @@ import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
|
||||
import static com.android.launcher3.AbstractFloatingView.TYPE_ALL_APPS_EDU;
|
||||
import static com.android.launcher3.LauncherState.ALL_APPS;
|
||||
import static com.android.launcher3.LauncherState.NORMAL;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||
import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS;
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_ALL_APPS_EDU;
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOME_GESTURE;
|
||||
import static com.android.launcher3.touch.AbstractStateChangeTouchController.SUCCESS_TRANSITION_PROGRESS;
|
||||
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET;
|
||||
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
|
||||
|
||||
import android.animation.ValueAnimator;
|
||||
@@ -45,6 +45,7 @@ import com.android.launcher3.anim.Interpolators;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.compat.AccessibilityManagerCompat;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.graphics.OverviewScrim;
|
||||
import com.android.launcher3.logging.StatsLogManager;
|
||||
import com.android.launcher3.states.StateAnimationConfig;
|
||||
import com.android.launcher3.testing.TestProtocol;
|
||||
@@ -52,7 +53,9 @@ import com.android.launcher3.touch.SingleAxisSwipeDetector;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
|
||||
import com.android.launcher3.util.TouchController;
|
||||
import com.android.quickstep.util.AnimatorControllerWithResistance;
|
||||
import com.android.quickstep.util.AssistantUtilities;
|
||||
import com.android.quickstep.util.OverviewToHomeAnim;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
|
||||
@@ -63,6 +66,8 @@ public class NavBarToHomeTouchController implements TouchController,
|
||||
SingleAxisSwipeDetector.Listener {
|
||||
|
||||
private static final Interpolator PULLBACK_INTERPOLATOR = DEACCEL_3;
|
||||
// How much of the overview scrim we can remove during the transition.
|
||||
private static final float OVERVIEW_TO_HOME_SCRIM_PROGRESS = 0.5f;
|
||||
|
||||
private final Launcher mLauncher;
|
||||
private final SingleAxisSwipeDetector mSwipeDetector;
|
||||
@@ -156,8 +161,13 @@ public class NavBarToHomeTouchController implements TouchController,
|
||||
final PendingAnimation builder = new PendingAnimation(accuracy);
|
||||
if (mStartState.overviewUi) {
|
||||
RecentsView recentsView = mLauncher.getOverviewPanel();
|
||||
builder.setFloat(recentsView, ADJACENT_PAGE_OFFSET,
|
||||
-mPullbackDistance / recentsView.getPageOffsetScale(), PULLBACK_INTERPOLATOR);
|
||||
AnimatorControllerWithResistance.createRecentsResistanceFromOverviewAnim(mLauncher,
|
||||
builder);
|
||||
float endScrimAlpha = Utilities.mapRange(OVERVIEW_TO_HOME_SCRIM_PROGRESS,
|
||||
mStartState.getOverviewScrimAlpha(mLauncher),
|
||||
mEndState.getOverviewScrimAlpha(mLauncher));
|
||||
builder.setFloat(mLauncher.getDragLayer().getOverviewScrim(),
|
||||
OverviewScrim.SCRIM_PROGRESS, endScrimAlpha, PULLBACK_INTERPOLATOR);
|
||||
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
|
||||
builder.addOnFrameCallback(recentsView::redrawLiveTile);
|
||||
}
|
||||
@@ -211,8 +221,13 @@ public class NavBarToHomeTouchController implements TouchController,
|
||||
recentsView.switchToScreenshot(null,
|
||||
() -> recentsView.finishRecentsAnimation(true /* toRecents */, null));
|
||||
}
|
||||
mLauncher.getStateManager().goToState(mEndState, true,
|
||||
() -> onSwipeInteractionCompleted(mEndState));
|
||||
if (mStartState == OVERVIEW) {
|
||||
new OverviewToHomeAnim(mLauncher, () -> onSwipeInteractionCompleted(mEndState))
|
||||
.animateWithVelocity(velocity);
|
||||
} else {
|
||||
mLauncher.getStateManager().goToState(mEndState, true,
|
||||
() -> onSwipeInteractionCompleted(mEndState));
|
||||
}
|
||||
if (mStartState != mEndState) {
|
||||
logStateChange(mStartState.containerType, logAction);
|
||||
}
|
||||
+133
-64
@@ -16,33 +16,45 @@
|
||||
|
||||
package com.android.launcher3.uioverrides.touchcontrollers;
|
||||
|
||||
import static com.android.launcher3.LauncherState.ALL_APPS;
|
||||
import static com.android.launcher3.LauncherState.HINT_STATE;
|
||||
import static com.android.launcher3.LauncherState.NORMAL;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||
import static com.android.launcher3.Utilities.EDGE_NAV_BAR;
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.PLAY_ATOMIC_OVERVIEW_PEEK;
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_HEADER_FADE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_SCALE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_TRANSLATE;
|
||||
import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.graphics.PointF;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.anim.AnimationSuccessListener;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.anim.Interpolators;
|
||||
import com.android.launcher3.graphics.OverviewScrim;
|
||||
import com.android.launcher3.statemanager.StateManager;
|
||||
import com.android.launcher3.states.StateAnimationConfig;
|
||||
import com.android.launcher3.testing.TestProtocol;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
|
||||
import com.android.launcher3.util.VibratorWrapper;
|
||||
import com.android.quickstep.util.StaggeredWorkspaceAnim;
|
||||
import com.android.quickstep.SystemUiProxy;
|
||||
import com.android.quickstep.util.AnimatorControllerWithResistance;
|
||||
import com.android.quickstep.util.MotionPauseDetector;
|
||||
import com.android.quickstep.util.OverviewToHomeAnim;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
|
||||
/**
|
||||
@@ -50,7 +62,7 @@ import com.android.quickstep.views.RecentsView;
|
||||
* the nav bar falls back to go to All Apps. Swiping from the nav bar without holding goes to the
|
||||
* first home screen instead of to Overview.
|
||||
*/
|
||||
public class NoButtonNavbarToOverviewTouchController extends FlingAndHoldTouchController {
|
||||
public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouchController {
|
||||
|
||||
|
||||
// How much of the movement to use for translating overview after swipe and hold.
|
||||
@@ -59,32 +71,29 @@ public class NoButtonNavbarToOverviewTouchController extends FlingAndHoldTouchCo
|
||||
private static final float TRANSLATION_ANIM_VELOCITY_DP_PER_MS = 0.8f;
|
||||
|
||||
private final RecentsView mRecentsView;
|
||||
private final MotionPauseDetector mMotionPauseDetector;
|
||||
private final float mMotionPauseMinDisplacement;
|
||||
|
||||
private boolean mDidTouchStartInNavBar;
|
||||
private boolean mReachedOverview;
|
||||
private boolean mIsOverviewRehidden;
|
||||
private boolean mIsHomeStaggeredAnimFinished;
|
||||
// The last recorded displacement before we reached overview.
|
||||
private PointF mStartDisplacement = new PointF();
|
||||
private float mStartY;
|
||||
private AnimatorPlaybackController mOverviewResistYAnim;
|
||||
|
||||
// Normal to Hint animation has flag SKIP_OVERVIEW, so we update this scrim with this animator.
|
||||
private ObjectAnimator mNormalToHintOverviewScrimAnimator;
|
||||
|
||||
public NoButtonNavbarToOverviewTouchController(Launcher l) {
|
||||
super(l);
|
||||
super(l, false /* allowDragToOverview */);
|
||||
mRecentsView = l.getOverviewPanel();
|
||||
mMotionPauseDetector = new MotionPauseDetector(l);
|
||||
mMotionPauseMinDisplacement = ViewConfiguration.get(l).getScaledTouchSlop();
|
||||
if (TestProtocol.sDebugTracing) {
|
||||
Log.d(TestProtocol.PAUSE_NOT_DETECTED, "NoButtonNavbarToOverviewTouchController.ctor");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getMotionPauseMaxDisplacement() {
|
||||
// No need to disallow pause when swiping up all the way up the screen (unlike
|
||||
// FlingAndHoldTouchController where user is probably intending to go to all apps).
|
||||
return Float.MAX_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canInterceptTouch(MotionEvent ev) {
|
||||
mDidTouchStartInNavBar = (ev.getEdgeFlags() & EDGE_NAV_BAR) != 0;
|
||||
@@ -115,6 +124,13 @@ public class NoButtonNavbarToOverviewTouchController extends FlingAndHoldTouchCo
|
||||
@Override
|
||||
public void onDragStart(boolean start, float startDisplacement) {
|
||||
super.onDragStart(start, startDisplacement);
|
||||
|
||||
mMotionPauseDetector.clear();
|
||||
|
||||
if (handlingOverviewAnim()) {
|
||||
mMotionPauseDetector.setOnMotionPauseListener(this::onMotionPauseChanged);
|
||||
}
|
||||
|
||||
if (mFromState == NORMAL && mToState == HINT_STATE) {
|
||||
mNormalToHintOverviewScrimAnimator = ObjectAnimator.ofFloat(
|
||||
mLauncher.getDragLayer().getOverviewScrim(),
|
||||
@@ -123,6 +139,7 @@ public class NoButtonNavbarToOverviewTouchController extends FlingAndHoldTouchCo
|
||||
mToState.getOverviewScrimAlpha(mLauncher));
|
||||
}
|
||||
mReachedOverview = false;
|
||||
mOverviewResistYAnim = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -135,8 +152,24 @@ public class NoButtonNavbarToOverviewTouchController extends FlingAndHoldTouchCo
|
||||
|
||||
@Override
|
||||
public void onDragEnd(float velocity) {
|
||||
super.onDragEnd(velocity);
|
||||
if (mMotionPauseDetector.isPaused() && handlingOverviewAnim()) {
|
||||
goToOverviewOrHomeOnDragEnd(velocity);
|
||||
} else {
|
||||
super.onDragEnd(velocity);
|
||||
}
|
||||
|
||||
View searchView = mLauncher.getAppsView().getSearchView();
|
||||
if (searchView instanceof FeedbackHandler) {
|
||||
((FeedbackHandler) searchView).resetFeedback();
|
||||
}
|
||||
|
||||
mMotionPauseDetector.clear();
|
||||
mNormalToHintOverviewScrimAnimator = null;
|
||||
if (mLauncher.isInState(OVERVIEW)) {
|
||||
// Normally we would cleanup the state based on mCurrentAnimation, but since we stop
|
||||
// using that when we pause to go to Overview, we need to clean up ourselves.
|
||||
clearState();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -152,14 +185,16 @@ public class NoButtonNavbarToOverviewTouchController extends FlingAndHoldTouchCo
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMotionPauseChanged(boolean isPaused) {
|
||||
private void onMotionPauseChanged(boolean isPaused) {
|
||||
if (mCurrentAnimation == null) {
|
||||
return;
|
||||
}
|
||||
mNormalToHintOverviewScrimAnimator = null;
|
||||
mCurrentAnimation.dispatchOnCancelWithoutCancelRunnable(() -> {
|
||||
mLauncher.getStateManager().goToState(OVERVIEW, true, () -> {
|
||||
mOverviewResistYAnim = AnimatorControllerWithResistance
|
||||
.createRecentsResistanceFromOverviewAnim(mLauncher, null)
|
||||
.createPlaybackController();
|
||||
mReachedOverview = true;
|
||||
maybeSwipeInteractionToOverviewComplete();
|
||||
});
|
||||
@@ -173,16 +208,10 @@ public class NoButtonNavbarToOverviewTouchController extends FlingAndHoldTouchCo
|
||||
}
|
||||
}
|
||||
|
||||
// Used if flinging back to home after reaching overview
|
||||
private void maybeSwipeInteractionToHomeComplete() {
|
||||
if (mIsHomeStaggeredAnimFinished && mIsOverviewRehidden) {
|
||||
onSwipeInteractionCompleted(NORMAL, Touch.FLING);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean handlingOverviewAnim() {
|
||||
return mDidTouchStartInNavBar && super.handlingOverviewAnim();
|
||||
private boolean handlingOverviewAnim() {
|
||||
int stateFlags = SystemUiProxy.INSTANCE.get(mLauncher).getLastSystemUiStateFlags();
|
||||
return mDidTouchStartInNavBar && mStartState == NORMAL
|
||||
&& (stateFlags & SYSUI_STATE_OVERVIEW_DISABLED) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -193,54 +222,37 @@ public class NoButtonNavbarToOverviewTouchController extends FlingAndHoldTouchCo
|
||||
if (mMotionPauseDetector.isPaused()) {
|
||||
if (!mReachedOverview) {
|
||||
mStartDisplacement.set(xDisplacement, yDisplacement);
|
||||
mStartY = event.getY();
|
||||
} else {
|
||||
mRecentsView.setTranslationX((xDisplacement - mStartDisplacement.x)
|
||||
* OVERVIEW_MOVEMENT_FACTOR);
|
||||
mRecentsView.setTranslationY((yDisplacement - mStartDisplacement.y)
|
||||
* OVERVIEW_MOVEMENT_FACTOR);
|
||||
float yProgress = (mStartDisplacement.y - yDisplacement) / mStartY;
|
||||
if (yProgress > 0 && mOverviewResistYAnim != null) {
|
||||
mOverviewResistYAnim.setPlayFraction(yProgress);
|
||||
} else {
|
||||
mRecentsView.setTranslationY((yDisplacement - mStartDisplacement.y)
|
||||
* OVERVIEW_MOVEMENT_FACTOR);
|
||||
}
|
||||
}
|
||||
// Stay in Overview.
|
||||
return true;
|
||||
}
|
||||
|
||||
float upDisplacement = -yDisplacement;
|
||||
mMotionPauseDetector.setDisallowPause(!handlingOverviewAnim()
|
||||
|| upDisplacement < mMotionPauseMinDisplacement);
|
||||
mMotionPauseDetector.addPosition(event);
|
||||
|
||||
return super.onDrag(yDisplacement, xDisplacement, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void goToOverviewOnDragEnd(float velocity) {
|
||||
private void goToOverviewOrHomeOnDragEnd(float velocity) {
|
||||
float velocityDp = dpiFromPx(velocity);
|
||||
boolean isFling = Math.abs(velocityDp) > 1;
|
||||
StateManager<LauncherState> stateManager = mLauncher.getStateManager();
|
||||
boolean goToHomeInsteadOfOverview = isFling;
|
||||
if (goToHomeInsteadOfOverview) {
|
||||
if (velocity > 0) {
|
||||
stateManager.goToState(NORMAL, true,
|
||||
() -> onSwipeInteractionCompleted(NORMAL, Touch.FLING));
|
||||
} else {
|
||||
mIsHomeStaggeredAnimFinished = mIsOverviewRehidden = false;
|
||||
|
||||
StaggeredWorkspaceAnim staggeredWorkspaceAnim = new StaggeredWorkspaceAnim(
|
||||
mLauncher, velocity, false /* animateOverviewScrim */);
|
||||
staggeredWorkspaceAnim.addAnimatorListener(new AnimationSuccessListener() {
|
||||
@Override
|
||||
public void onAnimationSuccess(Animator animator) {
|
||||
mIsHomeStaggeredAnimFinished = true;
|
||||
maybeSwipeInteractionToHomeComplete();
|
||||
}
|
||||
}).start();
|
||||
|
||||
// StaggeredWorkspaceAnim doesn't animate overview, so we handle it here.
|
||||
stateManager.cancelAnimation();
|
||||
StateAnimationConfig config = new StateAnimationConfig();
|
||||
config.duration = OVERVIEW.getTransitionDuration(mLauncher);
|
||||
config.animFlags = PLAY_ATOMIC_OVERVIEW_PEEK;
|
||||
AnimatorSet anim = stateManager.createAtomicAnimation(
|
||||
stateManager.getState(), NORMAL, config);
|
||||
anim.addListener(AnimationSuccessListener.forRunnable(() -> {
|
||||
mIsOverviewRehidden = true;
|
||||
maybeSwipeInteractionToHomeComplete();
|
||||
}));
|
||||
anim.start();
|
||||
}
|
||||
new OverviewToHomeAnim(mLauncher, ()-> onSwipeInteractionCompleted(NORMAL, Touch.FLING))
|
||||
.animateWithVelocity(velocity);
|
||||
}
|
||||
if (mReachedOverview) {
|
||||
float distanceDp = dpiFromPx(Math.max(
|
||||
@@ -256,10 +268,67 @@ public class NoButtonNavbarToOverviewTouchController extends FlingAndHoldTouchCo
|
||||
.withEndAction(goToHomeInsteadOfOverview
|
||||
? null
|
||||
: this::maybeSwipeInteractionToOverviewComplete);
|
||||
if (!goToHomeInsteadOfOverview) {
|
||||
// Return to normal properties for the overview state.
|
||||
StateAnimationConfig config = new StateAnimationConfig();
|
||||
config.duration = duration;
|
||||
LauncherState state = mLauncher.getStateManager().getState();
|
||||
mLauncher.getStateManager().createAtomicAnimation(state, state, config).start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private float dpiFromPx(float pixels) {
|
||||
return Utilities.dpiFromPx(pixels, mLauncher.getResources().getDisplayMetrics());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StateAnimationConfig getConfigForStates(
|
||||
LauncherState fromState, LauncherState toState) {
|
||||
if (fromState == NORMAL && toState == ALL_APPS) {
|
||||
StateAnimationConfig builder = new StateAnimationConfig();
|
||||
// Fade in prediction icons quickly, then rest of all apps after reaching overview.
|
||||
float progressToReachOverview = NORMAL.getVerticalProgress(mLauncher)
|
||||
- OVERVIEW.getVerticalProgress(mLauncher);
|
||||
builder.setInterpolator(ANIM_ALL_APPS_HEADER_FADE, Interpolators.clampToProgress(
|
||||
ACCEL,
|
||||
0,
|
||||
ALL_APPS_CONTENT_FADE_THRESHOLD));
|
||||
builder.setInterpolator(ANIM_ALL_APPS_FADE, Interpolators.clampToProgress(
|
||||
ACCEL,
|
||||
progressToReachOverview,
|
||||
progressToReachOverview + ALL_APPS_CONTENT_FADE_THRESHOLD));
|
||||
|
||||
// Get workspace out of the way quickly, to prepare for potential pause.
|
||||
builder.setInterpolator(ANIM_WORKSPACE_SCALE, DEACCEL_3);
|
||||
builder.setInterpolator(ANIM_WORKSPACE_TRANSLATE, DEACCEL_3);
|
||||
builder.setInterpolator(ANIM_WORKSPACE_FADE, DEACCEL_3);
|
||||
return builder;
|
||||
} else if (fromState == ALL_APPS && toState == NORMAL) {
|
||||
StateAnimationConfig builder = new StateAnimationConfig();
|
||||
// Keep all apps/predictions opaque until the very end of the transition.
|
||||
float progressToReachOverview = OVERVIEW.getVerticalProgress(mLauncher);
|
||||
builder.setInterpolator(ANIM_ALL_APPS_FADE, Interpolators.clampToProgress(
|
||||
DEACCEL,
|
||||
progressToReachOverview - ALL_APPS_CONTENT_FADE_THRESHOLD,
|
||||
progressToReachOverview));
|
||||
builder.setInterpolator(ANIM_ALL_APPS_HEADER_FADE, Interpolators.clampToProgress(
|
||||
DEACCEL,
|
||||
1 - ALL_APPS_CONTENT_FADE_THRESHOLD,
|
||||
1));
|
||||
return builder;
|
||||
}
|
||||
return super.getConfigForStates(fromState, toState);
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for views with feedback animation requiring reset
|
||||
*/
|
||||
public interface FeedbackHandler {
|
||||
|
||||
/**
|
||||
* reset searchWidget feedback
|
||||
*/
|
||||
void resetFeedback();
|
||||
}
|
||||
}
|
||||
+33
-58
@@ -15,18 +15,15 @@
|
||||
*/
|
||||
package com.android.launcher3.uioverrides.touchcontrollers;
|
||||
|
||||
import static com.android.launcher3.LauncherState.HOTSEAT_ICONS;
|
||||
import static com.android.launcher3.LauncherState.NORMAL;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW_BUTTONS;
|
||||
import static com.android.launcher3.LauncherState.QUICK_SWITCH;
|
||||
import static com.android.launcher3.anim.AlphaUpdateListener.ALPHA_CUTOFF_THRESHOLD;
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL_0_75;
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL_5;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity;
|
||||
import static com.android.launcher3.anim.PropertySetter.NO_ANIM_PROPERTY_SETTER;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_UNKNOWN_SWIPEDOWN;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_UNKNOWN_SWIPEUP;
|
||||
@@ -39,14 +36,12 @@ import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
|
||||
import static com.android.launcher3.touch.BothAxesSwipeDetector.DIRECTION_RIGHT;
|
||||
import static com.android.launcher3.touch.BothAxesSwipeDetector.DIRECTION_UP;
|
||||
import static com.android.launcher3.uioverrides.states.QuickstepAtomicAnimationFactory.INDEX_PAUSE_TO_OVERVIEW_ANIM;
|
||||
import static com.android.launcher3.util.DefaultDisplay.getSingleFrameMs;
|
||||
import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
|
||||
import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
|
||||
import static com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState.CANCEL;
|
||||
import static com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState.HIDE;
|
||||
import static com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState.PEEK;
|
||||
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET;
|
||||
import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS;
|
||||
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
|
||||
import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
|
||||
|
||||
import android.animation.Animator;
|
||||
@@ -60,10 +55,8 @@ import com.android.launcher3.BaseQuickstepLauncher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.allapps.AllAppsTransitionController;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.graphics.OverviewScrim;
|
||||
import com.android.launcher3.logging.StatsLogManager;
|
||||
import com.android.launcher3.states.StateAnimationConfig;
|
||||
@@ -74,11 +67,11 @@ import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
|
||||
import com.android.launcher3.util.TouchController;
|
||||
import com.android.launcher3.util.VibratorWrapper;
|
||||
import com.android.quickstep.AnimatedFloat;
|
||||
import com.android.quickstep.SystemUiProxy;
|
||||
import com.android.quickstep.util.AnimatorControllerWithResistance;
|
||||
import com.android.quickstep.util.LayoutUtils;
|
||||
import com.android.quickstep.util.MotionPauseDetector;
|
||||
import com.android.quickstep.util.ShelfPeekAnim;
|
||||
import com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState;
|
||||
import com.android.quickstep.util.StaggeredWorkspaceAnim;
|
||||
import com.android.quickstep.views.LauncherRecentsView;
|
||||
|
||||
@@ -90,16 +83,16 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
|
||||
BothAxesSwipeDetector.Listener, MotionPauseDetector.OnMotionPauseListener {
|
||||
|
||||
/** The minimum progress of the scale/translationY animation until drag end. */
|
||||
private static final float Y_ANIM_MIN_PROGRESS = 0.15f;
|
||||
private static final float Y_ANIM_MIN_PROGRESS = 0.25f;
|
||||
private static final Interpolator FADE_OUT_INTERPOLATOR = DEACCEL_5;
|
||||
private static final Interpolator TRANSLATE_OUT_INTERPOLATOR = ACCEL_0_75;
|
||||
private static final Interpolator SCALE_DOWN_INTERPOLATOR = DEACCEL;
|
||||
private static final Interpolator SCALE_DOWN_INTERPOLATOR = LINEAR;
|
||||
|
||||
private final BaseQuickstepLauncher mLauncher;
|
||||
private final BothAxesSwipeDetector mSwipeDetector;
|
||||
private final ShelfPeekAnim mShelfPeekAnim;
|
||||
private final float mXRange;
|
||||
private final float mYRange;
|
||||
private final float mMaxYProgress;
|
||||
private final MotionPauseDetector mMotionPauseDetector;
|
||||
private final float mMotionPauseMinDisplacement;
|
||||
private final LauncherRecentsView mRecentsView;
|
||||
@@ -113,16 +106,16 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
|
||||
// and the other two to set overview properties based on x and y progress.
|
||||
private AnimatorPlaybackController mNonOverviewAnim;
|
||||
private AnimatorPlaybackController mXOverviewAnim;
|
||||
private AnimatorPlaybackController mYOverviewAnim;
|
||||
private AnimatedFloat mYOverviewAnim;
|
||||
|
||||
public NoButtonQuickSwitchTouchController(BaseQuickstepLauncher launcher) {
|
||||
mLauncher = launcher;
|
||||
mSwipeDetector = new BothAxesSwipeDetector(mLauncher, this);
|
||||
mShelfPeekAnim = mLauncher.getShelfPeekAnim();
|
||||
mRecentsView = mLauncher.getOverviewPanel();
|
||||
mXRange = mLauncher.getDeviceProfile().widthPx / 2f;
|
||||
mYRange = LayoutUtils.getShelfTrackingDistance(
|
||||
mLauncher, mLauncher.getDeviceProfile(), mRecentsView.getPagedOrientationHandler());
|
||||
mMaxYProgress = mLauncher.getDeviceProfile().heightPx / mYRange;
|
||||
mMotionPauseDetector = new MotionPauseDetector(mLauncher);
|
||||
mMotionPauseMinDisplacement = mLauncher.getResources().getDimension(
|
||||
R.dimen.motion_pause_detector_min_displacement_from_app);
|
||||
@@ -187,25 +180,6 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
|
||||
@Override
|
||||
public void onMotionPauseChanged(boolean isPaused) {
|
||||
VibratorWrapper.INSTANCE.get(mLauncher).vibrate(OVERVIEW_HAPTIC);
|
||||
|
||||
if (FeatureFlags.ENABLE_OVERVIEW_ACTIONS.get()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ShelfAnimState shelfState = isPaused ? PEEK : HIDE;
|
||||
if (shelfState == PEEK) {
|
||||
// Some shelf elements (e.g. qsb) were hidden, but we need them visible when peeking.
|
||||
AllAppsTransitionController allAppsController = mLauncher.getAllAppsController();
|
||||
allAppsController.setAlphas(
|
||||
NORMAL, new StateAnimationConfig(), NO_ANIM_PROPERTY_SETTER);
|
||||
|
||||
if ((OVERVIEW.getVisibleElements(mLauncher) & HOTSEAT_ICONS) != 0) {
|
||||
// Hotseat was hidden, but we need it visible when peeking.
|
||||
mLauncher.getHotseat().setAlpha(1);
|
||||
}
|
||||
}
|
||||
mShelfPeekAnim.setShelfState(shelfState, ShelfPeekAnim.INTERPOLATOR,
|
||||
ShelfPeekAnim.DURATION);
|
||||
}
|
||||
|
||||
private void setupAnimators() {
|
||||
@@ -270,8 +244,18 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
|
||||
SCALE_DOWN_INTERPOLATOR);
|
||||
yAnim.setFloat(mRecentsView, FULLSCREEN_PROGRESS,
|
||||
toState.getOverviewFullscreenProgress(), SCALE_DOWN_INTERPOLATOR);
|
||||
mYOverviewAnim = yAnim.createPlaybackController();
|
||||
mYOverviewAnim.dispatchOnStart();
|
||||
AnimatorPlaybackController yNormalController = yAnim.createPlaybackController();
|
||||
AnimatorControllerWithResistance yAnimWithResistance = AnimatorControllerWithResistance
|
||||
.createForRecents(yNormalController, mLauncher,
|
||||
mRecentsView.getPagedViewOrientedState(), mLauncher.getDeviceProfile(),
|
||||
mRecentsView, RECENTS_SCALE_PROPERTY, mRecentsView,
|
||||
TASK_SECONDARY_TRANSLATION);
|
||||
mYOverviewAnim = new AnimatedFloat(() -> {
|
||||
if (mYOverviewAnim != null) {
|
||||
yAnimWithResistance.setProgress(mYOverviewAnim.value, mMaxYProgress);
|
||||
}
|
||||
});
|
||||
yNormalController.dispatchOnStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -287,10 +271,6 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
|
||||
mIsHomeScreenVisible = FADE_OUT_INTERPOLATOR.getInterpolation(xProgress)
|
||||
<= 1 - ALPHA_CUTOFF_THRESHOLD;
|
||||
|
||||
if (wasHomeScreenVisible && !mIsHomeScreenVisible) {
|
||||
// Get the shelf all the way offscreen so it pops up when we decide to peek it.
|
||||
mShelfPeekAnim.setShelfState(HIDE, LINEAR, 0);
|
||||
}
|
||||
|
||||
// Only allow motion pause if the home screen is invisible, since some
|
||||
// home screen elements will appear in the shelf on motion pause.
|
||||
@@ -298,16 +278,11 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
|
||||
|| -displacement.y < mMotionPauseMinDisplacement);
|
||||
mMotionPauseDetector.addPosition(ev);
|
||||
|
||||
if (mIsHomeScreenVisible) {
|
||||
// Cancel the shelf anim so it doesn't clobber mNonOverviewAnim.
|
||||
mShelfPeekAnim.setShelfState(CANCEL, LINEAR, 0);
|
||||
}
|
||||
|
||||
if (mXOverviewAnim != null) {
|
||||
mXOverviewAnim.setPlayFraction(xProgress);
|
||||
}
|
||||
if (mYOverviewAnim != null) {
|
||||
mYOverviewAnim.setPlayFraction(yProgress);
|
||||
mYOverviewAnim.updateValue(yProgress);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -354,9 +329,11 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
|
||||
} else if (verticalFling) {
|
||||
targetState = velocity.y > 0 ? QUICK_SWITCH : NORMAL;
|
||||
} else {
|
||||
// If user isn't flinging, just snap to the closest state based on x progress.
|
||||
// If user isn't flinging, just snap to the closest state.
|
||||
boolean passedHorizontalThreshold = mXOverviewAnim.getInterpolatedProgress() > 0.5f;
|
||||
targetState = passedHorizontalThreshold ? QUICK_SWITCH : NORMAL;
|
||||
boolean passedVerticalThreshold = mYOverviewAnim.value > 1f;
|
||||
targetState = passedHorizontalThreshold && !passedVerticalThreshold
|
||||
? QUICK_SWITCH : NORMAL;
|
||||
}
|
||||
|
||||
// Animate the various components to the target state.
|
||||
@@ -375,9 +352,9 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
|
||||
|
||||
boolean flingUpToNormal = verticalFling && velocity.y < 0 && targetState == NORMAL;
|
||||
|
||||
float yProgress = mYOverviewAnim.getProgressFraction();
|
||||
float yProgress = mYOverviewAnim.value;
|
||||
float startYProgress = Utilities.boundToRange(yProgress
|
||||
- velocity.y * getSingleFrameMs(mLauncher) / mYRange, 0f, 1f);
|
||||
- velocity.y * getSingleFrameMs(mLauncher) / mYRange, 0f, mMaxYProgress);
|
||||
final float endYProgress;
|
||||
if (flingUpToNormal) {
|
||||
endYProgress = 1;
|
||||
@@ -387,12 +364,11 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
|
||||
} else {
|
||||
endYProgress = 0;
|
||||
}
|
||||
long yDuration = BaseSwipeDetector.calculateDuration(velocity.y,
|
||||
Math.abs(endYProgress - startYProgress));
|
||||
ValueAnimator yOverviewAnim = mYOverviewAnim.getAnimationPlayer();
|
||||
yOverviewAnim.setFloatValues(startYProgress, endYProgress);
|
||||
float yDistanceToCover = Math.abs(endYProgress - startYProgress) * mYRange;
|
||||
long yDuration = (long) (yDistanceToCover / Math.max(1f, Math.abs(velocity.y)));
|
||||
ValueAnimator yOverviewAnim = mYOverviewAnim.animateToValue(startYProgress, endYProgress);
|
||||
yOverviewAnim.setDuration(yDuration);
|
||||
mYOverviewAnim.dispatchOnStart();
|
||||
mYOverviewAnim.updateValue(startYProgress);
|
||||
|
||||
ValueAnimator nonOverviewAnim = mNonOverviewAnim.getAnimationPlayer();
|
||||
if (flingUpToNormal && !mIsHomeScreenVisible) {
|
||||
@@ -457,9 +433,8 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
|
||||
mXOverviewAnim.getAnimationPlayer().cancel();
|
||||
}
|
||||
if (mYOverviewAnim != null) {
|
||||
mYOverviewAnim.getAnimationPlayer().cancel();
|
||||
mYOverviewAnim.cancelAnimation();
|
||||
}
|
||||
mShelfPeekAnim.setShelfState(ShelfAnimState.CANCEL, LINEAR, 0);
|
||||
mMotionPauseDetector.clear();
|
||||
}
|
||||
|
||||
+6
-11
@@ -24,7 +24,6 @@ import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_ACTIONS;
|
||||
import static com.android.launcher3.config.FeatureFlags.UNSTABLE_SPRINGS;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FADE;
|
||||
@@ -142,6 +141,10 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr
|
||||
Log.d(TestProtocol.OVERIEW_NOT_ALLAPPS,
|
||||
"PortraitStatesTouchController.getTargetState 1");
|
||||
}
|
||||
if (removeShelfFromOverview(mLauncher)) {
|
||||
// Don't allow swiping down to overview.
|
||||
return NORMAL;
|
||||
}
|
||||
return TouchInteractionService.isConnected() ?
|
||||
mLauncher.getStateManager().getLastState() : NORMAL;
|
||||
} else if (fromState == OVERVIEW) {
|
||||
@@ -150,7 +153,7 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr
|
||||
"PortraitStatesTouchController.getTargetState 2");
|
||||
}
|
||||
LauncherState positiveDragTarget = ALL_APPS;
|
||||
if (ENABLE_OVERVIEW_ACTIONS.get() && removeShelfFromOverview(mLauncher)) {
|
||||
if (removeShelfFromOverview(mLauncher)) {
|
||||
// Don't allow swiping up to all apps.
|
||||
positiveDragTarget = OVERVIEW;
|
||||
}
|
||||
@@ -245,7 +248,7 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr
|
||||
|
||||
final StateAnimationConfig config = totalShift == 0 ? new StateAnimationConfig()
|
||||
: getConfigForStates(mFromState, mToState);
|
||||
config.animFlags = updateAnimComponentsOnReinit(animFlags);
|
||||
config.animFlags = animFlags;
|
||||
config.duration = maxAccuracy;
|
||||
|
||||
cancelPendingAnim();
|
||||
@@ -279,14 +282,6 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr
|
||||
return 1 / totalShift;
|
||||
}
|
||||
|
||||
/**
|
||||
* Give subclasses the chance to update the animation when we re-initialize towards a new state.
|
||||
*/
|
||||
@AnimationFlags
|
||||
protected int updateAnimComponentsOnReinit(@AnimationFlags int animComponents) {
|
||||
return animComponents;
|
||||
}
|
||||
|
||||
private void cancelPendingAnim() {
|
||||
if (mPendingAnimation != null) {
|
||||
mPendingAnimation.finish(false, Touch.SWIPE);
|
||||
|
||||
+10
-1
@@ -24,6 +24,7 @@ import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import com.android.launcher3.AbstractFloatingView;
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
@@ -205,14 +206,19 @@ public abstract class TaskViewTouchController<T extends BaseDraggingActivity>
|
||||
long maxDuration = 2 * secondaryLayerDimension;
|
||||
int verticalFactor = orientationHandler.getTaskDragDisplacementFactor(mIsRtl);
|
||||
int secondaryTaskDimension = orientationHandler.getSecondaryDimension(mTaskBeingDragged);
|
||||
// The interpolator controlling the most prominent visual movement. We use this to determine
|
||||
// whether we passed SUCCESS_TRANSITION_PROGRESS.
|
||||
final Interpolator currentInterpolator;
|
||||
if (goingUp) {
|
||||
currentInterpolator = Interpolators.LINEAR;
|
||||
mPendingAnimation = mRecentsView.createTaskDismissAnimation(mTaskBeingDragged,
|
||||
true /* animateTaskView */, true /* removeTask */, maxDuration);
|
||||
|
||||
mEndDisplacement = -secondaryTaskDimension;
|
||||
} else {
|
||||
currentInterpolator = Interpolators.ZOOM_IN;
|
||||
mPendingAnimation = mRecentsView.createTaskLaunchAnimation(
|
||||
mTaskBeingDragged, maxDuration, Interpolators.ZOOM_IN);
|
||||
mTaskBeingDragged, maxDuration, currentInterpolator);
|
||||
|
||||
// Since the thumbnail is what is filling the screen, based the end displacement on it.
|
||||
View thumbnailView = mTaskBeingDragged.getThumbnail();
|
||||
@@ -227,6 +233,9 @@ public abstract class TaskViewTouchController<T extends BaseDraggingActivity>
|
||||
}
|
||||
mCurrentAnimation = mPendingAnimation.createPlaybackController()
|
||||
.setOnCancelRunnable(this::clearState);
|
||||
// Setting this interpolator doesn't affect the visual motion, but is used to determine
|
||||
// whether we successfully reached the target state in onDragEnd().
|
||||
mCurrentAnimation.getTarget().setInterpolator(currentInterpolator);
|
||||
onUserControlledAnimationCreated(mCurrentAnimation);
|
||||
mCurrentAnimation.getTarget().addListener(this);
|
||||
mCurrentAnimation.dispatchOnStart();
|
||||
+35
-75
@@ -20,17 +20,15 @@ import static android.widget.Toast.LENGTH_SHORT;
|
||||
import static com.android.launcher3.BaseActivity.INVISIBLE_BY_STATE_HANDLER;
|
||||
import static com.android.launcher3.BaseActivity.STATE_HANDLER_INVISIBILITY_FLAGS;
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
|
||||
import static com.android.launcher3.config.FeatureFlags.UNSTABLE_SPRINGS;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.IGNORE;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOME_GESTURE;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_OVERVIEW_GESTURE;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_QUICKSWITCH_LEFT;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_QUICKSWITCH_RIGHT;
|
||||
import static com.android.launcher3.util.DefaultDisplay.getSingleFrameMs;
|
||||
import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
|
||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||
import static com.android.launcher3.util.SystemUiController.UI_STATE_OVERVIEW;
|
||||
import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
|
||||
@@ -42,13 +40,10 @@ import static com.android.quickstep.GestureState.STATE_END_TARGET_ANIMATION_FINI
|
||||
import static com.android.quickstep.GestureState.STATE_END_TARGET_SET;
|
||||
import static com.android.quickstep.GestureState.STATE_RECENTS_SCROLLING_FINISHED;
|
||||
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
|
||||
import static com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState.HIDE;
|
||||
import static com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState.PEEK;
|
||||
import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD;
|
||||
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.TimeInterpolator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.ActivityManager;
|
||||
@@ -75,7 +70,6 @@ import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.anim.AnimationSuccessListener;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.anim.Interpolators;
|
||||
import com.android.launcher3.logging.StatsLogManager;
|
||||
import com.android.launcher3.logging.StatsLogManager.StatsLogger;
|
||||
@@ -93,10 +87,9 @@ import com.android.quickstep.GestureState.GestureEndTarget;
|
||||
import com.android.quickstep.inputconsumers.OverviewInputConsumer;
|
||||
import com.android.quickstep.util.ActiveGestureLog;
|
||||
import com.android.quickstep.util.ActivityInitListener;
|
||||
import com.android.quickstep.util.AnimatorControllerWithResistance;
|
||||
import com.android.quickstep.util.InputConsumerProxy;
|
||||
import com.android.quickstep.util.RectFSpringAnim;
|
||||
import com.android.quickstep.util.ShelfPeekAnim;
|
||||
import com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState;
|
||||
import com.android.quickstep.util.SurfaceTransactionApplier;
|
||||
import com.android.quickstep.util.TransformParams;
|
||||
import com.android.quickstep.views.LiveTileOverlay;
|
||||
@@ -207,15 +200,14 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<?>, Q extends
|
||||
|
||||
// Either RectFSpringAnim (if animating home) or ObjectAnimator (from mCurrentShift) otherwise
|
||||
private RunningWindowAnim mRunningWindowAnim;
|
||||
private boolean mIsShelfPeeking;
|
||||
private boolean mIsMotionPaused;
|
||||
|
||||
private boolean mContinuingLastGesture;
|
||||
|
||||
private ThumbnailData mTaskSnapshot;
|
||||
|
||||
// Used to control launcher components throughout the swipe gesture.
|
||||
private AnimatorPlaybackController mLauncherTransitionController;
|
||||
private boolean mHasLauncherTransitionControllerStarted;
|
||||
private AnimatorControllerWithResistance mLauncherTransitionController;
|
||||
|
||||
private AnimationFactory mAnimationFactory = (t) -> { };
|
||||
|
||||
@@ -494,7 +486,9 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<?>, Q extends
|
||||
* Called when motion pause is detected
|
||||
*/
|
||||
public void onMotionPauseChanged(boolean isPaused) {
|
||||
setShelfState(isPaused ? PEEK : HIDE, ShelfPeekAnim.INTERPOLATOR, ShelfPeekAnim.DURATION);
|
||||
mIsMotionPaused = isPaused;
|
||||
maybeUpdateRecentsAttachedState();
|
||||
performHapticFeedback();
|
||||
}
|
||||
|
||||
public void maybeUpdateRecentsAttachedState() {
|
||||
@@ -525,9 +519,23 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<?>, Q extends
|
||||
// The window is going away so make sure recents is always visible in this case.
|
||||
recentsAttachedToAppWindow = true;
|
||||
} else {
|
||||
recentsAttachedToAppWindow = mIsShelfPeeking || mIsLikelyToStartNewTask;
|
||||
recentsAttachedToAppWindow = mIsMotionPaused || mIsLikelyToStartNewTask;
|
||||
}
|
||||
mAnimationFactory.setRecentsAttachedToAppWindow(recentsAttachedToAppWindow, animate);
|
||||
|
||||
// Reapply window transform throughout the attach animation, as the animation affects how
|
||||
// much the window is bound by overscroll (vs moving freely).
|
||||
if (animate) {
|
||||
ValueAnimator reapplyWindowTransformAnim = ValueAnimator.ofFloat(0, 1);
|
||||
reapplyWindowTransformAnim.addUpdateListener(anim -> {
|
||||
if (mRunningWindowAnim == null) {
|
||||
applyWindowTransform();
|
||||
}
|
||||
});
|
||||
reapplyWindowTransformAnim.setDuration(RECENTS_ATTACH_DURATION).start();
|
||||
} else {
|
||||
applyWindowTransform();
|
||||
}
|
||||
}
|
||||
|
||||
public void setIsLikelyToStartNewTask(boolean isLikelyToStartNewTask) {
|
||||
@@ -541,19 +549,6 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<?>, Q extends
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
public void setShelfState(ShelfAnimState shelfState, Interpolator interpolator, long duration) {
|
||||
mAnimationFactory.setShelfState(shelfState, interpolator, duration);
|
||||
boolean wasShelfPeeking = mIsShelfPeeking;
|
||||
mIsShelfPeeking = shelfState == PEEK;
|
||||
if (mIsShelfPeeking != wasShelfPeeking) {
|
||||
maybeUpdateRecentsAttachedState();
|
||||
}
|
||||
if (shelfState.shouldPreformHaptic) {
|
||||
performHapticFeedback();
|
||||
}
|
||||
}
|
||||
|
||||
private void buildAnimationController() {
|
||||
if (!canCreateNewOrUpdateExistingLauncherTransitionController()) {
|
||||
return;
|
||||
@@ -564,11 +559,11 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<?>, Q extends
|
||||
|
||||
/**
|
||||
* We don't want to change mLauncherTransitionController if mGestureState.getEndTarget() == HOME
|
||||
* (it has its own animation) or if we're already animating the current controller.
|
||||
* (it has its own animation).
|
||||
* @return Whether we can create the launcher controller or update its progress.
|
||||
*/
|
||||
private boolean canCreateNewOrUpdateExistingLauncherTransitionController() {
|
||||
return mGestureState.getEndTarget() != HOME && !mHasLauncherTransitionControllerStarted;
|
||||
return mGestureState.getEndTarget() != HOME;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -578,10 +573,9 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<?>, Q extends
|
||||
return result;
|
||||
}
|
||||
|
||||
private void onAnimatorPlaybackControllerCreated(AnimatorPlaybackController anim) {
|
||||
private void onAnimatorPlaybackControllerCreated(AnimatorControllerWithResistance anim) {
|
||||
mLauncherTransitionController = anim;
|
||||
mLauncherTransitionController.dispatchSetInterpolator(t -> t * mDragLengthFactor);
|
||||
mLauncherTransitionController.dispatchOnStart();
|
||||
mLauncherTransitionController.getNormalController().dispatchOnStart();
|
||||
updateLauncherTransitionProgress();
|
||||
}
|
||||
|
||||
@@ -621,10 +615,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<?>, Q extends
|
||||
|| !canCreateNewOrUpdateExistingLauncherTransitionController()) {
|
||||
return;
|
||||
}
|
||||
// Normalize the progress to 0 to 1, as the animation controller will clamp it to that
|
||||
// anyway. The controller mimics the drag length factor by applying it to its interpolators.
|
||||
float progress = mCurrentShift.value / mDragLengthFactor;
|
||||
mLauncherTransitionController.setPlayFraction(progress);
|
||||
mLauncherTransitionController.setProgress(mCurrentShift.value, mDragLengthFactor);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -845,7 +836,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<?>, Q extends
|
||||
if (isCancel) {
|
||||
endTarget = LAST_TASK;
|
||||
} else if (mDeviceState.isFullyGesturalNavMode()) {
|
||||
if (mIsShelfPeeking) {
|
||||
if (mIsMotionPaused) {
|
||||
endTarget = RECENTS;
|
||||
} else if (goingToNewTask) {
|
||||
endTarget = NEW_TASK;
|
||||
@@ -867,7 +858,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<?>, Q extends
|
||||
|
||||
if (mDeviceState.isFullyGesturalNavMode() && isSwipeUp && !willGoToNewTaskOnSwipeUp) {
|
||||
endTarget = HOME;
|
||||
} else if (mDeviceState.isFullyGesturalNavMode() && isSwipeUp && !mIsShelfPeeking) {
|
||||
} else if (mDeviceState.isFullyGesturalNavMode() && isSwipeUp && !mIsMotionPaused) {
|
||||
// If swiping at a diagonal, base end target on the faster velocity.
|
||||
endTarget = NEW_TASK;
|
||||
} else if (isSwipeUp) {
|
||||
@@ -935,7 +926,6 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<?>, Q extends
|
||||
mInputConsumerProxy.enable();
|
||||
}
|
||||
if (endTarget == HOME) {
|
||||
setShelfState(ShelfAnimState.CANCEL, LINEAR, 0);
|
||||
duration = Math.max(MIN_OVERSHOOT_DURATION, duration);
|
||||
} else if (endTarget == RECENTS) {
|
||||
LiveTileOverlay.INSTANCE.startIconAnimation();
|
||||
@@ -951,9 +941,6 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<?>, Q extends
|
||||
}
|
||||
duration = Math.max(duration, mRecentsView.getScroller().getDuration());
|
||||
}
|
||||
if (mDeviceState.isFullyGesturalNavMode()) {
|
||||
setShelfState(ShelfAnimState.OVERVIEW, interpolator, duration);
|
||||
}
|
||||
}
|
||||
|
||||
// Let RecentsView handle the scrolling to the task, which we launch in startNewTask()
|
||||
@@ -1052,6 +1039,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<?>, Q extends
|
||||
}
|
||||
|
||||
if (mGestureState.getEndTarget() == HOME) {
|
||||
mTaskViewSimulator.setDrawsBelowRecents(false);
|
||||
HomeAnimationFactory homeAnimFactory = createHomeAnimationFactory(duration);
|
||||
RectFSpringAnim windowAnim = createWindowAnimationToHome(start, homeAnimFactory);
|
||||
windowAnim.addAnimatorListener(new AnimationSuccessListener() {
|
||||
@@ -1112,31 +1100,6 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<?>, Q extends
|
||||
windowAnim.start();
|
||||
mRunningWindowAnim = RunningWindowAnim.wrap(windowAnim);
|
||||
}
|
||||
// Always play the entire launcher animation when going home, since it is separate from
|
||||
// the animation that has been controlled thus far.
|
||||
if (mGestureState.getEndTarget() == HOME) {
|
||||
start = 0;
|
||||
}
|
||||
|
||||
// We want to use the same interpolator as the window, but need to adjust it to
|
||||
// interpolate over the remaining progress (end - start).
|
||||
TimeInterpolator adjustedInterpolator = Interpolators.mapToProgress(
|
||||
interpolator, start, end);
|
||||
if (mLauncherTransitionController == null) {
|
||||
return;
|
||||
}
|
||||
if (start == end || duration <= 0) {
|
||||
mLauncherTransitionController.dispatchSetInterpolator(t -> end);
|
||||
} else {
|
||||
mLauncherTransitionController.dispatchSetInterpolator(adjustedInterpolator);
|
||||
}
|
||||
mLauncherTransitionController.getAnimationPlayer().setDuration(Math.max(0, duration));
|
||||
|
||||
if (UNSTABLE_SPRINGS.get()) {
|
||||
mLauncherTransitionController.dispatchOnStart();
|
||||
}
|
||||
mLauncherTransitionController.getAnimationPlayer().start();
|
||||
mHasLauncherTransitionControllerStarted = true;
|
||||
}
|
||||
|
||||
private void computeRecentsScrollIfInvisible() {
|
||||
@@ -1261,10 +1224,6 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<?>, Q extends
|
||||
private void cancelCurrentAnimation() {
|
||||
mCanceled = true;
|
||||
mCurrentShift.cancelAnimation();
|
||||
if (mLauncherTransitionController != null && mLauncherTransitionController
|
||||
.getAnimationPlayer().isStarted()) {
|
||||
mLauncherTransitionController.getAnimationPlayer().cancel();
|
||||
}
|
||||
}
|
||||
|
||||
private void invalidateHandler() {
|
||||
@@ -1288,9 +1247,11 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<?>, Q extends
|
||||
}
|
||||
|
||||
private void endLauncherTransitionController() {
|
||||
setShelfState(ShelfAnimState.CANCEL, LINEAR, 0);
|
||||
if (mLauncherTransitionController != null) {
|
||||
mLauncherTransitionController.getAnimationPlayer().end();
|
||||
// End the animation, but stay at the same visual progress.
|
||||
mLauncherTransitionController.getNormalController().dispatchSetInterpolator(
|
||||
t -> Utilities.boundToRange(mCurrentShift.value, 0, 1));
|
||||
mLauncherTransitionController.getNormalController().getAnimationPlayer().end();
|
||||
mLauncherTransitionController = null;
|
||||
}
|
||||
}
|
||||
@@ -1572,8 +1533,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<?>, Q extends
|
||||
*/
|
||||
protected void applyWindowTransform() {
|
||||
if (mWindowTransitionController != null) {
|
||||
float progress = mCurrentShift.value / mDragLengthFactor;
|
||||
mWindowTransitionController.setPlayFraction(progress);
|
||||
mWindowTransitionController.setProgress(mCurrentShift.value, mDragLengthFactor);
|
||||
}
|
||||
if (mRecentsAnimationTargets != null) {
|
||||
if (mRecentsViewScrollLinked) {
|
||||
+2
-2
@@ -79,8 +79,8 @@ final class AppToOverviewAnimationProvider<T extends StatefulActivity<?>> extend
|
||||
BaseActivityInterface.AnimationFactory factory = mActivityInterface.prepareRecentsUI(
|
||||
mDeviceState,
|
||||
wasVisible, (controller) -> {
|
||||
controller.dispatchOnStart();
|
||||
controller.getAnimationPlayer().end();
|
||||
controller.getNormalController().dispatchOnStart();
|
||||
controller.getNormalController().getAnimationPlayer().end();
|
||||
});
|
||||
factory.createActivityInterface(RECENTS_LAUNCH_DURATION);
|
||||
factory.setRecentsAttachedToAppWindow(true, false);
|
||||
@@ -18,7 +18,6 @@ package com.android.quickstep;
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL_2;
|
||||
import static com.android.launcher3.anim.Interpolators.INSTANT;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_ACTIONS;
|
||||
import static com.android.quickstep.AbsSwipeUpHandler.RECENTS_ATTACH_DURATION;
|
||||
import static com.android.quickstep.SysUINavigationMode.getMode;
|
||||
import static com.android.quickstep.SysUINavigationMode.hideShelfInTwoButtonLandscape;
|
||||
@@ -28,6 +27,7 @@ import static com.android.quickstep.util.RecentsAtomicAnimationFactory.INDEX_REC
|
||||
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET;
|
||||
import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS;
|
||||
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
|
||||
import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.annotation.TargetApi;
|
||||
@@ -36,7 +36,6 @@ import android.content.res.Resources;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Build;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.UiThread;
|
||||
@@ -52,7 +51,7 @@ import com.android.launcher3.touch.PagedOrientationHandler;
|
||||
import com.android.launcher3.util.WindowBounds;
|
||||
import com.android.quickstep.SysUINavigationMode.Mode;
|
||||
import com.android.quickstep.util.ActivityInitListener;
|
||||
import com.android.quickstep.util.ShelfPeekAnim;
|
||||
import com.android.quickstep.util.AnimatorControllerWithResistance;
|
||||
import com.android.quickstep.util.SplitScreenBounds;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||
@@ -106,7 +105,7 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
|
||||
public abstract void onAssistantVisibilityChanged(float visibility);
|
||||
|
||||
public abstract AnimationFactory prepareRecentsUI(RecentsAnimationDeviceState deviceState,
|
||||
boolean activityVisible, Consumer<AnimatorPlaybackController> callback);
|
||||
boolean activityVisible, Consumer<AnimatorControllerWithResistance> callback);
|
||||
|
||||
public abstract ActivityInitListener createActivityInitListener(
|
||||
Predicate<Boolean> onInitListener);
|
||||
@@ -297,9 +296,6 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
|
||||
|
||||
default void onTransitionCancelled() { }
|
||||
|
||||
default void setShelfState(ShelfPeekAnim.ShelfAnimState animState,
|
||||
Interpolator interpolator, long duration) { }
|
||||
|
||||
/**
|
||||
* @param attached Whether to show RecentsView alongside the app window. If false, recents
|
||||
* will be hidden by some property we can animate, e.g. alpha.
|
||||
@@ -312,11 +308,11 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
|
||||
|
||||
protected final ACTIVITY_TYPE mActivity;
|
||||
private final STATE_TYPE mStartState;
|
||||
private final Consumer<AnimatorPlaybackController> mCallback;
|
||||
private final Consumer<AnimatorControllerWithResistance> mCallback;
|
||||
|
||||
private boolean mIsAttachedToWindow;
|
||||
|
||||
DefaultAnimationFactory(Consumer<AnimatorPlaybackController> callback) {
|
||||
DefaultAnimationFactory(Consumer<AnimatorControllerWithResistance> callback) {
|
||||
mCallback = callback;
|
||||
|
||||
mActivity = getCreatedActivity();
|
||||
@@ -344,7 +340,14 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
|
||||
controller.setEndAction(() -> mActivity.getStateManager().goToState(
|
||||
controller.getInterpolatedProgress() > 0.5 ? mOverviewState : mBackgroundState,
|
||||
false));
|
||||
mCallback.accept(controller);
|
||||
|
||||
RecentsView recentsView = mActivity.getOverviewPanel();
|
||||
AnimatorControllerWithResistance controllerWithResistance =
|
||||
AnimatorControllerWithResistance.createForRecents(controller, mActivity,
|
||||
recentsView.getPagedViewOrientedState(), mActivity.getDeviceProfile(),
|
||||
recentsView, RECENTS_SCALE_PROPERTY, recentsView,
|
||||
TASK_SECONDARY_TRANSLATION);
|
||||
mCallback.accept(controllerWithResistance);
|
||||
|
||||
// Creating the activity controller animation sometimes reapplies the launcher state
|
||||
// (because we set the animation as the current state animation), so we reapply the
|
||||
@@ -400,6 +403,6 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
|
||||
}
|
||||
|
||||
protected static boolean showOverviewActions(Context context) {
|
||||
return ENABLE_OVERVIEW_ACTIONS.get() && removeShelfFromOverview(context);
|
||||
return removeShelfFromOverview(context);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -27,11 +27,11 @@ import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.touch.PagedOrientationHandler;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
||||
import com.android.quickstep.fallback.RecentsState;
|
||||
import com.android.quickstep.util.ActivityInitListener;
|
||||
import com.android.quickstep.util.AnimatorControllerWithResistance;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||
|
||||
@@ -84,7 +84,7 @@ public final class FallbackActivityInterface extends
|
||||
/** 6 */
|
||||
@Override
|
||||
public AnimationFactory prepareRecentsUI(RecentsAnimationDeviceState deviceState,
|
||||
boolean activityVisible, Consumer<AnimatorPlaybackController> callback) {
|
||||
boolean activityVisible, Consumer<AnimatorControllerWithResistance> callback) {
|
||||
DefaultAnimationFactory factory = new DefaultAnimationFactory(callback);
|
||||
factory.initUI();
|
||||
return factory;
|
||||
+2
-10
@@ -27,7 +27,6 @@ import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Rect;
|
||||
import android.util.Log;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.UiThread;
|
||||
@@ -39,7 +38,6 @@ import com.android.launcher3.LauncherInitListener;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.allapps.DiscoveryBounce;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.statehandlers.DepthController;
|
||||
import com.android.launcher3.statehandlers.DepthController.ClampedDepthProperty;
|
||||
@@ -49,8 +47,8 @@ import com.android.launcher3.touch.PagedOrientationHandler;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
||||
import com.android.quickstep.SysUINavigationMode.Mode;
|
||||
import com.android.quickstep.util.ActivityInitListener;
|
||||
import com.android.quickstep.util.AnimatorControllerWithResistance;
|
||||
import com.android.quickstep.util.LayoutUtils;
|
||||
import com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.systemui.plugins.shared.LauncherOverlayManager;
|
||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||
@@ -118,15 +116,9 @@ public final class LauncherActivityInterface extends
|
||||
|
||||
@Override
|
||||
public AnimationFactory prepareRecentsUI(RecentsAnimationDeviceState deviceState,
|
||||
boolean activityVisible, Consumer<AnimatorPlaybackController> callback) {
|
||||
boolean activityVisible, Consumer<AnimatorControllerWithResistance> callback) {
|
||||
notifyRecentsOfOrientation(deviceState.getRotationTouchHelper());
|
||||
DefaultAnimationFactory factory = new DefaultAnimationFactory(callback) {
|
||||
@Override
|
||||
public void setShelfState(ShelfAnimState shelfState, Interpolator interpolator,
|
||||
long duration) {
|
||||
mActivity.getShelfPeekAnim().setShelfState(shelfState, interpolator, duration);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBackgroundToOverviewAnim(BaseQuickstepLauncher activity,
|
||||
PendingAnimation pa) {
|
||||
@@ -37,7 +37,7 @@ import android.view.Surface;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.ResourceUtils;
|
||||
import com.android.launcher3.testing.TestProtocol;
|
||||
import com.android.launcher3.util.DefaultDisplay;
|
||||
import com.android.launcher3.util.DisplayController.Info;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
@@ -85,7 +85,7 @@ class OrientationTouchTransformer {
|
||||
* QUICKSTEP_ROTATION_UNINITIALIZED, then user has not tapped on an active nav region.
|
||||
* Otherwise it will be the rotation of the display when the user first interacted with the
|
||||
* active nav bar region.
|
||||
* The "session" ends when {@link #enableMultipleRegions(boolean, DefaultDisplay.Info)} is
|
||||
* The "session" ends when {@link #enableMultipleRegions(boolean, Info)} is
|
||||
* called - usually from a timeout or if user starts interacting w/ the foreground app.
|
||||
*
|
||||
* This is different than {@link #mLastRectTouched} as it can get reset by the system whereas
|
||||
@@ -108,7 +108,7 @@ class OrientationTouchTransformer {
|
||||
mNavBarGesturalHeight = getNavbarSize(ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE);
|
||||
}
|
||||
|
||||
private void refreshTouchRegion(DefaultDisplay.Info info, Resources newRes) {
|
||||
private void refreshTouchRegion(Info info, Resources newRes) {
|
||||
// Swipe touch regions are independent of nav mode, so we have to clear them explicitly
|
||||
// here to avoid, for ex, a nav region for 2-button rotation 0 being used for 3-button mode
|
||||
// It tries to cache and reuse swipe regions whenever possible based only on rotation
|
||||
@@ -117,7 +117,7 @@ class OrientationTouchTransformer {
|
||||
resetSwipeRegions(info);
|
||||
}
|
||||
|
||||
void setNavigationMode(SysUINavigationMode.Mode newMode, DefaultDisplay.Info info,
|
||||
void setNavigationMode(SysUINavigationMode.Mode newMode, Info info,
|
||||
Resources newRes) {
|
||||
if (mMode == newMode) {
|
||||
return;
|
||||
@@ -126,7 +126,7 @@ class OrientationTouchTransformer {
|
||||
refreshTouchRegion(info, newRes);
|
||||
}
|
||||
|
||||
void setGesturalHeight(int newGesturalHeight, DefaultDisplay.Info info, Resources newRes) {
|
||||
void setGesturalHeight(int newGesturalHeight, Info info, Resources newRes) {
|
||||
if (mNavBarGesturalHeight == newGesturalHeight) {
|
||||
return;
|
||||
}
|
||||
@@ -140,9 +140,9 @@ class OrientationTouchTransformer {
|
||||
* alongside other regions.
|
||||
* Ok to call multiple times
|
||||
*
|
||||
* @see #enableMultipleRegions(boolean, DefaultDisplay.Info)
|
||||
* @see #enableMultipleRegions(boolean, Info)
|
||||
*/
|
||||
void createOrAddTouchRegion(DefaultDisplay.Info info) {
|
||||
void createOrAddTouchRegion(Info info) {
|
||||
mCurrentDisplayRotation = info.rotation;
|
||||
if (mQuickStepStartingRotation > QUICKSTEP_ROTATION_UNINITIALIZED
|
||||
&& mCurrentDisplayRotation == mQuickStepStartingRotation) {
|
||||
@@ -170,7 +170,7 @@ class OrientationTouchTransformer {
|
||||
* @param enableMultipleRegions Set to true to start tracking multiple nav bar regions
|
||||
* @param info The current displayInfo which will be the start of the quickswitch gesture
|
||||
*/
|
||||
void enableMultipleRegions(boolean enableMultipleRegions, DefaultDisplay.Info info) {
|
||||
void enableMultipleRegions(boolean enableMultipleRegions, Info info) {
|
||||
mEnableMultipleRegions = enableMultipleRegions &&
|
||||
mMode != SysUINavigationMode.Mode.TWO_BUTTONS;
|
||||
if (mEnableMultipleRegions) {
|
||||
@@ -191,7 +191,7 @@ class OrientationTouchTransformer {
|
||||
*
|
||||
* @param displayInfo The display whos rotation will be used as the current active rotation
|
||||
*/
|
||||
void setSingleActiveRegion(DefaultDisplay.Info displayInfo) {
|
||||
void setSingleActiveRegion(Info displayInfo) {
|
||||
mActiveTouchRotation = displayInfo.rotation;
|
||||
resetSwipeRegions(displayInfo);
|
||||
}
|
||||
@@ -202,7 +202,7 @@ class OrientationTouchTransformer {
|
||||
* To be called whenever we want to stop tracking more than one swipe region.
|
||||
* Ok to call multiple times.
|
||||
*/
|
||||
private void resetSwipeRegions(DefaultDisplay.Info region) {
|
||||
private void resetSwipeRegions(Info region) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "clearing all regions except rotation: " + mCurrentDisplayRotation);
|
||||
}
|
||||
@@ -226,7 +226,7 @@ class OrientationTouchTransformer {
|
||||
}
|
||||
}
|
||||
|
||||
private OrientationRectF createRegionForDisplay(DefaultDisplay.Info display) {
|
||||
private OrientationRectF createRegionForDisplay(Info display) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "creating rotation region for: " + mCurrentDisplayRotation);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.quickstep;
|
||||
|
||||
import static com.android.launcher3.util.MainThreadInitializedObject.forOverride;
|
||||
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.util.MainThreadInitializedObject;
|
||||
import com.android.launcher3.util.ResourceBasedOverride;
|
||||
import com.android.systemui.plugins.OverscrollPlugin;
|
||||
|
||||
/**
|
||||
* Resource overrideable factory for forcing a local overscroll plugin.
|
||||
* Override {@link R.string#overscroll_plugin_factory_class} to set a different class.
|
||||
*/
|
||||
public class OverscrollPluginFactory implements ResourceBasedOverride {
|
||||
public static final MainThreadInitializedObject<OverscrollPluginFactory> INSTANCE = forOverride(
|
||||
OverscrollPluginFactory.class,
|
||||
R.string.overscroll_plugin_factory_class);
|
||||
|
||||
/**
|
||||
* Get the plugin that is defined locally in launcher, as opposed to a dynamic side loaded one.
|
||||
*/
|
||||
public OverscrollPlugin getLocalOverscrollPlugin() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
-6
@@ -53,12 +53,6 @@ public class QuickstepTestInformationHandler extends TestInformationHandler {
|
||||
Bundle::putInt, PortraitStatesTouchController::getHotseatTop);
|
||||
}
|
||||
|
||||
case TestProtocol.REQUEST_OVERVIEW_ACTIONS_ENABLED: {
|
||||
response.putBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD,
|
||||
FeatureFlags.ENABLE_OVERVIEW_ACTIONS.get());
|
||||
return response;
|
||||
}
|
||||
|
||||
case TestProtocol.REQUEST_OVERVIEW_SHARE_ENABLED: {
|
||||
response.putBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD,
|
||||
FeatureFlags.ENABLE_OVERVIEW_SHARE.get());
|
||||
@@ -17,8 +17,8 @@ package com.android.quickstep;
|
||||
|
||||
import static android.content.Intent.ACTION_USER_UNLOCKED;
|
||||
|
||||
import static com.android.launcher3.util.DefaultDisplay.CHANGE_ALL;
|
||||
import static com.android.launcher3.util.DefaultDisplay.CHANGE_FRAME_DELAY;
|
||||
import static com.android.launcher3.util.DisplayController.DisplayHolder.CHANGE_ALL;
|
||||
import static com.android.launcher3.util.DisplayController.DisplayHolder.CHANGE_FRAME_DELAY;
|
||||
import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
|
||||
import static com.android.quickstep.SysUINavigationMode.Mode.THREE_BUTTONS;
|
||||
import static com.android.quickstep.SysUINavigationMode.Mode.TWO_BUTTONS;
|
||||
@@ -56,7 +56,10 @@ import androidx.annotation.BinderThread;
|
||||
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.util.DefaultDisplay;
|
||||
import com.android.launcher3.util.DisplayController;
|
||||
import com.android.launcher3.util.DisplayController.DisplayHolder;
|
||||
import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener;
|
||||
import com.android.launcher3.util.DisplayController.Info;
|
||||
import com.android.launcher3.util.SecureSettingsObserver;
|
||||
import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener;
|
||||
import com.android.quickstep.SysUINavigationMode.OneHandedModeChangeListener;
|
||||
@@ -76,14 +79,14 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
public class RecentsAnimationDeviceState implements
|
||||
NavigationModeChangeListener,
|
||||
DefaultDisplay.DisplayInfoChangeListener,
|
||||
DisplayInfoChangeListener,
|
||||
OneHandedModeChangeListener {
|
||||
|
||||
static final String SUPPORT_ONE_HANDED_MODE = "ro.support_one_handed_mode";
|
||||
|
||||
private final Context mContext;
|
||||
private final SysUINavigationMode mSysUiNavMode;
|
||||
private final DefaultDisplay mDefaultDisplay;
|
||||
private final DisplayHolder mDisplayHolder;
|
||||
private final int mDisplayId;
|
||||
private final RotationTouchHelper mRotationTouchHelper;
|
||||
|
||||
@@ -98,6 +101,7 @@ public class RecentsAnimationDeviceState implements
|
||||
private float mAssistantVisibility;
|
||||
private boolean mIsOneHandedModeEnabled;
|
||||
private boolean mIsSwipeToNotificationEnabled;
|
||||
private final boolean mIsOneHandedModeSupported;
|
||||
|
||||
private boolean mIsUserUnlocked;
|
||||
private final ArrayList<Runnable> mUserUnlockedActions = new ArrayList<>();
|
||||
@@ -119,12 +123,17 @@ public class RecentsAnimationDeviceState implements
|
||||
private boolean mIsUserSetupComplete;
|
||||
|
||||
public RecentsAnimationDeviceState(Context context) {
|
||||
this(context, DisplayController.getDefaultDisplay(context));
|
||||
}
|
||||
|
||||
public RecentsAnimationDeviceState(Context context, DisplayHolder displayHolder) {
|
||||
mContext = context;
|
||||
mDisplayHolder = displayHolder;
|
||||
mSysUiNavMode = SysUINavigationMode.INSTANCE.get(context);
|
||||
mDefaultDisplay = DefaultDisplay.INSTANCE.get(context);
|
||||
mDisplayId = mDefaultDisplay.getInfo().id;
|
||||
runOnDestroy(() -> mDefaultDisplay.removeChangeListener(this));
|
||||
mRotationTouchHelper = new RotationTouchHelper(context);
|
||||
mDisplayId = mDisplayHolder.getInfo().id;
|
||||
mIsOneHandedModeSupported = SystemProperties.getBoolean(SUPPORT_ONE_HANDED_MODE, false);
|
||||
runOnDestroy(() -> mDisplayHolder.removeChangeListener(this));
|
||||
mRotationTouchHelper = new RotationTouchHelper(context, mDisplayHolder);
|
||||
runOnDestroy(mRotationTouchHelper::destroy);
|
||||
|
||||
// Register for user unlocked if necessary
|
||||
@@ -167,7 +176,7 @@ public class RecentsAnimationDeviceState implements
|
||||
}
|
||||
}
|
||||
|
||||
if (SystemProperties.getBoolean(SUPPORT_ONE_HANDED_MODE, false)) {
|
||||
if (mIsOneHandedModeSupported) {
|
||||
SecureSettingsObserver oneHandedEnabledObserver =
|
||||
SecureSettingsObserver.newOneHandedSettingsObserver(
|
||||
mContext, enabled -> mIsOneHandedModeEnabled = enabled);
|
||||
@@ -230,9 +239,9 @@ public class RecentsAnimationDeviceState implements
|
||||
|
||||
@Override
|
||||
public void onNavigationModeChanged(SysUINavigationMode.Mode newMode) {
|
||||
mDefaultDisplay.removeChangeListener(this);
|
||||
mDefaultDisplay.addChangeListener(this);
|
||||
onDisplayInfoChanged(mDefaultDisplay.getInfo(), CHANGE_ALL);
|
||||
mDisplayHolder.removeChangeListener(this);
|
||||
mDisplayHolder.addChangeListener(this);
|
||||
onDisplayInfoChanged(mDisplayHolder.getInfo(), CHANGE_ALL);
|
||||
|
||||
if (newMode == NO_BUTTON) {
|
||||
mExclusionListener.register();
|
||||
@@ -240,12 +249,12 @@ public class RecentsAnimationDeviceState implements
|
||||
mExclusionListener.unregister();
|
||||
}
|
||||
|
||||
mNavBarPosition = new NavBarPosition(newMode, mDefaultDisplay.getInfo());
|
||||
mNavBarPosition = new NavBarPosition(newMode, mDisplayHolder.getInfo());
|
||||
mMode = newMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisplayInfoChanged(DefaultDisplay.Info info, int flags) {
|
||||
public void onDisplayInfoChanged(Info info, int flags) {
|
||||
if (info.id != getDisplayId() || flags == CHANGE_FRAME_DELAY) {
|
||||
// ignore displays that aren't running launcher and frame refresh rate changes
|
||||
return;
|
||||
@@ -522,19 +531,18 @@ public class RecentsAnimationDeviceState implements
|
||||
* @return whether the given motion event can trigger the one handed mode.
|
||||
*/
|
||||
public boolean canTriggerOneHandedAction(MotionEvent ev) {
|
||||
if (!SystemProperties.getBoolean(SUPPORT_ONE_HANDED_MODE, false)) {
|
||||
if (!mIsOneHandedModeSupported) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mIsOneHandedModeEnabled && !mIsSwipeToNotificationEnabled) {
|
||||
return false;
|
||||
if (mIsOneHandedModeEnabled || mIsSwipeToNotificationEnabled) {
|
||||
final Info displayInfo = mDisplayHolder.getInfo();
|
||||
return (mRotationTouchHelper.touchInOneHandedModeRegion(ev)
|
||||
&& displayInfo.rotation != Surface.ROTATION_90
|
||||
&& displayInfo.rotation != Surface.ROTATION_270
|
||||
&& displayInfo.metrics.densityDpi < DisplayMetrics.DENSITY_600);
|
||||
}
|
||||
|
||||
final DefaultDisplay.Info displayInfo = mDefaultDisplay.getInfo();
|
||||
return (mRotationTouchHelper.touchInOneHandedModeRegion(ev)
|
||||
&& displayInfo.rotation != Surface.ROTATION_90
|
||||
&& displayInfo.rotation != Surface.ROTATION_270
|
||||
&& displayInfo.metrics.densityDpi < DisplayMetrics.DENSITY_600);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isOneHandedModeEnabled() {
|
||||
|
||||
@@ -160,9 +160,9 @@ public class RecentsModel extends TaskStackChangeListener {
|
||||
|
||||
@Override
|
||||
public void onTaskRemoved(int taskId) {
|
||||
Task.TaskKey dummyKey = new Task.TaskKey(taskId, 0, null, null, 0, 0);
|
||||
mThumbnailCache.remove(dummyKey);
|
||||
mIconCache.onTaskRemoved(dummyKey);
|
||||
Task.TaskKey stubKey = new Task.TaskKey(taskId, 0, null, null, 0, 0);
|
||||
mThumbnailCache.remove(stubKey);
|
||||
mIconCache.onTaskRemoved(stubKey);
|
||||
}
|
||||
|
||||
public void onTrimMemory(int level) {
|
||||
|
||||
@@ -17,8 +17,8 @@ package com.android.quickstep;
|
||||
|
||||
import static android.view.Surface.ROTATION_0;
|
||||
|
||||
import static com.android.launcher3.util.DefaultDisplay.CHANGE_ALL;
|
||||
import static com.android.launcher3.util.DefaultDisplay.CHANGE_FRAME_DELAY;
|
||||
import static com.android.launcher3.util.DisplayController.DisplayHolder.CHANGE_ALL;
|
||||
import static com.android.launcher3.util.DisplayController.DisplayHolder.CHANGE_FRAME_DELAY;
|
||||
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
|
||||
import static com.android.quickstep.SysUINavigationMode.Mode.THREE_BUTTONS;
|
||||
|
||||
@@ -28,8 +28,9 @@ import android.view.MotionEvent;
|
||||
import android.view.OrientationEventListener;
|
||||
|
||||
import com.android.launcher3.testing.TestProtocol;
|
||||
import com.android.launcher3.util.DefaultDisplay;
|
||||
import com.android.launcher3.util.MainThreadInitializedObject;
|
||||
import com.android.launcher3.util.DisplayController.DisplayHolder;
|
||||
import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener;
|
||||
import com.android.launcher3.util.DisplayController.Info;
|
||||
import com.android.quickstep.util.RecentsOrientedState;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
import com.android.systemui.shared.system.QuickStepContract;
|
||||
@@ -40,10 +41,10 @@ import java.util.ArrayList;
|
||||
|
||||
public class RotationTouchHelper implements
|
||||
SysUINavigationMode.NavigationModeChangeListener,
|
||||
DefaultDisplay.DisplayInfoChangeListener {
|
||||
DisplayInfoChangeListener {
|
||||
|
||||
private final OrientationTouchTransformer mOrientationTouchTransformer;
|
||||
private final DefaultDisplay mDefaultDisplay;
|
||||
private final DisplayHolder mDisplayHolder;
|
||||
private final SysUINavigationMode mSysUiNavMode;
|
||||
private final int mDisplayId;
|
||||
private int mDisplayRotation;
|
||||
@@ -120,12 +121,12 @@ public class RotationTouchHelper implements
|
||||
|
||||
private final Context mContext;
|
||||
|
||||
public RotationTouchHelper(Context context) {
|
||||
public RotationTouchHelper(Context context, DisplayHolder displayHolder) {
|
||||
mContext = context;
|
||||
mDisplayHolder = displayHolder;
|
||||
Resources resources = mContext.getResources();
|
||||
mSysUiNavMode = SysUINavigationMode.INSTANCE.get(context);
|
||||
mDefaultDisplay = DefaultDisplay.INSTANCE.get(context);
|
||||
mDisplayId = mDefaultDisplay.getInfo().id;
|
||||
mDisplayId = mDisplayHolder.getInfo().id;
|
||||
|
||||
mOrientationTouchTransformer = new OrientationTouchTransformer(resources, mMode,
|
||||
() -> QuickStepContract.getWindowCornerRadius(resources));
|
||||
@@ -200,7 +201,7 @@ public class RotationTouchHelper implements
|
||||
return;
|
||||
}
|
||||
|
||||
mOrientationTouchTransformer.createOrAddTouchRegion(mDefaultDisplay.getInfo());
|
||||
mOrientationTouchTransformer.createOrAddTouchRegion(mDisplayHolder.getInfo());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -222,11 +223,11 @@ public class RotationTouchHelper implements
|
||||
|
||||
@Override
|
||||
public void onNavigationModeChanged(SysUINavigationMode.Mode newMode) {
|
||||
mDefaultDisplay.removeChangeListener(this);
|
||||
mDefaultDisplay.addChangeListener(this);
|
||||
onDisplayInfoChanged(mDefaultDisplay.getInfo(), CHANGE_ALL);
|
||||
mDisplayHolder.removeChangeListener(this);
|
||||
mDisplayHolder.addChangeListener(this);
|
||||
onDisplayInfoChanged(mDisplayHolder.getInfo(), CHANGE_ALL);
|
||||
|
||||
mOrientationTouchTransformer.setNavigationMode(newMode, mDefaultDisplay.getInfo(),
|
||||
mOrientationTouchTransformer.setNavigationMode(newMode, mDisplayHolder.getInfo(),
|
||||
mContext.getResources());
|
||||
if (!mMode.hasGestures && newMode.hasGestures) {
|
||||
setupOrientationSwipeHandler();
|
||||
@@ -242,7 +243,7 @@ public class RotationTouchHelper implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisplayInfoChanged(DefaultDisplay.Info info, int flags) {
|
||||
public void onDisplayInfoChanged(Info info, int flags) {
|
||||
if (info.id != mDisplayId|| flags == CHANGE_FRAME_DELAY) {
|
||||
// ignore displays that aren't running launcher and frame refresh rate changes
|
||||
return;
|
||||
@@ -275,7 +276,7 @@ public class RotationTouchHelper implements
|
||||
* Sets the gestural height.
|
||||
*/
|
||||
void setGesturalHeight(int newGesturalHeight) {
|
||||
mOrientationTouchTransformer.setGesturalHeight(newGesturalHeight, mDefaultDisplay.getInfo(),
|
||||
mOrientationTouchTransformer.setGesturalHeight(newGesturalHeight, mDisplayHolder.getInfo(),
|
||||
mContext.getResources());
|
||||
}
|
||||
|
||||
@@ -292,7 +293,7 @@ public class RotationTouchHelper implements
|
||||
}
|
||||
|
||||
private void enableMultipleRegions(boolean enable) {
|
||||
mOrientationTouchTransformer.enableMultipleRegions(enable, mDefaultDisplay.getInfo());
|
||||
mOrientationTouchTransformer.enableMultipleRegions(enable, mDisplayHolder.getInfo());
|
||||
notifySysuiOfCurrentRotation(mOrientationTouchTransformer.getQuickStepStartingRotation());
|
||||
if (enable && !mInOverview && !TestProtocol.sDisableSensorRotation) {
|
||||
// Clear any previous state from sensor manager
|
||||
@@ -355,7 +356,7 @@ public class RotationTouchHelper implements
|
||||
* notifies system UI of the primary rotation the user is interacting with
|
||||
*/
|
||||
private void toggleSecondaryNavBarsForRotation() {
|
||||
mOrientationTouchTransformer.setSingleActiveRegion(mDefaultDisplay.getInfo());
|
||||
mOrientationTouchTransformer.setSingleActiveRegion(mDisplayHolder.getInfo());
|
||||
notifySysuiOfCurrentRotation(mOrientationTouchTransformer.getCurrentActiveRotation());
|
||||
}
|
||||
|
||||
|
||||
+12
-25
@@ -16,7 +16,7 @@
|
||||
package com.android.quickstep;
|
||||
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL_1_5;
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.content.Context;
|
||||
@@ -24,7 +24,6 @@ import android.graphics.Matrix;
|
||||
import android.graphics.Matrix.ScaleToFit;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.UiThread;
|
||||
@@ -35,6 +34,7 @@ import com.android.launcher3.anim.AnimationSuccessListener;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.touch.PagedOrientationHandler;
|
||||
import com.android.quickstep.util.AnimatorControllerWithResistance;
|
||||
import com.android.quickstep.util.RectFSpringAnim;
|
||||
import com.android.quickstep.util.TaskViewSimulator;
|
||||
import com.android.quickstep.util.TransformParams;
|
||||
@@ -45,7 +45,6 @@ import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.
|
||||
public abstract class SwipeUpAnimationLogic {
|
||||
|
||||
protected static final Rect TEMP_RECT = new Rect();
|
||||
private static final Interpolator PULLBACK_INTERPOLATOR = DEACCEL;
|
||||
|
||||
protected DeviceProfile mDp;
|
||||
|
||||
@@ -66,12 +65,8 @@ public abstract class SwipeUpAnimationLogic {
|
||||
protected int mTransitionDragLength;
|
||||
// How much further we can drag past recents, as a factor of mTransitionDragLength.
|
||||
protected float mDragLengthFactor = 1;
|
||||
// Start resisting when swiping past this factor of mTransitionDragLength.
|
||||
private float mDragLengthFactorStartPullback = 1f;
|
||||
// This is how far down we can scale down, where 0f is full screen and 1f is recents.
|
||||
private float mDragLengthFactorMaxPullback = 1f;
|
||||
|
||||
protected AnimatorPlaybackController mWindowTransitionController;
|
||||
protected AnimatorControllerWithResistance mWindowTransitionController;
|
||||
|
||||
public SwipeUpAnimationLogic(Context context, RecentsAnimationDeviceState deviceState,
|
||||
GestureState gestureState, TransformParams transformParams) {
|
||||
@@ -84,6 +79,7 @@ public abstract class SwipeUpAnimationLogic {
|
||||
mTaskViewSimulator.setLayoutRotation(
|
||||
mDeviceState.getRotationTouchHelper().getCurrentActiveRotation(),
|
||||
mDeviceState.getRotationTouchHelper().getDisplayRotation());
|
||||
mTaskViewSimulator.setDrawsBelowRecents(true);
|
||||
}
|
||||
|
||||
protected void initTransitionEndpoints(DeviceProfile dp) {
|
||||
@@ -97,19 +93,17 @@ public abstract class SwipeUpAnimationLogic {
|
||||
if (mDeviceState.isFullyGesturalNavMode()) {
|
||||
// We can drag all the way to the top of the screen.
|
||||
mDragLengthFactor = (float) dp.heightPx / mTransitionDragLength;
|
||||
|
||||
float startScale = mTaskViewSimulator.getFullScreenScale();
|
||||
// Start pulling back when RecentsView scale is 0.75f, and let it go down to 0.5f.
|
||||
mDragLengthFactorStartPullback = (0.75f - startScale) / (1 - startScale);
|
||||
mDragLengthFactorMaxPullback = (0.5f - startScale) / (1 - startScale);
|
||||
} else {
|
||||
mDragLengthFactor = 1;
|
||||
mDragLengthFactorStartPullback = mDragLengthFactorMaxPullback = 1;
|
||||
mDragLengthFactor = 1 + AnimatorControllerWithResistance.TWO_BUTTON_EXTRA_DRAG_FACTOR;
|
||||
}
|
||||
|
||||
PendingAnimation pa = new PendingAnimation(mTransitionDragLength * 2);
|
||||
mTaskViewSimulator.addAppToOverviewAnim(pa, t -> t * mDragLengthFactor);
|
||||
mWindowTransitionController = pa.createPlaybackController();
|
||||
mTaskViewSimulator.addAppToOverviewAnim(pa, LINEAR);
|
||||
AnimatorPlaybackController normalController = pa.createPlaybackController();
|
||||
mWindowTransitionController = AnimatorControllerWithResistance.createForRecents(
|
||||
normalController, mContext, mTaskViewSimulator.getOrientationState(),
|
||||
mDp, mTaskViewSimulator.recentsViewScale, AnimatedFloat.VALUE,
|
||||
mTaskViewSimulator.recentsViewSecondaryTranslation, AnimatedFloat.VALUE);
|
||||
}
|
||||
|
||||
@UiThread
|
||||
@@ -122,13 +116,6 @@ public abstract class SwipeUpAnimationLogic {
|
||||
} else {
|
||||
float translation = Math.max(displacement, 0);
|
||||
shift = mTransitionDragLength == 0 ? 0 : translation / mTransitionDragLength;
|
||||
if (shift > mDragLengthFactorStartPullback) {
|
||||
float pullbackProgress = Utilities.getProgress(shift,
|
||||
mDragLengthFactorStartPullback, mDragLengthFactor);
|
||||
pullbackProgress = PULLBACK_INTERPOLATOR.getInterpolation(pullbackProgress);
|
||||
shift = mDragLengthFactorStartPullback + pullbackProgress
|
||||
* (mDragLengthFactorMaxPullback - mDragLengthFactorStartPullback);
|
||||
}
|
||||
}
|
||||
|
||||
mCurrentShift.updateValue(shift);
|
||||
@@ -183,7 +170,7 @@ public abstract class SwipeUpAnimationLogic {
|
||||
HomeAnimationFactory homeAnimationFactory) {
|
||||
final RectF targetRect = homeAnimationFactory.getWindowTargetRect();
|
||||
|
||||
mWindowTransitionController.setPlayFraction(startProgress / mDragLengthFactor);
|
||||
mCurrentShift.updateValue(startProgress);
|
||||
mTaskViewSimulator.apply(mTransformParams.setProgress(startProgress));
|
||||
RectF cropRectF = new RectF(mTaskViewSimulator.getCurrentCropRect());
|
||||
|
||||
+33
-13
@@ -18,7 +18,7 @@ package com.android.quickstep;
|
||||
|
||||
import static android.view.Surface.ROTATION_0;
|
||||
|
||||
import static com.android.launcher3.util.MainThreadInitializedObject.forOverride;
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
|
||||
import static com.android.quickstep.views.OverviewActionsView.DISABLED_NO_THUMBNAIL;
|
||||
import static com.android.quickstep.views.OverviewActionsView.DISABLED_ROTATED;
|
||||
|
||||
@@ -39,13 +39,12 @@ import com.android.launcher3.R;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
||||
import com.android.launcher3.popup.SystemShortcut;
|
||||
import com.android.launcher3.util.MainThreadInitializedObject;
|
||||
import com.android.launcher3.util.ResourceBasedOverride;
|
||||
import com.android.quickstep.util.RecentsOrientedState;
|
||||
import com.android.quickstep.views.OverviewActionsView;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.TaskThumbnailView;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
import com.android.systemui.plugins.OverscrollPlugin;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||
|
||||
@@ -91,20 +90,22 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
|
||||
return shortcuts;
|
||||
}
|
||||
|
||||
public static final MainThreadInitializedObject<TaskOverlayFactory> INSTANCE =
|
||||
forOverride(TaskOverlayFactory.class, R.string.task_overlay_factory_class);
|
||||
|
||||
/**
|
||||
* @return a launcher-provided OverscrollPlugin if available, otherwise null
|
||||
*/
|
||||
public OverscrollPlugin getLocalOverscrollPlugin() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public TaskOverlay createOverlay(TaskThumbnailView thumbnailView) {
|
||||
return new TaskOverlay(thumbnailView);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses can attach any system listeners in this method, must be paired with
|
||||
* {@link #removeListeners()}
|
||||
*/
|
||||
public void initListeners() { }
|
||||
|
||||
/**
|
||||
* Subclasses should remove any system listeners in this method, must be paired with
|
||||
* {@link #initListeners()}
|
||||
*/
|
||||
public void removeListeners() { }
|
||||
|
||||
/** Note that these will be shown in order from top to bottom, if available for the task. */
|
||||
private static final TaskShortcutFactory[] MENU_OPTIONS = new TaskShortcutFactory[]{
|
||||
TaskShortcutFactory.APP_INFO,
|
||||
@@ -156,6 +157,7 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
|
||||
getActionsView().setCallbacks(new OverlayUICallbacks() {
|
||||
@Override
|
||||
public void onShare() {
|
||||
endLiveTileMode(isAllowedByPolicy);
|
||||
if (isAllowedByPolicy) {
|
||||
mImageApi.startShareActivity();
|
||||
} else {
|
||||
@@ -166,12 +168,30 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
|
||||
@SuppressLint("NewApi")
|
||||
@Override
|
||||
public void onScreenshot() {
|
||||
endLiveTileMode(isAllowedByPolicy);
|
||||
saveScreenshot(task);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* End rendering live tile in Overview.
|
||||
*
|
||||
* @param showScreenshot if it's true, we take a screenshot and switch to it.
|
||||
*/
|
||||
public void endLiveTileMode(boolean showScreenshot) {
|
||||
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
|
||||
RecentsView recentsView = mThumbnailView.getTaskView().getRecentsView();
|
||||
if (showScreenshot) {
|
||||
recentsView.switchToScreenshot(
|
||||
() -> recentsView.finishRecentsAnimation(true /* toRecents */, null));
|
||||
} else {
|
||||
recentsView.finishRecentsAnimation(true /* toRecents */, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to save screenshot of the task thumbnail.
|
||||
*/
|
||||
+3
-9
@@ -18,7 +18,6 @@ package com.android.quickstep;
|
||||
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_ACTIONS;
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_SELECTIONS;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_FREE_FORM_TAP;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_SPLIT_SCREEN_TAP;
|
||||
@@ -310,16 +309,11 @@ public interface TaskShortcutFactory {
|
||||
TaskShortcutFactory WELLBEING = (activity, view) ->
|
||||
WellbeingModel.SHORTCUT_FACTORY.getShortcut(activity, view.getItemInfo());
|
||||
|
||||
TaskShortcutFactory SCREENSHOT = (activity, tv) -> {
|
||||
if (ENABLE_OVERVIEW_ACTIONS.get()) {
|
||||
return tv.getThumbnail().getTaskOverlay()
|
||||
.getScreenshotShortcut(activity, tv.getItemInfo());
|
||||
}
|
||||
return null;
|
||||
};
|
||||
TaskShortcutFactory SCREENSHOT = (activity, tv) -> tv.getThumbnail().getTaskOverlay()
|
||||
.getScreenshotShortcut(activity, tv.getItemInfo());
|
||||
|
||||
TaskShortcutFactory MODAL = (activity, tv) -> {
|
||||
if (ENABLE_OVERVIEW_ACTIONS.get() && ENABLE_OVERVIEW_SELECTIONS.get()) {
|
||||
if (ENABLE_OVERVIEW_SELECTIONS.get()) {
|
||||
return tv.getThumbnail().getTaskOverlay().getModalStateSystemShortcut(tv.getItemInfo());
|
||||
}
|
||||
return null;
|
||||
+2
-2
@@ -41,7 +41,7 @@ import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.statehandlers.DepthController;
|
||||
import com.android.launcher3.util.DefaultDisplay;
|
||||
import com.android.launcher3.util.DisplayController;
|
||||
import com.android.quickstep.util.SurfaceTransactionApplier;
|
||||
import com.android.quickstep.util.TaskViewSimulator;
|
||||
import com.android.quickstep.util.TransformParams;
|
||||
@@ -146,7 +146,7 @@ public final class TaskViewUtils {
|
||||
DeviceProfile dp = BaseActivity.fromContext(context).getDeviceProfile();
|
||||
// RecentsView never updates the display rotation until swipe-up so the value may be stale.
|
||||
// Use the display value instead.
|
||||
int displayRotation = DefaultDisplay.INSTANCE.get(context).getInfo().rotation;
|
||||
int displayRotation = DisplayController.getDefaultDisplay(context).getInfo().rotation;
|
||||
|
||||
TaskViewSimulator topMostSimulator = null;
|
||||
if (targets.apps.length > 0) {
|
||||
+7
-43
@@ -101,24 +101,6 @@ import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Wrapper around a list for processing arguments.
|
||||
*/
|
||||
class ArgList extends LinkedList<String> {
|
||||
public ArgList(List<String> l) {
|
||||
super(l);
|
||||
}
|
||||
|
||||
public String peekArg() {
|
||||
return peekFirst();
|
||||
}
|
||||
|
||||
public String nextArg() {
|
||||
return pollFirst().toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Service connected by system-UI for handling touch interaction.
|
||||
@@ -238,23 +220,6 @@ public class TouchInteractionService extends Service implements PluginListener<O
|
||||
WindowBounds wb = new WindowBounds(bounds, insets);
|
||||
MAIN_EXECUTOR.execute(() -> SplitScreenBounds.INSTANCE.setSecondaryWindowBounds(wb));
|
||||
}
|
||||
|
||||
/** Deprecated methods **/
|
||||
public void onQuickStep(MotionEvent motionEvent) { }
|
||||
|
||||
public void onQuickScrubEnd() { }
|
||||
|
||||
public void onQuickScrubProgress(float progress) { }
|
||||
|
||||
public void onQuickScrubStart() { }
|
||||
|
||||
public void onPreMotionEvent(int downHitTarget) { }
|
||||
|
||||
public void onMotionEvent(MotionEvent ev) {
|
||||
ev.recycle();
|
||||
}
|
||||
|
||||
public void onBind(ISystemUiProxy iSystemUiProxy) { }
|
||||
};
|
||||
|
||||
private static boolean sConnected = false;
|
||||
@@ -616,9 +581,8 @@ public class TouchInteractionService extends Service implements PluginListener<O
|
||||
if (FeatureFlags.ENABLE_QUICK_CAPTURE_GESTURE.get()) {
|
||||
OverscrollPlugin plugin = null;
|
||||
if (FeatureFlags.FORCE_LOCAL_OVERSCROLL_PLUGIN.get()) {
|
||||
TaskOverlayFactory factory =
|
||||
TaskOverlayFactory.INSTANCE.get(getApplicationContext());
|
||||
plugin = factory.getLocalOverscrollPlugin(); // may be null
|
||||
plugin = OverscrollPluginFactory.INSTANCE.get(
|
||||
getApplicationContext()).getLocalOverscrollPlugin();
|
||||
}
|
||||
|
||||
// If not local plugin was forced, use the actual overscroll plugin if available.
|
||||
@@ -842,10 +806,10 @@ public class TouchInteractionService extends Service implements PluginListener<O
|
||||
@Override
|
||||
protected void dump(FileDescriptor fd, PrintWriter pw, String[] rawArgs) {
|
||||
if (rawArgs.length > 0 && Utilities.IS_DEBUG_DEVICE) {
|
||||
ArgList args = new ArgList(Arrays.asList(rawArgs));
|
||||
switch (args.nextArg()) {
|
||||
LinkedList<String> args = new LinkedList(Arrays.asList(rawArgs));
|
||||
switch (args.pollFirst()) {
|
||||
case "cmd":
|
||||
if (args.peekArg() == null) {
|
||||
if (args.peekFirst() == null) {
|
||||
printAvailableCommands(pw);
|
||||
} else {
|
||||
onCommand(pw, args);
|
||||
@@ -886,8 +850,8 @@ public class TouchInteractionService extends Service implements PluginListener<O
|
||||
pw.println(" clear-touch-log: Clears the touch interaction log");
|
||||
}
|
||||
|
||||
private void onCommand(PrintWriter pw, ArgList args) {
|
||||
switch (args.nextArg()) {
|
||||
private void onCommand(PrintWriter pw, LinkedList<String> args) {
|
||||
switch (args.pollFirst()) {
|
||||
case "clear-touch-log":
|
||||
ActiveGestureLog.INSTANCE.clear();
|
||||
break;
|
||||
+2
-2
@@ -21,7 +21,7 @@ import android.view.MotionEvent;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.util.DefaultDisplay;
|
||||
import com.android.launcher3.util.DisplayController;
|
||||
import com.android.launcher3.util.TouchController;
|
||||
import com.android.quickstep.RecentsActivity;
|
||||
import com.android.quickstep.SysUINavigationMode;
|
||||
@@ -43,7 +43,7 @@ public class FallbackNavBarTouchController implements TouchController,
|
||||
SysUINavigationMode.Mode sysUINavigationMode = SysUINavigationMode.getMode(mActivity);
|
||||
if (sysUINavigationMode == SysUINavigationMode.Mode.NO_BUTTON) {
|
||||
NavBarPosition navBarPosition = new NavBarPosition(sysUINavigationMode,
|
||||
DefaultDisplay.INSTANCE.get(mActivity).getInfo());
|
||||
DisplayController.getDefaultDisplay(mActivity).getInfo());
|
||||
mTriggerSwipeUpTracker = new TriggerSwipeUpTouchTracker(mActivity,
|
||||
true /* disableHorizontalSwipe */, navBarPosition,
|
||||
null /* onInterceptTouch */, this);
|
||||
+4
@@ -19,6 +19,7 @@ import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_MODAL;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.PLAY_ATOMIC_OVERVIEW_PEEK;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.PLAY_ATOMIC_OVERVIEW_SCALE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
|
||||
@@ -26,6 +27,7 @@ import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET;
|
||||
import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS;
|
||||
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
|
||||
import static com.android.quickstep.views.RecentsView.TASK_MODALNESS;
|
||||
import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
|
||||
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.anim.PropertySetter;
|
||||
@@ -86,6 +88,8 @@ public class FallbackRecentsStateController implements StateHandler<RecentsState
|
||||
config.getInterpolator(ANIM_OVERVIEW_SCALE, LINEAR));
|
||||
setter.setFloat(mRecentsView, ADJACENT_PAGE_OFFSET, scaleAndOffset[1],
|
||||
config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_X, LINEAR));
|
||||
setter.setFloat(mRecentsView, TASK_SECONDARY_TRANSLATION, 0f,
|
||||
config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, LINEAR));
|
||||
|
||||
setter.setFloat(mRecentsView, TASK_MODALNESS, state.getOverviewModalness(),
|
||||
config.getInterpolator(ANIM_OVERVIEW_MODAL, LINEAR));
|
||||
+5
-5
@@ -101,20 +101,20 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity>
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldAddDummyTaskView(RunningTaskInfo runningTaskInfo) {
|
||||
protected boolean shouldAddStubTaskView(RunningTaskInfo runningTaskInfo) {
|
||||
if (mHomeTaskInfo != null && runningTaskInfo != null &&
|
||||
mHomeTaskInfo.taskId == runningTaskInfo.taskId
|
||||
&& getTaskViewCount() == 0) {
|
||||
// Do not add a dummy task if we are running over home with empty recents, so that we
|
||||
// show the empty recents message instead of showing a dummy task and later removing it.
|
||||
// Do not add a stub task if we are running over home with empty recents, so that we
|
||||
// show the empty recents message instead of showing a stub task and later removing it.
|
||||
return false;
|
||||
}
|
||||
return super.shouldAddDummyTaskView(runningTaskInfo);
|
||||
return super.shouldAddStubTaskView(runningTaskInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyLoadPlan(ArrayList<Task> tasks) {
|
||||
// When quick-switching on 3p-launcher, we add a "dummy" tile corresponding to Launcher
|
||||
// When quick-switching on 3p-launcher, we add a "stub" tile corresponding to Launcher
|
||||
// as well. This tile is never shown as we have setCurrentTaskHidden, but allows use to
|
||||
// track the index of the next task appropriately, as if we are switching on any other app.
|
||||
if (mHomeTaskInfo != null && mHomeTaskInfo.taskId == mRunningTaskId && !tasks.isEmpty()) {
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user