Merge "Fix TaskViewTouchController crash in seascape"
diff --git a/Android.mk b/Android.mk
index 349a134..503f9ae 100644
--- a/Android.mk
+++ b/Android.mk
@@ -208,11 +208,13 @@
LOCAL_SRC_FILES := \
$(call all-java-files-under, src) \
$(call all-java-files-under, quickstep/src) \
- $(call all-java-files-under, go/src)
+ $(call all-java-files-under, go/src) \
+ $(call all-java-files-under, go/quickstep/src)
LOCAL_RESOURCE_DIR := \
$(LOCAL_PATH)/quickstep/res \
- $(LOCAL_PATH)/go/res
+ $(LOCAL_PATH)/go/res \
+ $(LOCAL_PATH)/go/quickstep/res
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
LOCAL_PROGUARD_ENABLED := full
@@ -225,7 +227,7 @@
LOCAL_FULL_LIBS_MANIFEST_FILES := \
$(LOCAL_PATH)/go/AndroidManifest.xml \
- $(LOCAL_PATH)/quickstep/AndroidManifest-launcher.xml \
+ $(LOCAL_PATH)/go/AndroidManifest-launcher.xml \
$(LOCAL_PATH)/AndroidManifest-common.xml
LOCAL_MANIFEST_FILE := quickstep/AndroidManifest.xml
diff --git a/AndroidManifest-common.xml b/AndroidManifest-common.xml
index a47a500..9e76ce3 100644
--- a/AndroidManifest-common.xml
+++ b/AndroidManifest-common.xml
@@ -40,6 +40,8 @@
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
<uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
+ <!-- for rotating surface by arbitrary degree -->
+ <uses-permission android:name="android.permission.ROTATE_SURFACE_FLINGER" />
<!--
Permissions required for read/write access to the workspace data. These permission name
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 97bce9c..56a2595 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -49,7 +49,7 @@
android:stateNotNeeded="true"
android:windowSoftInputMode="adjustPan"
android:screenOrientation="unspecified"
- android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize|uiMode"
+ android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize"
android:resizeableActivity="true"
android:resumeWhilePausing="true"
android:taskAffinity=""
diff --git a/go/AndroidManifest-launcher.xml b/go/AndroidManifest-launcher.xml
new file mode 100644
index 0000000..2223036
--- /dev/null
+++ b/go/AndroidManifest-launcher.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 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.
+*/
+-->
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.launcher3">
+ <uses-sdk android:targetSdkVersion="29" android:minSdkVersion="25"/>
+ <!--
+ Manifest entries specific to Launcher3. This is merged with AndroidManifest-common.xml.
+ Refer comments around specific entries on how to extend individual components.
+ -->
+
+ <application
+ android:backupAgent="com.android.launcher3.LauncherBackupAgent"
+ android:fullBackupOnly="true"
+ android:fullBackupContent="@xml/backupscheme"
+ android:hardwareAccelerated="true"
+ android:icon="@drawable/ic_launcher_home"
+ android:label="@string/derived_app_name"
+ android:theme="@style/AppTheme"
+ android:largeHeap="@bool/config_largeHeap"
+ android:restoreAnyVersion="true"
+ android:supportsRtl="true" >
+
+ <!--
+ Main launcher activity. When extending only change the name, and keep all the
+ attributes and intent filters the same
+ -->
+ <activity
+ android:name="com.android.launcher3.Launcher3QuickStepGo"
+ android:launchMode="singleTask"
+ android:clearTaskOnLaunch="true"
+ android:stateNotNeeded="true"
+ android:windowSoftInputMode="adjustPan"
+ android:screenOrientation="unspecified"
+ android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize|uiMode"
+ android:resizeableActivity="true"
+ android:resumeWhilePausing="true"
+ android:taskAffinity=""
+ android:exported="true"
+ android:enabled="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.HOME" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.MONKEY"/>
+ <category android:name="android.intent.category.LAUNCHER_APP" />
+ </intent-filter>
+ <meta-data
+ android:name="com.android.launcher3.grid.control"
+ android:value="${packageName}.grid_control" />
+ </activity>
+
+ </application>
+</manifest>
diff --git a/go/quickstep/res/values/config.xml b/go/quickstep/res/values/config.xml
new file mode 100644
index 0000000..f376774
--- /dev/null
+++ b/go/quickstep/res/values/config.xml
@@ -0,0 +1,18 @@
+<?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>
+ <string name="app_sharing_component" translatable="false"/>
+</resources>
\ No newline at end of file
diff --git a/go/quickstep/res/values/strings.xml b/go/quickstep/res/values/strings.xml
new file mode 100644
index 0000000..fdd8397
--- /dev/null
+++ b/go/quickstep/res/values/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Label for app share drop target. [CHAR_LIMIT=20] -->
+ <string name="app_share_drop_target_label">Share App</string>
+</resources>
diff --git a/go/quickstep/src/com/android/launcher3/AppSharing.java b/go/quickstep/src/com/android/launcher3/AppSharing.java
new file mode 100644
index 0000000..b72e71c
--- /dev/null
+++ b/go/quickstep/src/com/android/launcher3/AppSharing.java
@@ -0,0 +1,132 @@
+/*
+ * 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;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.View;
+
+import androidx.core.content.FileProvider;
+
+import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.popup.SystemShortcut;
+
+import java.io.File;
+
+/**
+ * Defines the Share system shortcut and its factory.
+ * This shortcut can be added to the app long-press menu on the home screen.
+ * Clicking the button will initiate peer-to-peer sharing of the app.
+ */
+public final class AppSharing {
+ /**
+ * This flag enables this feature. It is defined here rather than in launcher3's FeatureFlags
+ * because it is unique to Go and not toggleable at runtime.
+ */
+ public static final boolean ENABLE_APP_SHARING = true;
+
+ private static final String TAG = "AppSharing";
+ private static final String FILE_PROVIDER_SUFFIX = ".overview.fileprovider";
+ private static final String APP_EXSTENSION = ".apk";
+ private static final String APP_MIME_TYPE = "application/application";
+
+ private final String mSharingComponent;
+
+ private AppSharing(Launcher launcher) {
+ mSharingComponent = launcher.getText(R.string.app_sharing_component).toString();
+ }
+
+ private boolean canShare(ItemInfo info) {
+ /**
+ * TODO: Implement once b/168831749 has been resolved
+ * The implementation should check the validity of the app.
+ * It should also check whether the app is free or paid, returning false in the latter case.
+ * For now, all checks occur in the sharing app.
+ * So, we simply check whether the sharing app is defined.
+ */
+ return !TextUtils.isEmpty(mSharingComponent);
+ }
+
+ private Uri getShareableUri(Context context, String path, String displayName) {
+ String authority = BuildConfig.APPLICATION_ID + FILE_PROVIDER_SUFFIX;
+ File pathFile = new File(path);
+ return FileProvider.getUriForFile(context, authority, pathFile, displayName);
+ }
+
+ private SystemShortcut<Launcher> getShortcut(Launcher launcher, ItemInfo info) {
+ if (!canShare(info)) {
+ return null;
+ }
+
+ return new Share(launcher, info);
+ }
+
+ /**
+ * The Share App system shortcut, used to initiate p2p sharing of a given app
+ */
+ public final class Share extends SystemShortcut<Launcher> {
+ public Share(Launcher target, ItemInfo itemInfo) {
+ super(R.drawable.ic_share, R.string.app_share_drop_target_label, target, itemInfo);
+ }
+
+ @Override
+ public void onClick(View view) {
+ Intent sendIntent = new Intent();
+ sendIntent.setAction(Intent.ACTION_SEND);
+
+ ComponentName targetComponent = mItemInfo.getTargetComponent();
+ if (targetComponent == null) {
+ Log.e(TAG, "Item missing target component");
+ return;
+ }
+ String packageName = targetComponent.getPackageName();
+ PackageManager packageManager = view.getContext().getPackageManager();
+ String sourceDir, appLabel;
+ try {
+ PackageInfo packageInfo = packageManager.getPackageInfo(packageName, 0);
+ sourceDir = packageInfo.applicationInfo.sourceDir;
+ appLabel = packageManager.getApplicationLabel(packageInfo.applicationInfo)
+ .toString() + APP_EXSTENSION;
+ } catch (Exception e) {
+ Log.e(TAG, "Could not find info for package \"" + packageName + "\"");
+ return;
+ }
+ Uri uri = getShareableUri(view.getContext(), sourceDir, appLabel);
+ sendIntent.putExtra(Intent.EXTRA_STREAM, uri);
+ sendIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
+
+ sendIntent.setType(APP_MIME_TYPE);
+ sendIntent.setComponent(ComponentName.unflattenFromString(mSharingComponent));
+
+ mTarget.startActivitySafely(view, sendIntent, mItemInfo);
+
+ AbstractFloatingView.closeAllOpenViews(mTarget);
+ }
+ }
+
+ /**
+ * Shortcut factory for generating the Share App button
+ */
+ public static final SystemShortcut.Factory<Launcher> SHORTCUT_FACTORY = (launcher, itemInfo) ->
+ (new AppSharing(launcher)).getShortcut(launcher, itemInfo);
+}
diff --git a/go/quickstep/src/com/android/launcher3/Launcher3QuickStepGo.java b/go/quickstep/src/com/android/launcher3/Launcher3QuickStepGo.java
new file mode 100644
index 0000000..8bd0fec
--- /dev/null
+++ b/go/quickstep/src/com/android/launcher3/Launcher3QuickStepGo.java
@@ -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.launcher3;
+
+import com.android.launcher3.popup.SystemShortcut;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
+
+import java.util.stream.Stream;
+
+/**
+ * The Launcher variant used for Android Go Edition
+ */
+public class Launcher3QuickStepGo extends QuickstepLauncher {
+ private static final String TAG = "Launcher3QuickStepGo";
+
+ @Override
+ public Stream<SystemShortcut.Factory> getSupportedShortcuts() {
+ Stream<SystemShortcut.Factory> shortcuts = super.getSupportedShortcuts();
+
+ if (AppSharing.ENABLE_APP_SHARING) {
+ shortcuts = Stream.concat(shortcuts, Stream.of(AppSharing.SHORTCUT_FACTORY));
+ }
+
+ return shortcuts;
+ }
+}
diff --git a/quickstep/AndroidManifest-launcher.xml b/quickstep/AndroidManifest-launcher.xml
index 19f85e4..53910e3 100644
--- a/quickstep/AndroidManifest-launcher.xml
+++ b/quickstep/AndroidManifest-launcher.xml
@@ -49,7 +49,7 @@
android:stateNotNeeded="true"
android:windowSoftInputMode="adjustPan"
android:screenOrientation="unspecified"
- android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize|uiMode"
+ android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize"
android:resizeableActivity="true"
android:resumeWhilePausing="true"
android:taskAffinity=""
diff --git a/quickstep/AndroidManifest.xml b/quickstep/AndroidManifest.xml
index 5be32a8..4e7c3fa 100644
--- a/quickstep/AndroidManifest.xml
+++ b/quickstep/AndroidManifest.xml
@@ -59,7 +59,7 @@
android:stateNotNeeded="true"
android:theme="@style/LauncherTheme"
android:screenOrientation="unspecified"
- android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize|uiMode"
+ android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize"
android:resizeableActivity="true"
android:resumeWhilePausing="true"
android:taskAffinity=""/>
diff --git a/quickstep/res/drawable/default_sandbox_app_icon.xml b/quickstep/res/drawable/default_sandbox_app_icon.xml
new file mode 100644
index 0000000..e9c9701
--- /dev/null
+++ b/quickstep/res/drawable/default_sandbox_app_icon.xml
@@ -0,0 +1,17 @@
+<?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.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="oval">
+ <solid android:color="@color/gesture_tutorial_fake_task_view_color" />
+</shape>
diff --git a/quickstep/res/drawable/default_sandbox_app_task_thumbnail.xml b/quickstep/res/drawable/default_sandbox_app_task_thumbnail.xml
new file mode 100644
index 0000000..9d4cc95
--- /dev/null
+++ b/quickstep/res/drawable/default_sandbox_app_task_thumbnail.xml
@@ -0,0 +1,17 @@
+<?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.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <solid android:color="@color/gesture_tutorial_fake_task_view_color" />
+</shape>
diff --git a/quickstep/res/drawable/default_sandbox_wallpaper.xml b/quickstep/res/drawable/default_sandbox_wallpaper.xml
new file mode 100644
index 0000000..816d1d6
--- /dev/null
+++ b/quickstep/res/drawable/default_sandbox_wallpaper.xml
@@ -0,0 +1,17 @@
+<?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.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <solid android:color="?android:attr/colorBackground" />
+</shape>
diff --git a/quickstep/res/layout/gesture_tutorial_fragment.xml b/quickstep/res/layout/gesture_tutorial_fragment.xml
index 52475df..2ff3a5e 100644
--- a/quickstep/res/layout/gesture_tutorial_fragment.xml
+++ b/quickstep/res/layout/gesture_tutorial_fragment.xml
@@ -16,8 +16,7 @@
<com.android.quickstep.interaction.RootSandboxLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="?android:attr/colorBackground">
+ android:layout_height="match_parent">
<View
android:id="@+id/gesture_tutorial_ripple_view"
@@ -29,15 +28,12 @@
android:id="@+id/gesture_tutorial_fake_icon_view"
android:layout_width="20dp"
android:layout_height="20dp"
- android:background="@drawable/bg_circle"
- android:backgroundTint="@color/gesture_tutorial_fake_task_view_color"
android:visibility="invisible" />
<View
android:id="@+id/gesture_tutorial_fake_task_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="@color/gesture_tutorial_fake_task_view_color"
android:visibility="invisible" />
<ImageView
diff --git a/quickstep/res/xml/overview_file_provider_paths.xml b/quickstep/res/xml/overview_file_provider_paths.xml
index 14d7459..07e3236 100644
--- a/quickstep/res/xml/overview_file_provider_paths.xml
+++ b/quickstep/res/xml/overview_file_provider_paths.xml
@@ -2,4 +2,5 @@
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<cache-path name="shared_images" path="/" />
<files-path name="log_files" path="/" />
+ <root-path name="apps" path="/" />
</paths>
\ No newline at end of file
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
index c724318..f02acab 100644
--- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
@@ -167,9 +167,14 @@
}
@Override
- protected void handlePendingActivityRequest() {
- super.handlePendingActivityRequest();
- if (mPendingActivityRequestCode != -1 && isInState(NORMAL)) {
+ public void onStateSetEnd(LauncherState state) {
+ super.onStateSetEnd(state);
+ handlePendingActivityRequest();
+ }
+
+ private void handlePendingActivityRequest() {
+ if (mPendingActivityRequestCode != -1 && isInState(NORMAL)
+ && ((getActivityFlags() & ACTIVITY_STATE_DEFERRED_RESUMED) != 0)) {
// Remove any active ProxyActivityStarter task and send RESULT_CANCELED to Launcher.
onActivityResult(mPendingActivityRequestCode, RESULT_CANCELED, null);
// ProxyActivityStarter is started with clear task to reset the task after which it
diff --git a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
index 3e9f82b..cc3b7b6 100644
--- a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
@@ -57,7 +57,6 @@
import android.os.CancellationSignal;
import android.os.Handler;
import android.os.Looper;
-import android.os.Trace;
import android.util.Pair;
import android.view.View;
@@ -140,7 +139,6 @@
// Progress = 0: All apps is fully pulled up, Progress = 1: All apps is fully pulled down.
public static final float ALL_APPS_PROGRESS_OFF_SCREEN = 1.3059858f;
- public static final String TRANSITION_OPEN_LAUNCHER = "transition:OpenLauncher";
protected final BaseQuickstepLauncher mLauncher;
@@ -805,11 +803,10 @@
== PackageManager.PERMISSION_GRANTED;
}
- private void addCujInstrumentation(Animator anim, int cuj, String transition) {
+ private void addCujInstrumentation(Animator anim, int cuj) {
anim.addListener(new AnimationSuccessListener() {
@Override
public void onAnimationStart(Animator animation) {
- Trace.beginAsyncSection(transition, 0);
InteractionJankMonitorWrapper.begin(cuj);
super.onAnimationStart(animation);
}
@@ -824,12 +821,6 @@
public void onAnimationSuccess(Animator animator) {
InteractionJankMonitorWrapper.end(cuj);
}
-
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- Trace.endAsyncSection(TRANSITION_OPEN_LAUNCHER, 0);
- }
});
}
@@ -898,8 +889,7 @@
if (launcherIsATargetWithMode(appTargets, MODE_OPENING)
|| mLauncher.isForceInvisible()) {
addCujInstrumentation(
- anim, InteractionJankMonitorWrapper.CUJ_APP_CLOSE_TO_HOME,
- TRANSITION_OPEN_LAUNCHER);
+ anim, InteractionJankMonitorWrapper.CUJ_APP_CLOSE_TO_HOME);
// Only register the content animation for cancellation when state changes
mLauncher.getStateManager().setCurrentAnimation(anim);
@@ -971,9 +961,7 @@
addCujInstrumentation(anim,
launchingFromRecents
? InteractionJankMonitorWrapper.CUJ_APP_LAUNCH_FROM_RECENTS
- : InteractionJankMonitorWrapper.CUJ_APP_LAUNCH_FROM_ICON,
- launchingFromRecents
- ? TRANSITION_LAUNCH_FROM_RECENTS : TRANSITION_LAUNCH_FROM_ICON);
+ : InteractionJankMonitorWrapper.CUJ_APP_LAUNCH_FROM_ICON);
if (launcherClosing) {
anim.addListener(mForceInvisibleListener);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index 950598c..2d704f8 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -35,7 +35,6 @@
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
-import android.util.Log;
import android.view.View;
import com.android.launcher3.BaseQuickstepLauncher;
@@ -55,7 +54,6 @@
import com.android.launcher3.model.data.ItemInfo;
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.LandscapeEdgeSwipeController;
import com.android.launcher3.uioverrides.touchcontrollers.NavBarToHomeTouchController;
@@ -273,9 +271,6 @@
@Override
public TouchController[] createTouchControllers() {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.PAUSE_NOT_DETECTED, "createTouchControllers.1");
- }
Mode mode = SysUINavigationMode.getMode(this);
ArrayList<TouchController> list = new ArrayList<>();
@@ -283,9 +278,6 @@
if (mode == NO_BUTTON) {
list.add(new NoButtonQuickSwitchTouchController(this));
list.add(new NavBarToHomeTouchController(this));
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.PAUSE_NOT_DETECTED, "createTouchControllers.2");
- }
list.add(new NoButtonNavbarToOverviewTouchController(this));
} else {
if (getDeviceProfile().isVerticalBarLayout()) {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
index f73e2f2..6b9c340 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
@@ -29,7 +29,6 @@
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
import android.animation.ValueAnimator;
-import android.util.Log;
import android.view.MotionEvent;
import android.view.animation.Interpolator;
@@ -47,7 +46,6 @@
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.graphics.OverviewScrim;
import com.android.launcher3.states.StateAnimationConfig;
-import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.touch.SingleAxisSwipeDetector;
import com.android.launcher3.util.TouchController;
import com.android.quickstep.TaskUtils;
@@ -103,37 +101,19 @@
}
private boolean canInterceptTouch(MotionEvent ev) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.PAUSE_NOT_DETECTED, "NavBarToHomeTouchController.canInterceptTouch "
- + ev);
- }
boolean cameFromNavBar = (ev.getEdgeFlags() & Utilities.EDGE_NAV_BAR) != 0;
if (!cameFromNavBar) {
return false;
}
if (mStartState.overviewUi || mStartState == ALL_APPS) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.PAUSE_NOT_DETECTED,
- "NavBarToHomeTouchController.canInterceptTouch true 1 "
- + mStartState.overviewUi + " " + (mStartState == ALL_APPS));
- }
return true;
}
int typeToClose = ENABLE_ALL_APPS_EDU.get() ? TYPE_ALL & ~TYPE_ALL_APPS_EDU : TYPE_ALL;
if (AbstractFloatingView.getTopOpenViewWithType(mLauncher, typeToClose) != null) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.PAUSE_NOT_DETECTED,
- "NavBarToHomeTouchController.canInterceptTouch true 2 "
- + AbstractFloatingView.getTopOpenView(mLauncher), new Exception());
- }
return true;
}
if (FeatureFlags.ASSISTANT_GIVES_LAUNCHER_FOCUS.get()
&& AssistantUtilities.isExcludedAssistantRunning()) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.PAUSE_NOT_DETECTED,
- "NavBarToHomeTouchController.canInterceptTouch true 3");
- }
return true;
}
return false;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
index 702c519..addfe92 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
@@ -37,7 +37,6 @@
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;
@@ -49,7 +48,6 @@
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.graphics.OverviewScrim;
import com.android.launcher3.states.StateAnimationConfig;
-import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.VibratorWrapper;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.util.AnimatorControllerWithResistance;
@@ -90,9 +88,6 @@
mRecentsView = l.getOverviewPanel();
mMotionPauseDetector = new MotionPauseDetector(l);
mMotionPauseMinDisplacement = ViewConfiguration.get(l).getScaledTouchSlop();
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.PAUSE_NOT_DETECTED, "NoButtonNavbarToOverviewTouchController.ctor");
- }
}
@Override
@@ -221,9 +216,6 @@
@Override
public boolean onDrag(float yDisplacement, float xDisplacement, MotionEvent event) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.PAUSE_NOT_DETECTED, "NoButtonNavbarToOverviewTouchController");
- }
if (mStartedOverview) {
if (!mReachedOverview) {
mStartDisplacement.set(xDisplacement, yDisplacement);
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index c59c045..3c6299f 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -19,7 +19,8 @@
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.QuickstepAppTransitionManagerImpl.TRANSITION_OPEN_LAUNCHER;
+import static com.android.launcher3.QuickstepAppTransitionManagerImpl.RECENTS_LAUNCH_DURATION;
+import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
import static com.android.launcher3.anim.Interpolators.DEACCEL;
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
@@ -31,6 +32,7 @@
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_QUICKSWITCH_RIGHT;
import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.launcher3.util.SystemUiController.UI_STATE_OVERVIEW;
import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
import static com.android.quickstep.GestureState.GestureEndTarget.HOME;
@@ -52,12 +54,11 @@
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
+import android.graphics.Matrix;
import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Build;
import android.os.SystemClock;
-import android.os.Trace;
-import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnApplyWindowInsetsListener;
@@ -78,7 +79,6 @@
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.logging.StatsLogManager.StatsLogger;
import com.android.launcher3.statemanager.StatefulActivity;
-import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.tracing.InputConsumerProto;
import com.android.launcher3.tracing.SwipeHandlerProto;
import com.android.launcher3.util.TraceHelper;
@@ -92,7 +92,7 @@
import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.util.InputConsumerProxy;
import com.android.quickstep.util.MotionPauseDetector;
-import com.android.quickstep.util.RecentsOrientedState;
+import com.android.quickstep.util.MultiValueUpdateListener;
import com.android.quickstep.util.ProtoTracer;
import com.android.quickstep.util.RecentsOrientedState;
import com.android.quickstep.util.RectFSpringAnim;
@@ -108,6 +108,7 @@
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
import com.android.systemui.shared.system.LatencyTrackerCompat;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
+import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
import com.android.systemui.shared.system.TaskInfoCompat;
import com.android.systemui.shared.system.TaskStackChangeListener;
@@ -321,13 +322,7 @@
protected boolean onActivityInit(Boolean alreadyOnHome) {
T createdActivity = mActivityInterface.getCreatedActivity();
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.PAUSE_NOT_DETECTED, "BaseSwipeUpHandler.1");
- }
if (createdActivity != null) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.PAUSE_NOT_DETECTED, "BaseSwipeUpHandler.2");
- }
initTransitionEndpoints(createdActivity.getDeviceProfile());
}
final T activity = mActivityInterface.getCreatedActivity();
@@ -1213,7 +1208,6 @@
anim.addAnimatorListener(new AnimationSuccessListener() {
@Override
public void onAnimationStart(Animator animation) {
- Trace.beginAsyncSection(TRANSITION_OPEN_LAUNCHER, 0);
InteractionJankMonitorWrapper.begin(cuj);
if (mActivity != null) {
removeLiveTileOverlay();
@@ -1236,12 +1230,6 @@
super.onAnimationCancel(animation);
InteractionJankMonitorWrapper.cancel(cuj);
}
-
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- Trace.endAsyncSection(TRANSITION_OPEN_LAUNCHER, 0);
- }
});
if (mRecentsAnimationTargets != null) {
mRecentsAnimationTargets.addReleaseCheck(anim);
@@ -1391,34 +1379,55 @@
if (mRecentsAnimationController != null) {
// Update the screenshot of the task
if (mTaskSnapshot == null) {
- mTaskSnapshot = mRecentsAnimationController.screenshotTask(runningTaskId);
+ UI_HELPER_EXECUTOR.execute(() -> {
+ final ThumbnailData taskSnapshot =
+ mRecentsAnimationController.screenshotTask(runningTaskId);
+ MAIN_EXECUTOR.execute(() -> {
+ mTaskSnapshot = taskSnapshot;
+ if (!updateThumbnail(runningTaskId)) {
+ setScreenshotCapturedState();
+ }
+ });
+ });
+ return;
}
- final TaskView taskView;
- if (mGestureState.getEndTarget() == HOME) {
- // Capture the screenshot before finishing the transition to home to ensure it's
- // taken in the correct orientation, but no need to update the thumbnail.
- taskView = null;
- } else {
- taskView = mRecentsView.updateThumbnail(runningTaskId, mTaskSnapshot);
- }
- if (taskView != null && !mCanceled) {
- // Defer finishing the animation until the next launcher frame with the
- // new thumbnail
- finishTransitionPosted = ViewUtils.postFrameDrawn(taskView,
- () -> mStateCallback.setStateOnUiThread(STATE_SCREENSHOT_CAPTURED),
- this::isCanceled);
- }
+ finishTransitionPosted = updateThumbnail(runningTaskId);
}
if (!finishTransitionPosted) {
- // If we haven't posted a draw callback, set the state immediately.
- Object traceToken = TraceHelper.INSTANCE.beginSection(SCREENSHOT_CAPTURED_EVT,
- TraceHelper.FLAG_CHECK_FOR_RACE_CONDITIONS);
- mStateCallback.setStateOnUiThread(STATE_SCREENSHOT_CAPTURED);
- TraceHelper.INSTANCE.endSection(traceToken);
+ setScreenshotCapturedState();
}
}
}
+ // Returns whether finish transition was posted.
+ private boolean updateThumbnail(int runningTaskId) {
+ boolean finishTransitionPosted = false;
+ final TaskView taskView;
+ if (mGestureState.getEndTarget() == HOME) {
+ // Capture the screenshot before finishing the transition to home to ensure it's
+ // taken in the correct orientation, but no need to update the thumbnail.
+ taskView = null;
+ } else {
+ taskView = mRecentsView.updateThumbnail(runningTaskId, mTaskSnapshot);
+ }
+ if (taskView != null && !mCanceled) {
+ // Defer finishing the animation until the next launcher frame with the
+ // new thumbnail
+ finishTransitionPosted = ViewUtils.postFrameDrawn(taskView,
+ () -> mStateCallback.setStateOnUiThread(STATE_SCREENSHOT_CAPTURED),
+ this::isCanceled);
+ }
+ return finishTransitionPosted;
+ }
+
+ private void setScreenshotCapturedState() {
+ // If we haven't posted a draw callback, set the state immediately.
+ Object traceToken = TraceHelper.INSTANCE.beginSection(SCREENSHOT_CAPTURED_EVT,
+ TraceHelper.FLAG_CHECK_FOR_RACE_CONDITIONS);
+ mStateCallback.setStateOnUiThread(STATE_SCREENSHOT_CAPTURED);
+ TraceHelper.INSTANCE.endSection(traceToken);
+ }
+
private void finishCurrentTransitionToRecents() {
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
mStateCallback.setStateOnUiThread(STATE_CURRENT_TASK_FINISHED);
@@ -1498,17 +1507,36 @@
}
private void launchOtherTaskInLiveTileMode(int taskId, RemoteAnimationTargetCompat[] apps) {
- TaskView taskView = mRecentsView.getTaskView(taskId);
- if (taskView == null) {
- return;
- }
-
AnimatorSet anim = new AnimatorSet();
- TaskViewUtils.composeRecentsLaunchAnimator(
- anim, taskView, apps,
- mRecentsAnimationTargets.wallpapers, true /* launcherClosing */,
- mActivity.getStateManager(), mRecentsView,
- mActivityInterface.getDepthController());
+ TaskView taskView = mRecentsView.getTaskView(taskId);
+ if (taskView == null || !mRecentsView.isTaskViewVisible(taskView)) {
+ // TODO: Refine this animation.
+ SurfaceTransactionApplier surfaceApplier =
+ new SurfaceTransactionApplier(mActivity.getDragLayer());
+ ValueAnimator appAnimator = ValueAnimator.ofFloat(0, 1);
+ appAnimator.setDuration(RECENTS_LAUNCH_DURATION);
+ appAnimator.setInterpolator(ACCEL_DEACCEL);
+ appAnimator.addUpdateListener(new MultiValueUpdateListener() {
+ @Override
+ public void onUpdate(float percent) {
+ SurfaceParams.Builder builder = new SurfaceParams.Builder(
+ apps[apps.length - 1].leash);
+ Matrix matrix = new Matrix();
+ matrix.postScale(percent, percent);
+ matrix.postTranslate(mDp.widthPx * (1 - percent) / 2,
+ mDp.heightPx * (1 - percent) / 2);
+ builder.withAlpha(percent).withMatrix(matrix);
+ surfaceApplier.scheduleApply(builder.build());
+ }
+ });
+ anim.play(appAnimator);
+ } else {
+ TaskViewUtils.composeRecentsLaunchAnimator(
+ anim, taskView, apps,
+ mRecentsAnimationTargets.wallpapers, true /* launcherClosing */,
+ mActivity.getStateManager(), mRecentsView,
+ mActivityInterface.getDepthController());
+ }
anim.addListener(new AnimatorListenerAdapter(){
@Override
@@ -1710,6 +1738,8 @@
LiveTileOverlay.INSTANCE.update(
mTaskViewSimulator.getCurrentRect(),
mTaskViewSimulator.getCurrentCornerRadius());
+ LiveTileOverlay.INSTANCE.setRotation(
+ mRecentsView.getPagedViewOrientedState().getDisplayRotation());
}
ProtoTracer.INSTANCE.get(mContext).scheduleFrameUpdate();
}
diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
index 43581ca..2559a6f 100644
--- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
+++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
@@ -25,6 +25,7 @@
import android.content.Context;
import android.os.Build;
import android.os.SystemClock;
+import android.os.Trace;
import android.view.ViewConfiguration;
import androidx.annotation.BinderThread;
@@ -141,6 +142,7 @@
private class RecentsActivityCommand<T extends StatefulActivity<?>> implements Runnable {
+ private static final String TRANSITION_NAME = "Transition:toOverview";
protected final BaseActivityInterface<?, T> mActivityInterface;
private final long mCreateTime;
private final AppToOverviewAnimationProvider<T> mAnimationProvider;
@@ -224,8 +226,15 @@
wallpaperTargets);
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
+ public void onAnimationStart(Animator animation) {
+ Trace.beginAsyncSection(TRANSITION_NAME, 0);
+ super.onAnimationStart(animation);
+ }
+
+ @Override
public void onAnimationEnd(Animator animation) {
onTransitionComplete();
+ Trace.endAsyncSection(TRANSITION_NAME, 0);
}
});
return animatorSet;
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationController.java b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
index 7de658c..bc5e18d 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationController.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
@@ -16,6 +16,7 @@
package com.android.quickstep;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.util.Executors.THREAD_POOL_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import android.graphics.Rect;
@@ -96,8 +97,8 @@
* {@link RecentsAnimationCallbacks#onTaskAppeared(RemoteAnimationTargetCompat)}}.
*/
@UiThread
- public boolean removeTaskTarget(@NonNull RemoteAnimationTargetCompat target) {
- return mController.removeTask(target.taskId);
+ public void removeTaskTarget(@NonNull RemoteAnimationTargetCompat target) {
+ THREAD_POOL_EXECUTOR.execute(() -> mController.removeTask(target.taskId));
}
@UiThread
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 8ce1f51..1e0a00a 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -627,10 +627,6 @@
}
private void handleOrientationSetup(InputConsumer baseInputConsumer) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.PAUSE_NOT_DETECTED, "handleOrientationSetup.1");
- }
-
baseInputConsumer.notifyOrientationSetup();
}
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OneHandedModeInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OneHandedModeInputConsumer.java
index 22bd334..b10bdde 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OneHandedModeInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OneHandedModeInputConsumer.java
@@ -54,6 +54,7 @@
private final PointF mLastPos = new PointF();
private boolean mPassedSlop;
+ private boolean mIsStopGesture;
public OneHandedModeInputConsumer(Context context, RecentsAnimationDeviceState deviceState,
InputConsumer delegate, InputMonitorCompat inputMonitor) {
@@ -105,7 +106,7 @@
float distance = (float) Math.hypot(mLastPos.x - mDownPos.x,
mLastPos.y - mDownPos.y);
if (distance > mDragDistThreshold && mPassedSlop) {
- onStopGestureDetected();
+ mIsStopGesture = true;
}
}
break;
@@ -113,15 +114,14 @@
case ACTION_UP: {
if (mLastPos.y >= mDownPos.y && mPassedSlop) {
onStartGestureDetected();
+ } else if (mIsStopGesture) {
+ onStopGestureDetected();
}
-
- mPassedSlop = false;
- mState = STATE_INACTIVE;
+ clearState();
break;
}
case ACTION_CANCEL:
- mPassedSlop = false;
- mState = STATE_INACTIVE;
+ clearState();
break;
}
@@ -130,6 +130,12 @@
}
}
+ private void clearState() {
+ mPassedSlop = false;
+ mState = STATE_INACTIVE;
+ mIsStopGesture = false;
+ }
+
private void onStartGestureDetected() {
if (mDeviceState.isOneHandedModeEnabled()) {
if (!mDeviceState.isOneHandedModeActive()) {
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
index 498e561..aad70c4 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
@@ -18,7 +18,6 @@
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
-import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -80,9 +79,6 @@
ev.setEdgeFlags(flags | Utilities.EDGE_NAV_BAR);
}
ev.offsetLocation(-mLocationOnScreen[0], -mLocationOnScreen[1]);
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.PAUSE_NOT_DETECTED, "OverviewInputConsumer");
- }
boolean handled = mTarget.proxyTouchEvent(ev, mStartingInActivityBounds);
ev.offsetLocation(mLocationOnScreen[0], mLocationOnScreen[1]);
ev.setEdgeFlags(flags);
diff --git a/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialController.java b/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialController.java
index d54efc5..4c1a595 100644
--- a/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialController.java
@@ -46,7 +46,7 @@
@Nullable
@Override
Integer getActionButtonStringId() {
- return R.string.gesture_tutorial_action_button_label_done;
+ return null;
}
@Override
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialController.java b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
index 2198ade..0d5a110 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
@@ -25,8 +25,10 @@
import android.widget.TextView;
import androidx.annotation.CallSuper;
+import androidx.annotation.DrawableRes;
import androidx.annotation.Nullable;
+import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.views.ClipIconView;
import com.android.quickstep.interaction.EdgeBackGestureHandler.BackGestureAttemptCallback;
@@ -63,13 +65,13 @@
mTutorialType = tutorialType;
mContext = mTutorialFragment.getContext();
- View rootView = tutorialFragment.getRootView();
+ RootSandboxLayout rootView = tutorialFragment.getRootView();
mCloseButton = rootView.findViewById(R.id.gesture_tutorial_fragment_close_button);
mCloseButton.setOnClickListener(button -> mTutorialFragment.closeTutorial());
mTitleTextView = rootView.findViewById(R.id.gesture_tutorial_fragment_title_view);
mSubtitleTextView = rootView.findViewById(R.id.gesture_tutorial_fragment_subtitle_view);
mFeedbackView = rootView.findViewById(R.id.gesture_tutorial_fragment_feedback_view);
- mLauncherView = tutorialFragment.getLauncherView();
+ mLauncherView = getMockLauncherView();
mFakeIconView = rootView.findViewById(R.id.gesture_tutorial_fake_icon_view);
mFakeTaskView = rootView.findViewById(R.id.gesture_tutorial_fake_task_view);
mRippleView = rootView.findViewById(R.id.gesture_tutorial_ripple_view);
@@ -84,6 +86,15 @@
mHideFeedbackRunnable =
() -> mFeedbackView.animate().alpha(0).setDuration(FEEDBACK_ANIMATION_MS)
.withEndAction(this::showHandCoachingAnimation).start();
+
+ if (mLauncherView != null) {
+ rootView.addView(mLauncherView, 0);
+ }
+ if (mContext != null) {
+ rootView.setBackground(mContext.getDrawable(getMockWallpaperResId()));
+ mFakeTaskView.setBackground(mContext.getDrawable(getMockAppTaskThumbnailResId()));
+ mFakeIconView.setBackground(mContext.getDrawable(getMockAppIconResId()));
+ }
}
void setTutorialType(TutorialType tutorialType) {
@@ -110,6 +121,28 @@
return null;
}
+ @DrawableRes
+ protected int getMockAppTaskThumbnailResId() {
+ return R.drawable.default_sandbox_app_task_thumbnail;
+ }
+
+ @Nullable
+ public View getMockLauncherView() {
+ InvariantDeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(mContext);
+
+ return new SandboxLauncherRenderer(mContext, dp, true).getRenderedView();
+ }
+
+ @DrawableRes
+ public int getMockAppIconResId() {
+ return R.drawable.default_sandbox_app_icon;
+ }
+
+ @DrawableRes
+ public int getMockWallpaperResId() {
+ return R.drawable.default_sandbox_wallpaper;
+ }
+
void showFeedback(int resId) {
hideHandCoachingAnimation();
mFeedbackView.setText(resId);
@@ -167,10 +200,11 @@
if (isComplete()) {
hideHandCoachingAnimation();
- mLauncherView.setVisibility(View.INVISIBLE);
} else {
showHandCoachingAnimation();
- mLauncherView.setVisibility(View.VISIBLE);
+ }
+ if (mLauncherView != null) {
+ mLauncherView.setVisibility(isComplete() ? View.INVISIBLE : View.VISIBLE);
}
}
@@ -213,8 +247,7 @@
return mTutorialType == TutorialType.BACK_NAVIGATION_COMPLETE
|| mTutorialType == TutorialType.HOME_NAVIGATION_COMPLETE
|| mTutorialType == TutorialType.OVERVIEW_NAVIGATION_COMPLETE
- || mTutorialType == TutorialType.ASSISTANT_COMPLETE
- || mTutorialType == TutorialType.SANDBOX_MODE;
+ || mTutorialType == TutorialType.ASSISTANT_COMPLETE;
}
/** Denotes the type of the tutorial. */
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
index 608fe72..413387e 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
@@ -31,7 +31,6 @@
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
-import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.R;
import com.android.quickstep.interaction.TutorialController.TutorialType;
@@ -42,11 +41,10 @@
TutorialType mTutorialType;
@Nullable TutorialController mTutorialController = null;
- View mRootView;
+ RootSandboxLayout mRootView;
@Nullable TutorialHandAnimation mHandCoachingAnimation = null;
EdgeBackGestureHandler mEdgeBackGestureHandler;
NavBarGestureHandler mNavBarGestureHandler;
- private View mLauncherView;
public static TutorialFragment newInstance(TutorialType tutorialType) {
TutorialFragment fragment = getFragmentForTutorialType(tutorialType);
@@ -114,7 +112,8 @@
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
- mRootView = inflater.inflate(R.layout.gesture_tutorial_fragment, container, false);
+ mRootView = (RootSandboxLayout) inflater.inflate(
+ R.layout.gesture_tutorial_fragment, container, false);
mRootView.setOnApplyWindowInsetsListener((view, insets) -> {
Insets systemInsets = insets.getInsets(WindowInsets.Type.systemBars());
mEdgeBackGestureHandler.setInsets(systemInsets.left, systemInsets.right);
@@ -126,9 +125,6 @@
mHandCoachingAnimation =
new TutorialHandAnimation(getContext(), mRootView, handAnimationResId);
}
- InvariantDeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(getContext());
- mLauncherView = new SandboxLauncherRenderer(getContext(), dp, true).getRenderedView();
- ((ViewGroup) mRootView).addView(mLauncherView, 0);
return mRootView;
}
@@ -161,7 +157,7 @@
}
void onAttachedToWindow() {
- mEdgeBackGestureHandler.setViewGroupParent((ViewGroup) getRootView());
+ mEdgeBackGestureHandler.setViewGroupParent(getRootView());
}
void onDetachedFromWindow() {
@@ -186,14 +182,10 @@
super.onSaveInstanceState(savedInstanceState);
}
- View getRootView() {
+ RootSandboxLayout getRootView() {
return mRootView;
}
- View getLauncherView() {
- return mLauncherView;
- }
-
@Nullable TutorialHandAnimation getHandAnimation() {
return mHandCoachingAnimation;
}
diff --git a/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java b/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java
index 0bb0bbc..3157865 100644
--- a/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java
+++ b/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java
@@ -16,7 +16,13 @@
package com.android.quickstep.logging;
+import static com.android.launcher3.InvariantDeviceProfile.KEY_MIGRATION_SRC_HOTSEAT_COUNT;
import static com.android.launcher3.Utilities.getDevicePrefs;
+import static com.android.launcher3.Utilities.getPrefs;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_GRID_SIZE_2;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_GRID_SIZE_3;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_GRID_SIZE_4;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_GRID_SIZE_5;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOME_SCREEN_SUGGESTIONS_DISABLED;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOME_SCREEN_SUGGESTIONS_ENABLED;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NOTIFICATION_DOT_DISABLED;
@@ -34,7 +40,6 @@
import com.android.launcher3.AutoInstallsLayout;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
import com.android.launcher3.logging.InstanceIdSequence;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.logging.StatsLogManager.StatsLogger;
@@ -69,7 +74,7 @@
mLoggablePrefs = loadPrefKeys(context);
mNavMode = SysUINavigationMode.INSTANCE.get(context).addModeChangeListener(this);
- Utilities.getPrefs(context).registerOnSharedPreferenceChangeListener(this);
+ getPrefs(context).registerOnSharedPreferenceChangeListener(this);
getDevicePrefs(context).registerOnSharedPreferenceChangeListener(this);
SecureSettingsObserver dotsObserver =
@@ -125,7 +130,8 @@
@Override
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
- if (LAST_PREDICTION_ENABLED_STATE.equals(key) || mLoggablePrefs.containsKey(key)) {
+ if (LAST_PREDICTION_ENABLED_STATE.equals(key) || KEY_MIGRATION_SRC_HOTSEAT_COUNT.equals(key)
+ || mLoggablePrefs.containsKey(key)) {
dispatchUserEvent();
}
}
@@ -142,7 +148,28 @@
? LAUNCHER_HOME_SCREEN_SUGGESTIONS_ENABLED
: LAUNCHER_HOME_SCREEN_SUGGESTIONS_DISABLED);
- SharedPreferences prefs = Utilities.getPrefs(mContext);
+ SharedPreferences prefs = getPrefs(mContext);
+ StatsLogManager.LauncherEvent gridSizeChangedEvent = null;
+ switch (prefs.getInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT, -1)) {
+ case 5:
+ gridSizeChangedEvent = LAUNCHER_GRID_SIZE_5;
+ break;
+ case 4:
+ gridSizeChangedEvent = LAUNCHER_GRID_SIZE_4;
+ break;
+ case 3:
+ gridSizeChangedEvent = LAUNCHER_GRID_SIZE_3;
+ break;
+ case 2:
+ gridSizeChangedEvent = LAUNCHER_GRID_SIZE_2;
+ break;
+ default:
+ // Ignore illegal input.
+ break;
+ }
+ if (gridSizeChangedEvent != null) {
+ logger.log(gridSizeChangedEvent);
+ }
mLoggablePrefs.forEach((key, lp) -> logger.log(() ->
prefs.getBoolean(key, lp.defaultValue) ? lp.eventIdOn : lp.eventIdOff));
}
diff --git a/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java b/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
index da5f59e..8cde5f2 100644
--- a/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
+++ b/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
@@ -19,14 +19,12 @@
import android.content.Context;
import android.content.res.Resources;
-import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import com.android.launcher3.Alarm;
import com.android.launcher3.R;
import com.android.launcher3.compat.AccessibilityManagerCompat;
-import com.android.launcher3.testing.TestProtocol;
/**
* Given positions along x- or y-axis, tracks velocity and acceleration and determines when there is
@@ -87,9 +85,6 @@
mSpeedSlow = res.getDimension(R.dimen.motion_pause_detector_speed_slow);
mSpeedSomewhatFast = res.getDimension(R.dimen.motion_pause_detector_speed_somewhat_fast);
mSpeedFast = res.getDimension(R.dimen.motion_pause_detector_speed_fast);
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.PAUSE_NOT_DETECTED, "creating alarm");
- }
mForcePauseTimeout = new Alarm();
mForcePauseTimeout.setOnAlarmListener(alarm -> updatePaused(true /* isPaused */));
mMakePauseHarderToTrigger = makePauseHarderToTrigger;
@@ -126,9 +121,6 @@
* @param pointerIndex Index for the pointer being tracked in the motion event
*/
public void addPosition(MotionEvent ev, int pointerIndex) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.PAUSE_NOT_DETECTED, "setting alarm");
- }
mForcePauseTimeout.setAlarm(mMakePauseHarderToTrigger
? HARDER_TRIGGER_TIMEOUT
: FORCE_PAUSE_TIMEOUT);
@@ -176,9 +168,6 @@
}
private void updatePaused(boolean isPaused) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.PAUSE_NOT_DETECTED, "updatePaused: " + isPaused);
- }
if (mDisallowPause) {
isPaused = false;
}
@@ -207,9 +196,6 @@
setOnMotionPauseListener(null);
mIsPaused = mHasEverBeenPaused = false;
mSlowStartTime = 0;
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.PAUSE_NOT_DETECTED, "canceling alarm");
- }
mForcePauseTimeout.cancelAlarm();
}
diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
index e273aeb..facc99a 100644
--- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
+++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
@@ -519,6 +519,29 @@
}
}
+ /**
+ * Contrary to {@link #postDisplayRotation}.
+ */
+ public static void preDisplayRotation(@SurfaceRotation int displayRotation,
+ float screenWidth, float screenHeight, Matrix out) {
+ switch (displayRotation) {
+ case ROTATION_0:
+ return;
+ case ROTATION_90:
+ out.postRotate(90);
+ out.postTranslate(screenWidth, 0);
+ break;
+ case ROTATION_180:
+ out.postRotate(180);
+ out.postTranslate(screenHeight, screenWidth);
+ break;
+ case ROTATION_270:
+ out.postRotate(270);
+ out.postTranslate(0, screenHeight);
+ break;
+ }
+ }
+
@NonNull
@Override
public String toString() {
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
index 2f4bb8e..5a7f541 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -19,6 +19,7 @@
import static com.android.launcher3.states.RotationHelper.deltaRotation;
import static com.android.launcher3.touch.PagedOrientationHandler.MATRIX_POST_TRANSLATE;
import static com.android.quickstep.util.RecentsOrientedState.postDisplayRotation;
+import static com.android.quickstep.util.RecentsOrientedState.preDisplayRotation;
import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_MODE_FULLSCREEN;
import android.animation.TimeInterpolator;
@@ -80,6 +81,7 @@
private DeviceProfile mDp;
private final Matrix mMatrix = new Matrix();
+ private final Matrix mMatrixTmp = new Matrix();
private final Point mRunningTargetWindowPosition = new Point();
// Thumbnail view properties
@@ -211,7 +213,10 @@
*/
public RectF getCurrentRect() {
RectF result = getCurrentCropRect();
- mMatrix.mapRect(result);
+ mMatrixTmp.set(mMatrix);
+ preDisplayRotation(mOrientationState.getDisplayRotation(), mDp.widthPx, mDp.heightPx,
+ mMatrixTmp);
+ mMatrixTmp.mapRect(result);
return result;
}
diff --git a/quickstep/src/com/android/quickstep/views/LiveTileOverlay.java b/quickstep/src/com/android/quickstep/views/LiveTileOverlay.java
index f6eb0e2..747c3f2 100644
--- a/quickstep/src/com/android/quickstep/views/LiveTileOverlay.java
+++ b/quickstep/src/com/android/quickstep/views/LiveTileOverlay.java
@@ -1,5 +1,10 @@
package com.android.quickstep.views;
+import static android.view.Surface.ROTATION_0;
+import static android.view.Surface.ROTATION_180;
+import static android.view.Surface.ROTATION_270;
+import static android.view.Surface.ROTATION_90;
+
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.launcher3.anim.Interpolators.LINEAR;
@@ -19,6 +24,7 @@
import android.view.ViewOverlay;
import com.android.launcher3.anim.Interpolators;
+import com.android.quickstep.util.RecentsOrientedState.SurfaceRotation;
public class LiveTileOverlay extends Drawable {
@@ -43,6 +49,8 @@
private final RectF mCurrentRect = new RectF();
private final Rect mBoundsRect = new Rect();
+ private @SurfaceRotation int mRotation = ROTATION_0;
+
private float mCornerRadius;
private Drawable mIcon;
private Animator mIconAnimator;
@@ -69,6 +77,10 @@
mCurrentRect.set(left, top, right, bottom);
}
+ public void setRotation(@SurfaceRotation int rotation) {
+ mRotation = rotation;
+ }
+
public void setIcon(Drawable icon) {
mIcon = icon;
}
@@ -103,8 +115,35 @@
canvas.save();
float scale = Interpolators.clampToProgress(FAST_OUT_SLOW_IN, 0f,
1f).getInterpolation(mIconAnimationProgress);
- canvas.translate(mCurrentRect.centerX() - mIcon.getBounds().width() / 2 * scale,
- mCurrentRect.top - mIcon.getBounds().height() / 2 * scale);
+
+ int iconRadius = mIcon.getBounds().width() / 2;
+ float dx = 0;
+ float dy = 0;
+
+ switch (mRotation) {
+ case ROTATION_0:
+ dx = mCurrentRect.centerX() - iconRadius * scale;
+ dy = mCurrentRect.top - iconRadius * scale;
+ break;
+ case ROTATION_90:
+ dx = mCurrentRect.right - iconRadius * scale;
+ dy = mCurrentRect.centerY() - iconRadius * scale;
+ break;
+ case ROTATION_270:
+ dx = mCurrentRect.left - iconRadius * scale;
+ dy = mCurrentRect.centerY() - iconRadius * scale;
+ break;
+ case ROTATION_180:
+ dx = mCurrentRect.centerX() - iconRadius * scale;
+ dy = mCurrentRect.bottom - iconRadius * scale;
+ break;
+ }
+
+ int rotationDegrees = mRotation * 90;
+ if (mRotation == ROTATION_90 || mRotation == ROTATION_270) {
+ canvas.rotate(rotationDegrees, dx + iconRadius, dy + iconRadius);
+ }
+ canvas.translate(dx, dy);
canvas.scale(scale, scale);
mIcon.draw(canvas);
canvas.restore();
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 3230348..d94e623 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -36,6 +36,7 @@
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_ICON_TAP_OR_LONGPRESS;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_TAP;
+import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -250,13 +251,14 @@
* Builds proto for logging
*/
public WorkspaceItemInfo getItemInfo() {
- ComponentKey componentKey = TaskUtils.getLaunchComponentKeyForTask(getTask().key);
+ final Task task = getTask();
+ ComponentKey componentKey = TaskUtils.getLaunchComponentKeyForTask(task.key);
WorkspaceItemInfo stubInfo = new WorkspaceItemInfo();
stubInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_TASK;
stubInfo.container = LauncherSettings.Favorites.CONTAINER_TASKSWITCHER;
stubInfo.user = componentKey.user;
stubInfo.intent = new Intent().setComponent(componentKey.componentName);
- stubInfo.title = TaskUtils.getTitle(getContext(), getTask());
+ stubInfo.title = task.title;
stubInfo.screenId = getRecentsView().indexOfChild(this);
return stubInfo;
}
@@ -418,15 +420,21 @@
if (freezeTaskList) {
ActivityOptionsCompat.setFreezeRecentTasksList(opts);
}
- ActivityManagerWrapper.getInstance().startActivityFromRecentsAsync(mTask.key,
- opts, (success) -> {
- if (resultCallback != null && !success) {
- // If the call to start activity failed, then post the result
- // immediately, otherwise, wait for the animation start callback
- // from the activity options above
- resultCallbackHandler.post(() -> resultCallback.accept(false));
- }
- }, resultCallbackHandler);
+ UI_HELPER_EXECUTOR.execute(
+ () -> ActivityManagerWrapper.getInstance().startActivityFromRecentsAsync(
+ mTask.key,
+ opts,
+ (success) -> {
+ if (resultCallback != null && !success) {
+ // If the call to start activity failed, then post the
+ // result
+ // immediately, otherwise, wait for the animation start
+ // callback
+ // from the activity options above
+ resultCallbackHandler.post(
+ () -> resultCallback.accept(false));
+ }
+ }, resultCallbackHandler));
}
}
}
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
index c5863c1..cc97f4b 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
@@ -310,6 +310,10 @@
assertTrue("The second app we should have quick switched to is not running",
isTestActivityRunning(2));
}
+ background = getAndAssertBackground();
+ background.quickSwitchToPreviousAppSwipeLeft();
+ assertTrue("The 2nd app we should have quick switched to is not running",
+ isTestActivityRunning(3));
getAndAssertBackground();
}
diff --git a/res/values/config.xml b/res/values/config.xml
index 46b8c23..41d1a12 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -111,6 +111,7 @@
<!-- QSB IDs. DO not change -->
<item type="id" name="search_container_workspace" />
<item type="id" name="search_container_all_apps" />
+ <item type="id" name="search_container_hotseat" />
<!-- Recents -->
<item type="id" name="overview_panel"/>
diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java
index 0d90602..52f0a4a 100644
--- a/src/com/android/launcher3/BaseDraggingActivity.java
+++ b/src/com/android/launcher3/BaseDraggingActivity.java
@@ -42,7 +42,6 @@
import androidx.annotation.Nullable;
-import com.android.launcher3.Launcher.OnResumeCallback;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.logging.InstanceIdSequence;
@@ -108,20 +107,10 @@
private void updateTheme() {
if (mThemeRes != Themes.getActivityThemeRes(this)) {
- // Workaround (b/162812884): The system currently doesn't allow recreating an activity
- // when it is not resumed, in such a case defer recreation until it is possible
- if (hasBeenResumed()) {
- recreate();
- } else {
- addOnResumeCallback(this::recreate);
- }
+ recreate();
}
}
- protected void addOnResumeCallback(OnResumeCallback callback) {
- // To be overridden
- }
-
@Override
public void onActionModeStarted(ActionMode mode) {
super.onActionModeStarted(mode);
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index e4bdb39..4f4f2a7 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -27,6 +27,8 @@
import androidx.annotation.Nullable;
+import com.android.launcher3.config.FeatureFlags;
+
import java.util.function.Consumer;
/**
@@ -38,7 +40,8 @@
private boolean mHasVerticalHotseat;
private Workspace mWorkspace;
private boolean mSendTouchToWorkspace;
- @Nullable private Consumer<Boolean> mOnVisibilityAggregatedCallback;
+ @Nullable
+ private Consumer<Boolean> mOnVisibilityAggregatedCallback;
public Hotseat(Context context) {
this(context, null);
@@ -73,8 +76,9 @@
if (hasVerticalHotseat) {
setGridSize(1, idp.numHotseatIcons);
} else {
- setGridSize(idp.numHotseatIcons, 1);
+ setGridSize(idp.numHotseatIcons, FeatureFlags.ENABLE_DEVICE_SEARCH.get() ? 2 : 1);
}
+ showInlineQsb();
}
@Override
@@ -97,7 +101,11 @@
lp.height = grid.hotseatBarSizePx + insets.bottom;
}
Rect padding = grid.getHotseatLayoutPadding();
- setPadding(padding.left, padding.top, padding.right, padding.bottom);
+ int paddingBottom = padding.bottom;
+ if (FeatureFlags.ENABLE_DEVICE_SEARCH.get() && !grid.isVerticalBarLayout()) {
+ paddingBottom -= grid.hotseatBarBottomPaddingPx;
+ }
+ setPadding(padding.left, padding.top, padding.right, paddingBottom);
setLayoutParams(lp);
InsettableFrameLayout.dispatchInsets(this, insets);
@@ -148,4 +156,8 @@
public void setOnVisibilityAggregatedCallback(@Nullable Consumer<Boolean> callback) {
mOnVisibilityAggregatedCallback = callback;
}
+
+ protected void showInlineQsb() {
+ //Does nothing
+ }
}
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index ff53b5f..1d88e83 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -19,6 +19,7 @@
import static com.android.launcher3.Utilities.getDevicePrefs;
import static com.android.launcher3.Utilities.getPointString;
import static com.android.launcher3.config.FeatureFlags.APPLY_CONFIG_AT_RUNTIME;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_FOUR_COLUMNS;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.PackageManagerHelper.getPackageFilter;
@@ -215,6 +216,9 @@
}
public static String getCurrentGridName(Context context) {
+ if (ENABLE_FOUR_COLUMNS.get()) {
+ return ENABLE_FOUR_COLUMNS.key;
+ }
return Utilities.isGridOptionsEnabled(context)
? Utilities.getPrefs(context).getString(KEY_IDP_GRID_NAME, null) : null;
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 058eca8..e099d85 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -18,6 +18,7 @@
import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
+import static android.content.pm.ActivityInfo.CONFIG_UI_MODE;
import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_NO;
import static android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
@@ -221,6 +222,8 @@
static final boolean DEBUG_STRICT_MODE = false;
+ private static final boolean ENABLE_ACTIVITY_CROSSFADE = false;
+
private static final int REQUEST_CREATE_SHORTCUT = 1;
private static final int REQUEST_CREATE_APPWIDGET = 5;
@@ -958,8 +961,6 @@
DiscoveryBounce.showForHomeIfNeeded(this);
}
- protected void handlePendingActivityRequest() { }
-
private void logStopAndResume(boolean isResume) {
if (mPendingExecutor != null) return;
int pageIndex = mWorkspace.isOverlayShown() ? -1 : mWorkspace.getCurrentPage();
@@ -1050,7 +1051,7 @@
@Override
public void onStateSetEnd(LauncherState state) {
- super.onStateSetStart(state);
+ super.onStateSetEnd(state);
getAppWidgetHost().setResumed(state == LauncherState.NORMAL);
getWorkspace().setClipChildren(!state.hasFlag(FLAG_MULTI_PAGE));
@@ -1134,7 +1135,11 @@
int stateOrdinal = savedState.getInt(RUNTIME_STATE, NORMAL.ordinal);
LauncherState[] stateValues = LauncherState.values();
LauncherState state = stateValues[stateOrdinal];
- if (!state.shouldDisableRestore()) {
+
+ NonConfigInstance lastInstance = (NonConfigInstance) getLastNonConfigurationInstance();
+ boolean forceRestore = lastInstance != null
+ && (lastInstance.config.diff(mOldConfig) & CONFIG_UI_MODE) != 0;
+ if (forceRestore || !state.shouldDisableRestore()) {
mStateManager.goToState(state, false /* animated */);
}
@@ -1373,14 +1378,18 @@
@Override
public Object onRetainNonConfigurationInstance() {
+ NonConfigInstance instance = new NonConfigInstance();
+ instance.config = new Configuration(mOldConfig);
+
int width = mDragLayer.getWidth();
int height = mDragLayer.getHeight();
- if (width <= 0 || height <= 0) {
- return null;
+ // TODO: b/172467144 Remove hardcoded ENABLE_ACTIVITY_CROSSFADE.
+ if (ENABLE_ACTIVITY_CROSSFADE && width > 0 && height > 0) {
+ instance.snapshot =
+ BitmapRenderer.createHardwareBitmap(width, height, mDragLayer::draw);
}
-
- return BitmapRenderer.createHardwareBitmap(width, height, mDragLayer::draw);
+ return instance;
}
public AllAppsTransitionController getAllAppsController() {
@@ -1468,8 +1477,7 @@
if (!isInState(NORMAL)) {
// Only change state, if not already the same. This prevents cancelling any
// animations running as part of resume
- mStateManager.goToState(NORMAL, mStateManager.shouldAnimateStateChange(),
- this::handlePendingActivityRequest);
+ mStateManager.goToState(NORMAL, mStateManager.shouldAnimateStateChange());
}
// Reset the apps view
@@ -1974,7 +1982,6 @@
return result;
}
- @Override
public void addOnResumeCallback(OnResumeCallback callback) {
mOnResumeCallbacks.add(callback);
}
@@ -2340,9 +2347,7 @@
if (item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {
// Verify that we own the widget
if (appWidgetInfo == null) {
- FileLog.e(TAG, "Removing invalid widget: id=" + item.appWidgetId
- + ",title=" + item.title
- + ",providerName=" + item.providerName.toShortString());
+ FileLog.e(TAG, "Removing invalid widget: id=" + item.appWidgetId);
getModelWriter().deleteWidgetInfo(item, getAppWidgetHost());
return null;
}
@@ -2786,15 +2791,14 @@
* updates.
*/
private void crossFadeWithPreviousAppearance() {
- Bitmap previousAppearanceBitmap = (Bitmap) getLastNonConfigurationInstance();
+ NonConfigInstance lastInstance = (NonConfigInstance) getLastNonConfigurationInstance();
- if (previousAppearanceBitmap == null) {
+ if (lastInstance == null || lastInstance.snapshot == null) {
return;
}
ImageView crossFadeHelper = new ImageView(this);
-
- crossFadeHelper.setImageBitmap(previousAppearanceBitmap);
+ crossFadeHelper.setImageBitmap(lastInstance.snapshot);
crossFadeHelper.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
InsettableFrameLayout.LayoutParams layoutParams = new InsettableFrameLayout.LayoutParams(
@@ -2814,4 +2818,9 @@
.withEndAction(() -> getRootView().removeView(crossFadeHelper))
.start();
}
+
+ private static class NonConfigInstance {
+ public Configuration config;
+ public Bitmap snapshot;
+ }
}
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 6af248c..aeed16a 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -85,7 +85,6 @@
import java.util.Locale;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
-import java.util.stream.Collectors;
public class LauncherProvider extends ContentProvider {
private static final String TAG = "LauncherProvider";
@@ -932,11 +931,6 @@
final IntSet validWidgets = IntSet.wrap(LauncherDbUtils.queryIntArray(db,
Favorites.TABLE_NAME, Favorites.APPWIDGET_ID,
"itemType=" + Favorites.ITEM_TYPE_APPWIDGET, null, null));
- final String allWidgetIds = Arrays.stream(allWidgets).mapToObj(String::valueOf)
- .collect(Collectors.joining(","));
- final String validWidgetIds = validWidgets.getArray().toConcatString();
- FileLog.d(TAG, "All widget ids: " + allWidgetIds);
- FileLog.d(TAG, "Valid widget ids: " + validWidgetIds);
for (int widgetId : allWidgets) {
if (!validWidgets.contains(widgetId)) {
try {
diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java
index eba0ac9..79476fc 100644
--- a/src/com/android/launcher3/LauncherState.java
+++ b/src/com/android/launcher3/LauncherState.java
@@ -29,6 +29,7 @@
import android.content.Context;
import android.view.animation.Interpolator;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.statemanager.BaseState;
import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.states.HintState;
@@ -168,9 +169,9 @@
/**
* Returns an array of two elements.
- * The first specifies the scale for the overview
- * The second is the factor ([0, 1], 0 => center-screen; 1 => offscreen) by which overview
- * should be shifted horizontally.
+ * The first specifies the scale for the overview
+ * The second is the factor ([0, 1], 0 => center-screen; 1 => offscreen) by which overview
+ * should be shifted horizontally.
*/
public float[] getOverviewScaleAndOffset(Launcher launcher) {
return launcher.getNormalOverviewScaleAndOffset();
@@ -185,10 +186,12 @@
}
public int getVisibleElements(Launcher launcher) {
- if (launcher.getDeviceProfile().isVerticalBarLayout()) {
- return HOTSEAT_ICONS | VERTICAL_SWIPE_INDICATOR;
+ int flags = HOTSEAT_ICONS | VERTICAL_SWIPE_INDICATOR;
+ if (!FeatureFlags.ENABLE_DEVICE_SEARCH.get()
+ && !launcher.getDeviceProfile().isVerticalBarLayout()) {
+ flags |= HOTSEAT_SEARCH_BOX;
}
- return HOTSEAT_ICONS | HOTSEAT_SEARCH_BOX | VERTICAL_SWIPE_INDICATOR;
+ return flags;
}
/**
@@ -229,6 +232,7 @@
/**
* Returns the amount of blur and wallpaper zoom for this state with {@param isMultiWindowMode}.
+ *
* @see #getDepth(Context).
*/
public final float getDepth(Context context, boolean isMultiWindowMode) {
@@ -255,7 +259,7 @@
return new PageAlphaProvider(ACCEL_2) {
@Override
public float getPageAlpha(int pageIndex) {
- return pageIndex != centerPage ? 0 : 1f;
+ return pageIndex != centerPage ? 0 : 1f;
}
};
}
diff --git a/src/com/android/launcher3/ShortcutAndWidgetContainer.java b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
index 6326b7a..ee0c7bb 100644
--- a/src/com/android/launcher3/ShortcutAndWidgetContainer.java
+++ b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
@@ -36,7 +36,8 @@
// return an (x, y) value from helper functions. Do NOT use them to maintain other state.
private final int[] mTmpCellXY = new int[2];
- @ContainerType private final int mContainerType;
+ @ContainerType
+ private final int mContainerType;
private final WallpaperManager mWallpaperManager;
private int mCellWidth;
@@ -44,7 +45,7 @@
private int mCountX;
- private ActivityContext mActivity;
+ private final ActivityContext mActivity;
private boolean mInvertIfRtl = false;
public ShortcutAndWidgetContainer(Context context, @ContainerType int containerType) {
@@ -79,7 +80,7 @@
int count = getChildCount();
int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
- int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
+ int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(widthSpecSize, heightSpecSize);
for (int i = 0; i < count; i++) {
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 5d5e017..558c6a8 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -548,6 +548,7 @@
if (focusedItem instanceof SearchAdapterItem) {
SearchTarget searchTarget = ((SearchAdapterItem) focusedItem).getSearchTarget();
SearchEventTracker.INSTANCE.get(getContext()).quickSelect(searchTarget);
+ return true;
}
if (focusedItem.appInfo != null) {
ItemInfo itemInfo = focusedItem.appInfo;
diff --git a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
index 000ccbb..bd2f04d 100644
--- a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
+++ b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
@@ -47,6 +47,7 @@
import com.android.launcher3.allapps.AlphabeticalAppsList;
import com.android.launcher3.allapps.SearchUiManager;
import com.android.launcher3.anim.PropertySetter;
+import com.android.launcher3.config.FeatureFlags;
import java.util.ArrayList;
import java.util.List;
@@ -215,7 +216,8 @@
@Override
public float getScrollRangeDelta(Rect insets) {
- if (mLauncher.getDeviceProfile().isVerticalBarLayout()) {
+ if (mLauncher.getDeviceProfile().isVerticalBarLayout()
+ || FeatureFlags.ENABLE_DEVICE_SEARCH.get()) {
return 0;
} else {
return insets.bottom + insets.top;
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 8e6c2a7..883eab0 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -153,16 +153,17 @@
"ENABLE_OVERVIEW_CONTENT_PUSH", false, "Show Content Push button in Overview Actions");
public static final BooleanFlag ENABLE_DATABASE_RESTORE = getDebugFlag(
- "ENABLE_DATABASE_RESTORE", true,
+ "ENABLE_DATABASE_RESTORE", false,
"Enable database restore when new restore session is created");
public static final BooleanFlag ENABLE_SMARTSPACE_UNIVERSAL = getDebugFlag(
"ENABLE_SMARTSPACE_UNIVERSAL", false,
"Replace Smartspace with a version rendered by System UI.");
- public static final BooleanFlag ENABLE_SMARTSPACE_BLUECHIP = getDebugFlag(
- "ENABLE_SMARTSPACE_BLUECHIP", false,
- "Replace Smartspace with the Bluechip version. Ignored if ENABLE_SMARTSPACE_UNIVERSAL is enabled.");
+ public static final BooleanFlag ENABLE_SMARTSPACE_ENHANCED = getDebugFlag(
+ "ENABLE_SMARTSPACE_ENHANCED", false,
+ "Replace Smartspace with the enhanced version. "
+ + "Ignored if ENABLE_SMARTSPACE_UNIVERSAL is enabled.");
public static final BooleanFlag ENABLE_SYSTEM_VELOCITY_PROVIDER = getDebugFlag(
"ENABLE_SYSTEM_VELOCITY_PROVIDER", true,
@@ -189,6 +190,10 @@
"EXPANDED_SMARTSPACE", false, "Expands smartspace height to two rows. "
+ "Any apps occupying the first row will be removed from workspace.");
+ public static final BooleanFlag ENABLE_FOUR_COLUMNS = new DeviceFlag(
+ "ENABLE_FOUR_COLUMNS", false, "Uses 4 columns in launcher grid."
+ + "Warning: This will permanently alter your home screen items and is not reversible.");
+
public static void initialize(Context context) {
synchronized (sDebugFlags) {
for (DebugFlag flag : sDebugFlags) {
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index 0b445bc..2066cd3 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -332,6 +332,18 @@
@UiEvent(doc = "Notification dismissed by swiping right.")
LAUNCHER_NOTIFICATION_DISMISSED(652),
+
+ @UiEvent(doc = "Current grid size is changed to 5.")
+ LAUNCHER_GRID_SIZE_5(662),
+
+ @UiEvent(doc = "Current grid size is changed to 4.")
+ LAUNCHER_GRID_SIZE_4(663),
+
+ @UiEvent(doc = "Current grid size is changed to 3.")
+ LAUNCHER_GRID_SIZE_3(664),
+
+ @UiEvent(doc = "Current grid size is changed to 2.")
+ LAUNCHER_GRID_SIZE_2(665),
;
// ADD MORE
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index 80a684d..b108788 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -745,11 +745,7 @@
+ "span=" + appWidgetInfo.spanX + "x"
+ appWidgetInfo.spanY + " minSpan="
+ widgetProviderInfo.minSpanX + "x"
- + widgetProviderInfo.minSpanY
- + ", appWidgetInfo.provider="
- + appWidgetInfo.providerName.toShortString()
- + ", widgetProviderInfo.provider="
- + widgetProviderInfo.provider.toShortString());
+ + widgetProviderInfo.minSpanY);
continue;
}
if (!c.isOnWorkspaceOrHotseat()) {
diff --git a/src/com/android/launcher3/statemanager/StatefulActivity.java b/src/com/android/launcher3/statemanager/StatefulActivity.java
index dbe5f42..601e117 100644
--- a/src/com/android/launcher3/statemanager/StatefulActivity.java
+++ b/src/com/android/launcher3/statemanager/StatefulActivity.java
@@ -121,7 +121,9 @@
final int origDragLayerChildCount = dragLayer.getChildCount();
super.onStop();
- getStateManager().moveToRestState();
+ if (!isChangingConfigurations()) {
+ getStateManager().moveToRestState();
+ }
// Workaround for b/78520668, explicitly trim memory once UI is hidden
onTrimMemory(TRIM_MEMORY_UI_HIDDEN);
diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java
index b2d0081..218172b 100644
--- a/src/com/android/launcher3/testing/TestProtocol.java
+++ b/src/com/android/launcher3/testing/TestProtocol.java
@@ -103,7 +103,6 @@
public static final String REQUEST_MOCK_SENSOR_ROTATION = "mock-sensor-rotation";
public static final String PERMANENT_DIAG_TAG = "TaplTarget";
- public static final String PAUSE_NOT_DETECTED = "b/139891609";
public static final String OVERIEW_NOT_ALLAPPS = "b/156095088";
public static final String NO_SWIPE_TO_HOME = "b/158017601";
public static final String WORK_PROFILE_REMOVED = "b/159671700";
diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
index a9d0e61..23baaf0 100644
--- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
+++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
@@ -172,9 +172,6 @@
@Override
public final boolean onControllerTouchEvent(MotionEvent ev) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.PAUSE_NOT_DETECTED, "onControllerTouchEvent");
- }
return mDetector.onTouchEvent(ev);
}
@@ -396,6 +393,12 @@
@Override
public void onDragEnd(float velocity) {
+ if (mCurrentAnimation == null) {
+ // Unlikely, but we may have been canceled just before onDragEnd(). We assume whoever
+ // canceled us will handle a new state transition to clean up.
+ return;
+ }
+
boolean fling = mDetector.isFling(velocity);
boolean blockedFling = fling && mFlingBlockCheck.isBlocked();
diff --git a/src/com/android/launcher3/touch/BaseSwipeDetector.java b/src/com/android/launcher3/touch/BaseSwipeDetector.java
index 01b33d8..1276ece 100644
--- a/src/com/android/launcher3/touch/BaseSwipeDetector.java
+++ b/src/com/android/launcher3/touch/BaseSwipeDetector.java
@@ -26,8 +26,6 @@
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
-import com.android.launcher3.testing.TestProtocol;
-
import java.util.LinkedList;
import java.util.Queue;
@@ -175,9 +173,6 @@
if (mState != ScrollState.DRAGGING && shouldScrollStart(mDisplacement)) {
setState(ScrollState.DRAGGING);
}
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.PAUSE_NOT_DETECTED, "before report dragging");
- }
if (mState == ScrollState.DRAGGING) {
reportDragging(ev);
}
diff --git a/src/com/android/launcher3/touch/SingleAxisSwipeDetector.java b/src/com/android/launcher3/touch/SingleAxisSwipeDetector.java
index ddb4b0f..8c3c115 100644
--- a/src/com/android/launcher3/touch/SingleAxisSwipeDetector.java
+++ b/src/com/android/launcher3/touch/SingleAxisSwipeDetector.java
@@ -17,7 +17,6 @@
import android.content.Context;
import android.graphics.PointF;
-import android.util.Log;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
@@ -25,7 +24,6 @@
import androidx.annotation.VisibleForTesting;
import com.android.launcher3.Utilities;
-import com.android.launcher3.testing.TestProtocol;
/**
* One dimensional scroll/drag/swipe gesture detector (either HORIZONTAL or VERTICAL).
@@ -115,11 +113,6 @@
super(config, isRtl);
mListener = l;
mDir = dir;
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.PAUSE_NOT_DETECTED, "SingleAxisSwipeDetector.ctor "
- + l.getClass().getSimpleName()
- + " @ " + android.util.Log.getStackTraceString(new Throwable()));
- }
}
public void setDetectableScrollConditions(int scrollDirectionFlags, boolean ignoreSlop) {
@@ -167,10 +160,6 @@
@Override
protected void reportDraggingInternal(PointF displacement, MotionEvent event) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.PAUSE_NOT_DETECTED, "SingleAxisSwipeDetector "
- + mListener.getClass().getSimpleName());
- }
mListener.onDrag(mDir.extractDirection(displacement),
mDir.extractOrthogonalDirection(displacement), event);
}
diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java
index 2be827b..5464dd8 100644
--- a/src/com/android/launcher3/views/BaseDragLayer.java
+++ b/src/com/android/launcher3/views/BaseDragLayer.java
@@ -33,7 +33,6 @@
import android.graphics.RectF;
import android.os.Build;
import android.util.AttributeSet;
-import android.util.Log;
import android.util.Property;
import android.view.MotionEvent;
import android.view.View;
@@ -49,7 +48,6 @@
import com.android.launcher3.InsettableFrameLayout;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
-import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
import com.android.launcher3.util.SimpleBroadcastReceiver;
@@ -191,12 +189,6 @@
}
private TouchController findControllerToHandleTouch(MotionEvent ev) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.PAUSE_NOT_DETECTED, "findControllerToHandleTouch ev=" + ev
- + ", isEventInLauncher=" + isEventInLauncher(ev)
- + ", topOpenView=" + AbstractFloatingView.getTopOpenView(mActivity));
- }
-
AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mActivity);
if (topView != null
&& (isEventInLauncher(ev) || topView.canInterceptEventsInSystemGestureRegion())
diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java
index d9a14e9..1857c5a 100644
--- a/src/com/android/launcher3/views/FloatingIconView.java
+++ b/src/com/android/launcher3/views/FloatingIconView.java
@@ -55,7 +55,6 @@
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.popup.SystemShortcut;
import com.android.launcher3.shortcuts.DeepShortcutView;
-import com.android.launcher3.testing.TestProtocol;
/**
* A view that is created to look like another view with the purpose of creating fluid animations.
@@ -534,11 +533,6 @@
view.setVisibility(INVISIBLE);
parent.addView(view);
dragLayer.addView(view.mListenerView);
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.PAUSE_NOT_DETECTED, "getFloatingIconView. listenerView "
- + "added to dragLayer. listenerView=" + view.mListenerView + ", fiv=" + view,
- new Exception());
- }
view.mListenerView.setListener(view::fastFinish);
view.mEndRunnable = () -> {
@@ -578,10 +572,6 @@
private void finish(DragLayer dragLayer) {
((ViewGroup) dragLayer.getParent()).removeView(this);
dragLayer.removeView(mListenerView);
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.PAUSE_NOT_DETECTED, "listenerView removed from dragLayer. "
- + "listenerView=" + mListenerView + ", fiv=" + this, new Exception());
- }
recycle();
mLauncher.getViewCache().recycleView(R.layout.floating_icon_view, this);
}
diff --git a/src/com/android/launcher3/views/ListenerView.java b/src/com/android/launcher3/views/ListenerView.java
index 6e3f0ce..b2df0ee 100644
--- a/src/com/android/launcher3/views/ListenerView.java
+++ b/src/com/android/launcher3/views/ListenerView.java
@@ -17,13 +17,11 @@
import android.content.Context;
import android.util.AttributeSet;
-import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import com.android.launcher3.AbstractFloatingView;
-import com.android.launcher3.testing.TestProtocol;
/**
* An invisible AbstractFloatingView that can run a callback when it is being closed.
@@ -38,20 +36,12 @@
}
public void setListener(Runnable listener) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.PAUSE_NOT_DETECTED, "ListenerView setListener lv=" + this
- + ", listener=" + listener, new Exception());
- }
mCloseListener = listener;
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.PAUSE_NOT_DETECTED, "ListenerView onAttachedToWindow lv=" + this,
- new Exception());
- }
mIsOpen = true;
}
@@ -59,19 +49,10 @@
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
mIsOpen = false;
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.PAUSE_NOT_DETECTED, "ListenerView onDetachedFromView lv=" + this,
- new Exception());
- }
}
@Override
protected void handleClose(boolean animate) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.PAUSE_NOT_DETECTED, "ListenerView handeClose lv=" + this
- + ", mIsOpen=" + mIsOpen + ", mCloseListener=" + mCloseListener
- + ", getParent()=" + getParent(), new Exception());
- }
if (mIsOpen) {
if (mCloseListener != null) {
mCloseListener.run();
@@ -91,10 +72,6 @@
@Override
public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.PAUSE_NOT_DETECTED, "ListenerView touchEvent lv=" + this
- + ", ev=" + ev, new Exception());
- }
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
handleClose(false);
}
diff --git a/src/com/android/launcher3/views/ThumbnailSearchResultView.java b/src/com/android/launcher3/views/ThumbnailSearchResultView.java
index f213f22..573d48f 100644
--- a/src/com/android/launcher3/views/ThumbnailSearchResultView.java
+++ b/src/com/android/launcher3/views/ThumbnailSearchResultView.java
@@ -88,9 +88,15 @@
bitmap = ((BitmapDrawable) target.getRemoteAction().getIcon()
.loadDrawable(getContext())).getBitmap();
// crop
- bitmap = Bitmap.createBitmap(bitmap, 0,
- bitmap.getHeight() / 2 - bitmap.getWidth() / 2,
- bitmap.getWidth(), bitmap.getWidth());
+ if (bitmap.getWidth() < bitmap.getHeight()) {
+ bitmap = Bitmap.createBitmap(bitmap, 0,
+ bitmap.getHeight() / 2 - bitmap.getWidth() / 2,
+ bitmap.getWidth(), bitmap.getWidth());
+ } else {
+ bitmap = Bitmap.createBitmap(bitmap, bitmap.getWidth() / 2 - bitmap.getHeight() / 2,
+ 0,
+ bitmap.getHeight(), bitmap.getHeight());
+ }
setTag(itemInfo);
} else {
bitmap = (Bitmap) target.getExtras().getParcelable("bitmap");
diff --git a/src/com/android/launcher3/views/WorkEduView.java b/src/com/android/launcher3/views/WorkEduView.java
index d6737db..03d3026 100644
--- a/src/com/android/launcher3/views/WorkEduView.java
+++ b/src/com/android/launcher3/views/WorkEduView.java
@@ -60,7 +60,6 @@
private View mViewWrapper;
private Button mProceedButton;
private TextView mContentText;
- private AllAppsPagedView mAllAppsPagedView;
private int mNextWorkEduStep = WORK_EDU_PERSONAL_APPS;
@@ -101,13 +100,10 @@
// make sure layout does not shrink when we change the text
mContentText.post(() -> mContentText.setMinLines(mContentText.getLineCount()));
- if (mLauncher.getAppsView().getContentView() instanceof AllAppsPagedView) {
- mAllAppsPagedView = (AllAppsPagedView) mLauncher.getAppsView().getContentView();
- }
mProceedButton.setOnClickListener(view -> {
- if (mAllAppsPagedView != null) {
- mAllAppsPagedView.snapToPage(AllAppsContainerView.AdapterHolder.WORK);
+ if (getAllAppsPagedView() != null) {
+ getAllAppsPagedView().snapToPage(AllAppsContainerView.AdapterHolder.WORK);
}
goToWorkTab(true);
});
@@ -155,8 +151,8 @@
}
private void goToFirstPage() {
- if (mAllAppsPagedView != null) {
- mAllAppsPagedView.snapToPageImmediately(AllAppsContainerView.AdapterHolder.MAIN);
+ if (getAllAppsPagedView() != null) {
+ getAllAppsPagedView().snapToPageImmediately(AllAppsContainerView.AdapterHolder.MAIN);
}
}
@@ -171,6 +167,11 @@
mOpenCloseAnimator.start();
}
+ private AllAppsPagedView getAllAppsPagedView() {
+ View v = mLauncher.getAppsView().getContentView();
+ return (v instanceof AllAppsPagedView) ? (AllAppsPagedView) v : null;
+ }
+
/**
* Checks if user has not seen onboarding UI yet and shows it when user navigates to all apps
*/
diff --git a/tests/AndroidManifest-common.xml b/tests/AndroidManifest-common.xml
index bc6356f..f243f27 100644
--- a/tests/AndroidManifest-common.xml
+++ b/tests/AndroidManifest-common.xml
@@ -98,7 +98,7 @@
<activity
android:name="com.android.launcher3.testcomponent.TestLauncherActivity"
android:clearTaskOnLaunch="true"
- android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize|uiMode"
+ android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize"
android:enabled="false"
android:label="Test launcher"
android:launchMode="singleTask"
diff --git a/tests/src/com/android/launcher3/ui/WorkTabTest.java b/tests/src/com/android/launcher3/ui/WorkTabTest.java
index 1e1cf04..ac0d355 100644
--- a/tests/src/com/android/launcher3/ui/WorkTabTest.java
+++ b/tests/src/com/android/launcher3/ui/WorkTabTest.java
@@ -82,6 +82,7 @@
mDevice.pressHome();
waitForLauncherCondition("Launcher didn't start", Objects::nonNull);
executeOnLauncher(launcher -> launcher.getStateManager().goToState(ALL_APPS));
+ waitForState("Launcher internal state didn't switch to All Apps", () -> ALL_APPS);
waitForLauncherCondition("Personal tab is missing",
launcher -> launcher.getAppsView().isPersonalTabVisible(), 60000);
waitForLauncherCondition("Work tab is missing",
@@ -180,6 +181,10 @@
// open work tab
executeOnLauncher(launcher -> launcher.getStateManager().goToState(ALL_APPS));
waitForState("Launcher did not switch to all apps", () -> ALL_APPS);
+ waitForLauncherCondition("Work tab not setup",
+ launcher -> launcher.getAppsView().getContentView() instanceof AllAppsPagedView,
+ 60000);
+
executeOnLauncher(launcher -> {
AllAppsPagedView pagedView = (AllAppsPagedView) launcher.getAppsView().getContentView();
pagedView.setCurrentPage(WORK_PAGE);
@@ -199,7 +204,7 @@
DragLayer dragLayer = l.getDragLayer();
return dragLayer.getChildCount() > 0 && dragLayer.getChildAt(
dragLayer.getChildCount() - 1) instanceof WorkEduView;
- });
+ }, 6000);
return getFromLauncher(launcher -> (WorkEduView) launcher.getDragLayer().getChildAt(
launcher.getDragLayer().getChildCount() - 1));
}
diff --git a/tests/tapl/com/android/launcher3/tapl/Background.java b/tests/tapl/com/android/launcher3/tapl/Background.java
index 153b3ce..d317783 100644
--- a/tests/tapl/com/android/launcher3/tapl/Background.java
+++ b/tests/tapl/com/android/launcher3/tapl/Background.java
@@ -144,14 +144,25 @@
private void expectSwitchToOverviewEvents() {
}
- /**
- * Swipes right or double presses the square button to switch to the previous app.
- */
@NonNull
public Background quickSwitchToPreviousApp() {
+ boolean toRight = true;
+ quickSwitch(toRight);
+ return new Background(mLauncher);
+ }
+
+ @NonNull
+ public Background quickSwitchToPreviousAppSwipeLeft() {
+ boolean toRight = false;
+ quickSwitch(toRight);
+ return new Background(mLauncher);
+ }
+
+ @NonNull
+ private void quickSwitch(boolean toRight) {
try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
- LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "want to quick switch to the previous app")) {
+ LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "want to quick switch to the previous app")) {
verifyActiveContainer();
final boolean launcherWasVisible = mLauncher.isLauncherVisible();
boolean transposeInLandscape = false;
@@ -164,19 +175,36 @@
final int startY;
final int endX;
final int endY;
- if (mLauncher.getDevice().isNaturalOrientation() || !transposeInLandscape) {
- // Swipe from the bottom left to the bottom right of the screen.
- startX = 0;
- startY = getSwipeStartY();
- endX = mLauncher.getDevice().getDisplayWidth();
- endY = startY;
+ if (toRight) {
+ if (mLauncher.getDevice().isNaturalOrientation() || !transposeInLandscape) {
+ // Swipe from the bottom left to the bottom right of the screen.
+ startX = 0;
+ startY = getSwipeStartY();
+ endX = mLauncher.getDevice().getDisplayWidth();
+ endY = startY;
+ } else {
+ // Swipe from the bottom right to the top right of the screen.
+ startX = getSwipeStartX();
+ startY = mLauncher.getRealDisplaySize().y - 1;
+ endX = startX;
+ endY = 0;
+ }
} else {
- // Swipe from the bottom right to the top right of the screen.
- startX = getSwipeStartX();
- startY = mLauncher.getRealDisplaySize().y - 1;
- endX = startX;
- endY = 0;
+ if (mLauncher.getDevice().isNaturalOrientation() || !transposeInLandscape) {
+ // Swipe from the bottom right to the bottom left of the screen.
+ startX = mLauncher.getDevice().getDisplayWidth();
+ startY = getSwipeStartY();
+ endX = 0;
+ endY = startY;
+ } else {
+ // Swipe from the bottom left to the top left of the screen.
+ startX = getSwipeStartX();
+ startY = 0;
+ endX = startX;
+ endY = mLauncher.getRealDisplaySize().y - 1;
+ }
}
+
final boolean isZeroButton = mLauncher.getNavigationModel()
== LauncherInstrumentation.NavigationModel.ZERO_BUTTON;
LauncherInstrumentation.GestureScope gestureScope =
@@ -205,7 +233,7 @@
break;
}
mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, TASK_START_EVENT);
- return new Background(mLauncher);
+ return;
}
}
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 22833ec..3c89cfd 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -105,6 +105,7 @@
static final Pattern EVENT_TOUCH_DOWN_TIS = getTouchEventPatternTIS("ACTION_DOWN");
static final Pattern EVENT_TOUCH_UP_TIS = getTouchEventPatternTIS("ACTION_UP");
private final String mLauncherPackage;
+ private final boolean mIsLauncher3;
// Types for launcher containers that the user is interacting with. "Background" is a
// pseudo-container corresponding to inactive launcher covered by another app.
@@ -205,6 +206,7 @@
public LauncherInstrumentation(Instrumentation instrumentation) {
mInstrumentation = instrumentation;
mDevice = UiDevice.getInstance(instrumentation);
+ mIsLauncher3 = "com.android.launcher3".equals(getLauncherPackageName());
// Launcher should run in test harness so that custom accessibility protocol between
// Launcher and TAPL is enabled. In-process tests enable this protocol with a direct call
@@ -1396,7 +1398,7 @@
}
boolean isLauncher3() {
- return "com.android.launcher3".equals(getLauncherPackageName());
+ return mIsLauncher3;
}
void expectEvent(String sequence, Pattern expected) {