From 0b3b2921c3f0883f2dc924f9ca42f395d8c4f68d Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Mon, 26 Jul 2021 10:40:56 -1000 Subject: [PATCH 01/66] Don't recreate touch controllers when ending gesture Test: swipe up to overview from an app and swipe up to dismiss it during the transition Bug: 189700453 Change-Id: I303696f90dbb236ea93e06d94a3c92d783850fa4 (cherry picked from commit 0e9ecaeea8873b576320a0240757e4d0034cdcbb) --- quickstep/src/com/android/quickstep/views/RecentsView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index ce79125be1..fa4d6a1003 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -1775,7 +1775,7 @@ public abstract class RecentsView Date: Wed, 9 Jun 2021 16:34:45 -0400 Subject: [PATCH 02/66] Update preferences to Material Next styling There should be enough free space to merge this change into S V2. Test: Settings root, all apps, and about have new style on S Bug: 187732263 Fix: 188254205, 188012913 Change-Id: I346bbf819f3fe1eb13b47125b53c15baab11e439 Merged-In: I346bbf819f3fe1eb13b47125b53c15baab11e439 --- Android.bp | 1 + AndroidManifest-common.xml | 2 +- .../home_settings_switch_thumb_color.xml | 27 ++++++ .../home_settings_switch_track_color.xml | 28 ++++++ .../home_settings_switch_thumb.xml | 29 ++++++ .../home_settings_switch_track.xml | 26 +++++ res/layout-v31/settings_activity.xml | 69 ++++++++++++++ res/values-night-v31/colors.xml | 27 ++++++ res/values-v31/colors.xml | 10 ++ res/values-v31/config.xml | 20 ++++ res/values-v31/styles.xml | 95 +++++++++++++++++++ res/values/styles.xml | 10 +- 12 files changed, 338 insertions(+), 6 deletions(-) create mode 100644 res/color-v31/home_settings_switch_thumb_color.xml create mode 100644 res/color-v31/home_settings_switch_track_color.xml create mode 100644 res/drawable-v31/home_settings_switch_thumb.xml create mode 100644 res/drawable-v31/home_settings_switch_track.xml create mode 100644 res/layout-v31/settings_activity.xml create mode 100644 res/values-night-v31/colors.xml create mode 100644 res/values-v31/config.xml create mode 100644 res/values-v31/styles.xml diff --git a/Android.bp b/Android.bp index 1b6ffe42b7..45d022f4fd 100644 --- a/Android.bp +++ b/Android.bp @@ -112,6 +112,7 @@ android_library { "androidx.preference_preference", "androidx.slice_slice-view", "androidx.cardview_cardview", + "com.google.android.material_material", "iconloader_base", ], manifest: "AndroidManifest-common.xml", diff --git a/AndroidManifest-common.xml b/AndroidManifest-common.xml index d725a16f80..4eecf29d67 100644 --- a/AndroidManifest-common.xml +++ b/AndroidManifest-common.xml @@ -144,7 +144,7 @@ diff --git a/res/color-v31/home_settings_switch_thumb_color.xml b/res/color-v31/home_settings_switch_thumb_color.xml new file mode 100644 index 0000000000..91d3d9b5e4 --- /dev/null +++ b/res/color-v31/home_settings_switch_thumb_color.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + diff --git a/res/color-v31/home_settings_switch_track_color.xml b/res/color-v31/home_settings_switch_track_color.xml new file mode 100644 index 0000000000..50784f527d --- /dev/null +++ b/res/color-v31/home_settings_switch_track_color.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + diff --git a/res/drawable-v31/home_settings_switch_thumb.xml b/res/drawable-v31/home_settings_switch_thumb.xml new file mode 100644 index 0000000000..260d5ea35f --- /dev/null +++ b/res/drawable-v31/home_settings_switch_thumb.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/res/drawable-v31/home_settings_switch_track.xml b/res/drawable-v31/home_settings_switch_track.xml new file mode 100644 index 0000000000..502a3007a9 --- /dev/null +++ b/res/drawable-v31/home_settings_switch_track.xml @@ -0,0 +1,26 @@ + + + + + + + + \ No newline at end of file diff --git a/res/layout-v31/settings_activity.xml b/res/layout-v31/settings_activity.xml new file mode 100644 index 0000000000..59e14f22dd --- /dev/null +++ b/res/layout-v31/settings_activity.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/values-night-v31/colors.xml b/res/values-night-v31/colors.xml new file mode 100644 index 0000000000..2c1bc90074 --- /dev/null +++ b/res/values-night-v31/colors.xml @@ -0,0 +1,27 @@ + + + + @android:color/system_accent1_100 + @android:color/system_neutral1_700 + @android:color/system_neutral1_900 + + @android:color/system_neutral2_300 + @android:color/system_accent2_700 + @android:color/system_neutral1_700 + \ No newline at end of file diff --git a/res/values-v31/colors.xml b/res/values-v31/colors.xml index d73ee57080..c2ebeffe66 100644 --- a/res/values-v31/colors.xml +++ b/res/values-v31/colors.xml @@ -42,6 +42,16 @@ @android:color/system_accent2_50 + @android:color/system_accent1_600 + @android:color/system_neutral1_100 + @android:color/system_neutral1_50 + + @android:color/system_accent1_100 + @android:color/system_accent2_100 + @android:color/system_neutral2_100 + @android:color/system_accent1_600 + @android:color/system_neutral2_600 + @android:color/system_accent1_100 @android:color/system_accent2_600 diff --git a/res/values-v31/config.xml b/res/values-v31/config.xml new file mode 100644 index 0000000000..afb9e6d9e8 --- /dev/null +++ b/res/values-v31/config.xml @@ -0,0 +1,20 @@ + + + + false + false + \ No newline at end of file diff --git a/res/values-v31/styles.xml b/res/values-v31/styles.xml new file mode 100644 index 0000000000..0d2fce0307 --- /dev/null +++ b/res/values-v31/styles.xml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/values/styles.xml b/res/values/styles.xml index d30b80c813..e4a245a5c2 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -147,18 +147,18 @@ - - From 931bc2a38e88e3006334a3ab11daeec81d214a0f Mon Sep 17 00:00:00 2001 From: Thales Lima Date: Wed, 28 Jul 2021 12:09:16 +0100 Subject: [PATCH 03/66] navigation: don't run gesture animation if gestures are not enabled Makes the animation when using 3 button navigation be closer to what we have in non fallback mode, also fixing the problem when fallback recents just started and don't have any views. Fix 194487871 Test: manual with gestures, 2 button and 3 button nav Change-Id: If3925d6bef1d14f51b86169d06607786972f5f1f (cherry picked from commit 8d49c4bb296d9870825e3dc01b7880dd5236b98c) --- quickstep/src/com/android/quickstep/FallbackSwipeHandler.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java index fd44e023a7..e2f198c05d 100644 --- a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java +++ b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java @@ -173,7 +173,9 @@ public class FallbackSwipeHandler extends @Override protected void notifyGestureAnimationStartToRecents() { if (mRunningOverHome) { - mRecentsView.onGestureAnimationStartOnHome(mGestureState.getRunningTask()); + if (SysUINavigationMode.getMode(mContext).hasGestures) { + mRecentsView.onGestureAnimationStartOnHome(mGestureState.getRunningTask()); + } } else { super.notifyGestureAnimationStartToRecents(); } From 57e0866fdd76bbb9213d9efc0a8a0346ae1573c2 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Fri, 6 Aug 2021 11:52:10 -0700 Subject: [PATCH 04/66] Fixing ModelPreload cancelling existing load When a model preload call was made while the loader task is running (eg: on enabling/disabling icon theme, Launcher reloads and then launcher preview start a model-preload), it would cancel the original loader and then start a new loader with empty callbacks. So the model indeed get loaded, but the original callbacks never got notified of it. > Instead we only start preload if an existing task is not running. > Also when preloading, we use existing callbacks, instead of using empty callbacks Bug: 193851085 Bug: 195155924 Test: Verified repro steps Change-Id: I0a96310be8489756f364aa2a12e4345e1418733d --- src/com/android/launcher3/LauncherModel.java | 33 ++++---- .../graphics/PreviewSurfaceRenderer.java | 18 ++--- .../android/launcher3/model/ModelPreload.java | 76 ------------------- 3 files changed, 22 insertions(+), 105 deletions(-) delete mode 100644 src/com/android/launcher3/model/ModelPreload.java diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java index eef3980f96..545f4c3999 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -72,6 +72,7 @@ import java.util.HashSet; import java.util.List; import java.util.concurrent.CancellationException; import java.util.concurrent.Executor; +import java.util.function.Consumer; import java.util.function.Supplier; /** @@ -376,7 +377,13 @@ public class LauncherModel extends LauncherApps.Callback implements InstallSessi loaderResults.bindWidgets(); return true; } else { - startLoaderForResults(loaderResults); + stopLoader(); + mLoaderTask = new LoaderTask( + mApp, mBgAllAppsList, mBgDataModel, mModelDelegate, loaderResults); + + // Always post the loader task, instead of running directly + // (even on same thread) so that we exit any nested synchronized blocks + MODEL_EXECUTOR.post(mLoaderTask); } } } @@ -399,25 +406,17 @@ public class LauncherModel extends LauncherApps.Callback implements InstallSessi } } - public void startLoaderForResults(LoaderResults results) { + /** + * Loads the model if not loaded + * @param callback called with the data model upon successful load or null on model thread. + */ + public void loadAsync(Consumer callback) { synchronized (mLock) { - stopLoader(); - mLoaderTask = new LoaderTask( - mApp, mBgAllAppsList, mBgDataModel, mModelDelegate, results); - - // Always post the loader task, instead of running directly (even on same thread) so - // that we exit any nested synchronized blocks - MODEL_EXECUTOR.post(mLoaderTask); - } - } - - public void startLoaderForResultsIfNotLoaded(LoaderResults results) { - synchronized (mLock) { - if (!isModelLoaded()) { - Log.d(TAG, "Workspace not loaded, loading now"); - startLoaderForResults(results); + if (!mModelLoaded && !mIsLoaderTaskRunning) { + startLoader(); } } + MODEL_EXECUTOR.post(() -> callback.accept(isModelLoaded() ? mBgDataModel : null)); } @Override diff --git a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java index df493599ed..3b140a06bd 100644 --- a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java +++ b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java @@ -49,7 +49,6 @@ import com.android.launcher3.model.GridSizeMigrationTask; import com.android.launcher3.model.GridSizeMigrationTaskV2; import com.android.launcher3.model.LoaderTask; import com.android.launcher3.model.ModelDelegate; -import com.android.launcher3.model.ModelPreload; import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.RunnableList; import com.android.launcher3.util.Themes; @@ -174,18 +173,13 @@ public class PreviewSurfaceRenderer { } }.run(); } else { - new ModelPreload() { - - @Override - public void onComplete(boolean isSuccess) { - if (isSuccess) { - MAIN_EXECUTOR.execute(() -> - renderView(inflationContext, getBgDataModel(), null)); - } else { - Log.e(TAG, "Model loading failed"); - } + LauncherAppState.getInstance(inflationContext).getModel().loadAsync(dataModel -> { + if (dataModel != null) { + MAIN_EXECUTOR.execute(() -> renderView(inflationContext, dataModel, null)); + } else { + Log.e(TAG, "Model loading failed"); } - }.start(inflationContext); + }); } } diff --git a/src/com/android/launcher3/model/ModelPreload.java b/src/com/android/launcher3/model/ModelPreload.java deleted file mode 100644 index 756b7da759..0000000000 --- a/src/com/android/launcher3/model/ModelPreload.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.launcher3.model; - -import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; - -import android.content.Context; -import android.util.Log; - -import androidx.annotation.WorkerThread; - -import com.android.launcher3.LauncherAppState; -import com.android.launcher3.LauncherModel; -import com.android.launcher3.LauncherModel.ModelUpdateTask; -import com.android.launcher3.model.BgDataModel.Callbacks; - -import java.util.concurrent.Executor; - -/** - * Utility class to preload LauncherModel - */ -public class ModelPreload implements ModelUpdateTask { - - private static final String TAG = "ModelPreload"; - - private LauncherAppState mApp; - private LauncherModel mModel; - private BgDataModel mBgDataModel; - private AllAppsList mAllAppsList; - - @Override - public final void init(LauncherAppState app, LauncherModel model, BgDataModel dataModel, - AllAppsList allAppsList, Executor uiExecutor) { - mApp = app; - mModel = model; - mBgDataModel = dataModel; - mAllAppsList = allAppsList; - } - - @Override - public final void run() { - mModel.startLoaderForResultsIfNotLoaded( - new LoaderResults(mApp, mBgDataModel, mAllAppsList, new Callbacks[0])); - MODEL_EXECUTOR.post(() -> { - Log.d(TAG, "Preload completed : " + mModel.isModelLoaded()); - onComplete(mModel.isModelLoaded()); - }); - } - - public BgDataModel getBgDataModel() { - return mBgDataModel; - } - - /** - * Called when the task is complete - */ - @WorkerThread - public void onComplete(boolean isSuccess) { } - - public void start(Context context) { - LauncherAppState.getInstance(context).getModel().enqueueModelUpdateTask(this); - } -} \ No newline at end of file From 26de7be984b9a9e9d7ce246efcf52b1fb0761653 Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Tue, 27 Jul 2021 10:34:54 -0700 Subject: [PATCH 05/66] Fix NPE when converting final screen to empty screen. Bug: 194553613 Test: manual Change-Id: Id29b8574964688f6f6aa96dd5b1b8a4d8b9110c0 --- src/com/android/launcher3/Workspace.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 5bdc4022c2..2bb4e5c711 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -687,8 +687,9 @@ public class Workspace extends PagedView CellLayout finalScreen = mWorkspaceScreens.get(finalScreenId); // If the final screen is empty, convert it to the extra empty screen - if (finalScreen.getShortcutsAndWidgets().getChildCount() == 0 && - !finalScreen.isDropPending()) { + if (finalScreen != null + && finalScreen.getShortcutsAndWidgets().getChildCount() == 0 + && !finalScreen.isDropPending()) { mWorkspaceScreens.remove(finalScreenId); mScreenOrder.removeValue(finalScreenId); From cea66b3a812ea892f4e10c7df91436c6573b9c89 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Tue, 17 Aug 2021 02:11:04 -0700 Subject: [PATCH 06/66] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I1827e8d2469c9c7993b5b15ea5a964e1fa562dbb --- quickstep/res/values-te/strings.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/quickstep/res/values-te/strings.xml b/quickstep/res/values-te/strings.xml index 73e4e0c687..ef8f3bad48 100644 --- a/quickstep/res/values-te/strings.xml +++ b/quickstep/res/values-te/strings.xml @@ -33,13 +33,13 @@ "మీ సూచించబడిన యాప్‌లు" "మీ మొదటి స్క్రీన్‌ దిగువ వరుసలో యాప్ సలహాలను పొందండి" "మీ హోమ్ స్క్రీన్‌లోని ఇష్టమైన వాటి వరుసలో యాప్ సూచ‌న‌లు పొందండి" - "మీరు ఎక్కువగా ఉపయోగించే యాప్‌లను నేరుగా మొదటి స్క్రీన్‌లోనే సులభంగా యాక్సెస్ చేయండి. మీ రోజువారీ కార్యకలాపాలను బట్టి సూచనలు మారతాయి. దిగువ వరుసలోని యాప్‌లు మీ మొదటి స్క్రీన్ పైకి చేరుకుంటాయి." - "మీరు ఎక్కువగా ఉపయోగించే యాప్‌లను నేరుగా మొదటి స్క్రీన్‌లోనే సులభంగా యాక్సెస్ చేయండి. మీ రోజువారీ కార్యకలాపాలను బట్టి సూచనలు మారతాయి. ఇష్టమైన వాటి వరుసలోని యాప్‌లు మీ మొదటి స్క్రీన్‌కు చేరుకుంటాయి." - "మీరు ఎక్కువగా ఉపయోగించే యాప్‌లను నేరుగా మొదటి స్క్రీన్‌లోనే సులభంగా యాక్సెస్ చేయండి. మీ రోజువారీ కార్యకలాపాలను బట్టి సూచనలు మారతాయి. దిగువ వరుసలోని యాప్‌లు కొత్త ఫోల్డర్‌కు తరలించబడతాయి." + "మీరు ఎక్కువగా ఉపయోగించే యాప్‌లను నేరుగా మొదటి స్క్రీన్‌లోనే సులభంగా యాక్సెస్ చేయండి. మీ రోజువారీ యాక్టివిటీలను బట్టి సూచనలు మారతాయి. దిగువ వరుసలోని యాప్‌లు మీ మొదటి స్క్రీన్ పైకి చేరుకుంటాయి." + "మీరు ఎక్కువగా ఉపయోగించే యాప్‌లను నేరుగా మొదటి స్క్రీన్‌లోనే సులభంగా యాక్సెస్ చేయండి. మీ రోజువారీ యాక్టివిటీలను బట్టి సూచనలు మారతాయి. ఇష్టమైన వాటి వరుసలోని యాప్‌లు మీ మొదటి స్క్రీన్‌కు చేరుకుంటాయి." + "మీరు ఎక్కువగా ఉపయోగించే యాప్‌లను నేరుగా మొదటి స్క్రీన్‌లోనే సులభంగా యాక్సెస్ చేయండి. మీ రోజువారీ యాక్టివిటీలను బట్టి సూచనలు మారతాయి. దిగువ వరుసలోని యాప్‌లు కొత్త ఫోల్డర్‌కు తరలించబడతాయి." "యాప్ సూచ‌న‌లను పొందండి" "వద్దు" "సెట్టింగ్‌లు" - "ఎక్కువగా ఉపయోగించిన యాప్‌లు ఇక్కడ కనిపిస్తాయి, అవి రోజువారీ కార్యకలాపాలను బట్టి మారుతూ ఉంటాయి" + "ఎక్కువగా ఉపయోగించిన యాప్‌లు ఇక్కడ కనిపిస్తాయి, అవి రోజువారీ యాక్టివిటీలను బట్టి మారుతూ ఉంటాయి" "యాప్ సలహాలను పొందడానికి దిగువ వరుస నుండి యాప్‌లను లాగండి" "యాప్ సూచ‌న‌లు ఖాళీ స్పేస్‌కు జోడించబడ్డాయి" "యాప్ సలహాలు ఎనేబుల్ చేయబడ్డాయి" From af65b6d3d25d1f45408210b2bfff501025d3af7e Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Tue, 17 Aug 2021 02:11:45 -0700 Subject: [PATCH 07/66] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I945a5fbf0a31fe983fe20c6f173d80e6d9423e26 --- quickstep/res/values-te/strings.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/quickstep/res/values-te/strings.xml b/quickstep/res/values-te/strings.xml index 73e4e0c687..ef8f3bad48 100644 --- a/quickstep/res/values-te/strings.xml +++ b/quickstep/res/values-te/strings.xml @@ -33,13 +33,13 @@ "మీ సూచించబడిన యాప్‌లు" "మీ మొదటి స్క్రీన్‌ దిగువ వరుసలో యాప్ సలహాలను పొందండి" "మీ హోమ్ స్క్రీన్‌లోని ఇష్టమైన వాటి వరుసలో యాప్ సూచ‌న‌లు పొందండి" - "మీరు ఎక్కువగా ఉపయోగించే యాప్‌లను నేరుగా మొదటి స్క్రీన్‌లోనే సులభంగా యాక్సెస్ చేయండి. మీ రోజువారీ కార్యకలాపాలను బట్టి సూచనలు మారతాయి. దిగువ వరుసలోని యాప్‌లు మీ మొదటి స్క్రీన్ పైకి చేరుకుంటాయి." - "మీరు ఎక్కువగా ఉపయోగించే యాప్‌లను నేరుగా మొదటి స్క్రీన్‌లోనే సులభంగా యాక్సెస్ చేయండి. మీ రోజువారీ కార్యకలాపాలను బట్టి సూచనలు మారతాయి. ఇష్టమైన వాటి వరుసలోని యాప్‌లు మీ మొదటి స్క్రీన్‌కు చేరుకుంటాయి." - "మీరు ఎక్కువగా ఉపయోగించే యాప్‌లను నేరుగా మొదటి స్క్రీన్‌లోనే సులభంగా యాక్సెస్ చేయండి. మీ రోజువారీ కార్యకలాపాలను బట్టి సూచనలు మారతాయి. దిగువ వరుసలోని యాప్‌లు కొత్త ఫోల్డర్‌కు తరలించబడతాయి." + "మీరు ఎక్కువగా ఉపయోగించే యాప్‌లను నేరుగా మొదటి స్క్రీన్‌లోనే సులభంగా యాక్సెస్ చేయండి. మీ రోజువారీ యాక్టివిటీలను బట్టి సూచనలు మారతాయి. దిగువ వరుసలోని యాప్‌లు మీ మొదటి స్క్రీన్ పైకి చేరుకుంటాయి." + "మీరు ఎక్కువగా ఉపయోగించే యాప్‌లను నేరుగా మొదటి స్క్రీన్‌లోనే సులభంగా యాక్సెస్ చేయండి. మీ రోజువారీ యాక్టివిటీలను బట్టి సూచనలు మారతాయి. ఇష్టమైన వాటి వరుసలోని యాప్‌లు మీ మొదటి స్క్రీన్‌కు చేరుకుంటాయి." + "మీరు ఎక్కువగా ఉపయోగించే యాప్‌లను నేరుగా మొదటి స్క్రీన్‌లోనే సులభంగా యాక్సెస్ చేయండి. మీ రోజువారీ యాక్టివిటీలను బట్టి సూచనలు మారతాయి. దిగువ వరుసలోని యాప్‌లు కొత్త ఫోల్డర్‌కు తరలించబడతాయి." "యాప్ సూచ‌న‌లను పొందండి" "వద్దు" "సెట్టింగ్‌లు" - "ఎక్కువగా ఉపయోగించిన యాప్‌లు ఇక్కడ కనిపిస్తాయి, అవి రోజువారీ కార్యకలాపాలను బట్టి మారుతూ ఉంటాయి" + "ఎక్కువగా ఉపయోగించిన యాప్‌లు ఇక్కడ కనిపిస్తాయి, అవి రోజువారీ యాక్టివిటీలను బట్టి మారుతూ ఉంటాయి" "యాప్ సలహాలను పొందడానికి దిగువ వరుస నుండి యాప్‌లను లాగండి" "యాప్ సూచ‌న‌లు ఖాళీ స్పేస్‌కు జోడించబడ్డాయి" "యాప్ సలహాలు ఎనేబుల్ చేయబడ్డాయి" From c864f6c50e9085329b7d259910fd03fb53591e9e Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Tue, 17 Aug 2021 02:15:20 -0700 Subject: [PATCH 08/66] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I7fb2cb94cefd0abab06ebaf0f6a54d5ef2b225aa --- res/values-ta/strings.xml | 4 ++-- res/values-te/strings.xml | 26 +++++++++++++------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml index c4ee9ae523..25a1739c3e 100644 --- a/res/values-ta/strings.xml +++ b/res/values-ta/strings.xml @@ -101,8 +101,8 @@ "மாற்றிய பெயரைச் சேமிக்க, தட்டவும்" "கோப்புறை மூடப்பட்டது" "கோப்புறை %1$s என மறுபெயரிடப்பட்டது" - "கோப்புறை: %1$s, %2$d கோப்புகள்" - "கோப்புறை: %1$s, %2$d அல்லது அதற்கு அதிகமான கோப்புகள்" + "கோப்புறை: %1$s, %2$d ஃபைல்கள்" + "கோப்புறை: %1$s, %2$d அல்லது அதற்கு அதிகமான ஃபைல்கள்" "வால்பேப்பர்கள்" "வால்பேப்பர் & ஸ்டைல்" "முகப்பு அமைப்புகள்" diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml index 68938883b1..22aa78533a 100644 --- a/res/values-te/strings.xml +++ b/res/values-te/strings.xml @@ -58,7 +58,7 @@ "విడ్జెట్ సెట్టింగ్‌లను మార్చడానికి ట్యాప్ చేయండి" "అర్థమైంది" "విడ్జెట్ సెట్టింగ్‌లను మార్చండి" - "అప్లికేషన్‌లను శోధించండి" + "అప్లికేషన్‌లను వెతకండి" "అప్లికేషన్‌లను లోడ్ చేస్తోంది…" "\"%1$s\"కి సరిపోలే అప్లికేషన్‌లేవీ కనుగొనబడలేదు" "మరిన్ని యాప్‌ల కోసం వెతుకు" @@ -68,9 +68,9 @@ "షార్ట్‌కట్‌ను తరలించడానికి లేదా అనుకూల చర్యలను ఉపయోగించడానికి రెండుసార్లు నొక్కండి & హోల్డ్ చేయండి." "ఈ మొదటి స్క్రీన్‌లో స్థలం లేదు" "ఇష్టమైనవి ట్రేలో ఖాళీ లేదు" - "యాప్‌ల జాబితా" - "వ్యక్తిగత యాప్‌ల జాబితా" - "కార్యాలయ యాప్‌ల జాబితా" + "యాప్‌ల లిస్ట్‌" + "వ్యక్తిగత యాప్‌ల లిస్ట్‌" + "కార్యాలయ యాప్‌ల లిస్ట్‌" "తీసివేయి" "అన్ఇన్‌స్టాల్ చేయి" "యాప్ సమాచారం" @@ -78,11 +78,11 @@ "యాప్‌ను సూచించవద్దు" "సూచనను పిన్ చేయండి" "షార్ట్‌కట్‌లను ఇన్‌స్టాల్ చేయడం" - "వినియోగదారు ప్రమేయం లేకుండా సత్వరమార్గాలను జోడించడానికి యాప్‌ను అనుమతిస్తుంది." - "హోమ్ సెట్టింగ్‌లు మరియు సత్వరమార్గాలను చదవడం" - "హోమ్‌లో సెట్టింగ్‌లు మరియు సత్వరమార్గాలను చదవడానికి యాప్‌ను అనుమతిస్తుంది." - "హోమ్ సెట్టింగ్‌లు మరియు సత్వరమార్గాలను వ్రాయడం" - "హోమ్‌లో సెట్టింగ్‌లు మరియు సత్వరమార్గాలను మార్చడానికి యాప్‌ను అనుమతిస్తుంది." + "వినియోగదారు ప్రమేయం లేకుండా షార్ట్‌కట్‌లను జోడించడానికి యాప్‌ను అనుమతిస్తుంది." + "హోమ్ సెట్టింగ్‌లు మరియు షార్ట్‌కట్‌లను చదవడం" + "హోమ్‌లో సెట్టింగ్‌లు మరియు షార్ట్‌కట్‌లను చదవడానికి యాప్‌ను అనుమతిస్తుంది." + "హోమ్ సెట్టింగ్‌లు మరియు షార్ట్‌కట్‌లను వ్రాయడం" + "హోమ్‌లో సెట్టింగ్‌లు మరియు షార్ట్‌కట్‌లను మార్చడానికి యాప్‌ను అనుమతిస్తుంది." "ఫోన్ కాల్స్‌ను చేసేందుకు %1$sకి అనుమతి లేదు" "విడ్జెట్‌ను లోడ్ చేయడం సాధ్యం కాలేదు" "సెటప్‌ను పూర్తి చేయడానికి ట్యాప్ చేయండి" @@ -126,8 +126,8 @@ "%1$s‌ను ఇన్‌స్టాల్ చేయడం, %2$s పూర్తయింది" "%1$s డౌన్‌లోడ్ అవుతోంది, %2$s పూర్తయింది" "%1$s ఇన్‌స్టాల్ కావడానికి వేచి ఉంది" - "విడ్జెట్‌ల జాబితా" - "విడ్జెట్‌ల జాబితా మూసివేయబడింది" + "విడ్జెట్‌ల లిస్ట్‌" + "విడ్జెట్‌ల లిస్ట్‌ మూసివేయబడింది" "హోమ్ స్క్రీన్‌కు జోడించండి" "అంశాన్ని ఇక్కడికి తరలించు" "అంశం హోమ్‌స్క్రీన్‌కి జోడించబడింది" @@ -141,7 +141,7 @@ "ఈ ఫోల్డర్‌కి జోడించండి: %1$s" "%1$s గల ఫోల్డర్‌కు జోడించు" "అంశం ఫోల్డర్‌కు జోడించబడింది" - "ఈ పేరుతో ఫోల్డర్‌ను సృష్టించండి: %1$s" + "ఈ పేరుతో ఫోల్డర్‌ను క్రియేట్ చేయండి: %1$s" "ఫోల్డర్ సృష్టించబడింది" "హోమ్‌స్క్రీన్‌కు తరలించు" "పరిమాణం మార్చు" @@ -150,7 +150,7 @@ "వెడల్పును తగ్గించు" "ఎత్తును తగ్గించు" "విడ్జెట్ పరిమాణం వెడల్పు %1$sకి, ఎత్తు %2$sకి మార్చబడింది" - "సత్వరమార్గాలు" + "షార్ట్‌కట్స్" "షార్ట్‌కట్‌లు మరియు నోటిఫికేషన్‌లు" "తీసివేయి" "మూసివేస్తుంది" From f07084c8f4b96b4063c4fde3601b29288b6e700f Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Tue, 17 Aug 2021 02:16:14 -0700 Subject: [PATCH 09/66] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I2e99b63e1092bd252b2052280d05e765cbe799ac --- res/values-ta/strings.xml | 4 ++-- res/values-te/strings.xml | 28 ++++++++++++++-------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml index c4ee9ae523..25a1739c3e 100644 --- a/res/values-ta/strings.xml +++ b/res/values-ta/strings.xml @@ -101,8 +101,8 @@ "மாற்றிய பெயரைச் சேமிக்க, தட்டவும்" "கோப்புறை மூடப்பட்டது" "கோப்புறை %1$s என மறுபெயரிடப்பட்டது" - "கோப்புறை: %1$s, %2$d கோப்புகள்" - "கோப்புறை: %1$s, %2$d அல்லது அதற்கு அதிகமான கோப்புகள்" + "கோப்புறை: %1$s, %2$d ஃபைல்கள்" + "கோப்புறை: %1$s, %2$d அல்லது அதற்கு அதிகமான ஃபைல்கள்" "வால்பேப்பர்கள்" "வால்பேப்பர் & ஸ்டைல்" "முகப்பு அமைப்புகள்" diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml index 80a6f10bf1..22aa78533a 100644 --- a/res/values-te/strings.xml +++ b/res/values-te/strings.xml @@ -58,7 +58,7 @@ "విడ్జెట్ సెట్టింగ్‌లను మార్చడానికి ట్యాప్ చేయండి" "అర్థమైంది" "విడ్జెట్ సెట్టింగ్‌లను మార్చండి" - "అప్లికేషన్‌లను శోధించండి" + "అప్లికేషన్‌లను వెతకండి" "అప్లికేషన్‌లను లోడ్ చేస్తోంది…" "\"%1$s\"కి సరిపోలే అప్లికేషన్‌లేవీ కనుగొనబడలేదు" "మరిన్ని యాప్‌ల కోసం వెతుకు" @@ -68,9 +68,9 @@ "షార్ట్‌కట్‌ను తరలించడానికి లేదా అనుకూల చర్యలను ఉపయోగించడానికి రెండుసార్లు నొక్కండి & హోల్డ్ చేయండి." "ఈ మొదటి స్క్రీన్‌లో స్థలం లేదు" "ఇష్టమైనవి ట్రేలో ఖాళీ లేదు" - "అనువర్తనాల జాబితా" - "వ్యక్తిగత యాప్‌ల జాబితా" - "కార్యాలయ యాప్‌ల జాబితా" + "యాప్‌ల లిస్ట్‌" + "వ్యక్తిగత యాప్‌ల లిస్ట్‌" + "కార్యాలయ యాప్‌ల లిస్ట్‌" "తీసివేయి" "అన్ఇన్‌స్టాల్ చేయి" "యాప్ సమాచారం" @@ -78,12 +78,12 @@ "యాప్‌ను సూచించవద్దు" "సూచనను పిన్ చేయండి" "షార్ట్‌కట్‌లను ఇన్‌స్టాల్ చేయడం" - "వినియోగదారు ప్రమేయం లేకుండా సత్వరమార్గాలను జోడించడానికి యాప్‌ను అనుమతిస్తుంది." - "హోమ్ సెట్టింగ్‌లు మరియు సత్వరమార్గాలను చదవడం" - "హోమ్‌లో సెట్టింగ్‌లు మరియు సత్వరమార్గాలను చదవడానికి యాప్‌ను అనుమతిస్తుంది." - "హోమ్ సెట్టింగ్‌లు మరియు సత్వరమార్గాలను వ్రాయడం" - "హోమ్‌లో సెట్టింగ్‌లు మరియు సత్వరమార్గాలను మార్చడానికి యాప్‌ను అనుమతిస్తుంది." - "ఫోన్ కాల్‌లను చేసేందుకు %1$sకి అనుమతి లేదు" + "వినియోగదారు ప్రమేయం లేకుండా షార్ట్‌కట్‌లను జోడించడానికి యాప్‌ను అనుమతిస్తుంది." + "హోమ్ సెట్టింగ్‌లు మరియు షార్ట్‌కట్‌లను చదవడం" + "హోమ్‌లో సెట్టింగ్‌లు మరియు షార్ట్‌కట్‌లను చదవడానికి యాప్‌ను అనుమతిస్తుంది." + "హోమ్ సెట్టింగ్‌లు మరియు షార్ట్‌కట్‌లను వ్రాయడం" + "హోమ్‌లో సెట్టింగ్‌లు మరియు షార్ట్‌కట్‌లను మార్చడానికి యాప్‌ను అనుమతిస్తుంది." + "ఫోన్ కాల్స్‌ను చేసేందుకు %1$sకి అనుమతి లేదు" "విడ్జెట్‌ను లోడ్ చేయడం సాధ్యం కాలేదు" "సెటప్‌ను పూర్తి చేయడానికి ట్యాప్ చేయండి" "ఇది సిస్టమ్ యాప్ మరియు దీన్ని అన్‌ఇన్‌స్టాల్ చేయడం సాధ్యపడదు." @@ -126,8 +126,8 @@ "%1$s‌ను ఇన్‌స్టాల్ చేయడం, %2$s పూర్తయింది" "%1$s డౌన్‌లోడ్ అవుతోంది, %2$s పూర్తయింది" "%1$s ఇన్‌స్టాల్ కావడానికి వేచి ఉంది" - "విడ్జెట్‌ల జాబితా" - "విడ్జెట్‌ల జాబితా మూసివేయబడింది" + "విడ్జెట్‌ల లిస్ట్‌" + "విడ్జెట్‌ల లిస్ట్‌ మూసివేయబడింది" "హోమ్ స్క్రీన్‌కు జోడించండి" "అంశాన్ని ఇక్కడికి తరలించు" "అంశం హోమ్‌స్క్రీన్‌కి జోడించబడింది" @@ -141,7 +141,7 @@ "ఈ ఫోల్డర్‌కి జోడించండి: %1$s" "%1$s గల ఫోల్డర్‌కు జోడించు" "అంశం ఫోల్డర్‌కు జోడించబడింది" - "ఈ పేరుతో ఫోల్డర్‌ను సృష్టించండి: %1$s" + "ఈ పేరుతో ఫోల్డర్‌ను క్రియేట్ చేయండి: %1$s" "ఫోల్డర్ సృష్టించబడింది" "హోమ్‌స్క్రీన్‌కు తరలించు" "పరిమాణం మార్చు" @@ -150,7 +150,7 @@ "వెడల్పును తగ్గించు" "ఎత్తును తగ్గించు" "విడ్జెట్ పరిమాణం వెడల్పు %1$sకి, ఎత్తు %2$sకి మార్చబడింది" - "సత్వరమార్గాలు" + "షార్ట్‌కట్స్" "షార్ట్‌కట్‌లు మరియు నోటిఫికేషన్‌లు" "తీసివేయి" "మూసివేస్తుంది" From 482f983a7b459f63cad16578fa9cee1eced35d24 Mon Sep 17 00:00:00 2001 From: Lucas Dupin Date: Wed, 28 Jul 2021 10:24:54 -0700 Subject: [PATCH 10/66] Add depth to -1 screen Wallpaper will zoom out as you drag the overlay Test: manually pull overlay Fixes: 192502999 Change-Id: I9067b70d10497d4e16a5ef601161fbedfa9307e1 Merged-In: I9067b70d10497d4e16a5ef601161fbedfa9307e1 (cherry picked from commit 87d752062e9df6fffa7beb907b899cac69359f11) --- .../launcher3/BaseQuickstepLauncher.java | 11 ++++++++++ .../statehandlers/DepthController.java | 16 +++++++++++++++ src/com/android/launcher3/Launcher.java | 20 +++++++++++-------- 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java index a44de793a3..de0416b693 100644 --- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java @@ -200,6 +200,17 @@ public abstract class BaseQuickstepLauncher extends Launcher } } + /** + * {@code LauncherOverlayCallbacks} scroll amount. + * Indicates transition progress to -1 screen. + * @param progress From 0 to 1. + */ + @Override + public void onScrollChanged(float progress) { + super.onScrollChanged(progress); + mDepthController.onOverlayScrollChanged(progress); + } + @Override public void startIntentSenderForResult(IntentSender intent, int requestCode, Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options) { diff --git a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java index 370fb8ef7c..f01ff8bd5d 100644 --- a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java +++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java @@ -116,6 +116,10 @@ public class DepthController implements StateHandler, private boolean mCrossWindowBlursEnabled; private WallpaperManagerCompat mWallpaperManager; private SurfaceControl mSurface; + /** + * How visible the -1 overlay is, from 0 to 1. + */ + private float mOverlayScrollProgress; /** * Ratio from 0 to 1, where 0 is fully zoomed out, and 1 is zoomed in. * @see android.service.wallpaper.WallpaperService.Engine#onZoomChanged(float) @@ -251,12 +255,24 @@ public class DepthController implements StateHandler, } } + public void onOverlayScrollChanged(float progress) { + // Round out the progress to dedupe frequent, non-perceptable updates + int progressI = (int) (progress * 256); + float progressF = progressI / 256f; + if (Float.compare(mOverlayScrollProgress, progressF) == 0) { + return; + } + mOverlayScrollProgress = progressF; + dispatchTransactionSurface(mDepth); + } + private boolean dispatchTransactionSurface(float depth) { boolean supportsBlur = BlurUtils.supportsBlursOnWindows(); if (supportsBlur && (mSurface == null || !mSurface.isValid())) { return false; } ensureDependencies(); + depth = Math.max(depth, mOverlayScrollProgress); IBinder windowToken = mLauncher.getRootView().getWindowToken(); if (windowToken != null) { mWallpaperManager.setWallpaperZoomOut(windowToken, depth); diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 099f256982..5fb862ee95 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -218,7 +218,8 @@ import java.util.stream.Stream; * Default launcher application. */ public class Launcher extends StatefulActivity implements LauncherExterns, - Callbacks, InvariantDeviceProfile.OnIDPChangeListener, PluginListener { + Callbacks, InvariantDeviceProfile.OnIDPChangeListener, PluginListener, + LauncherOverlayCallbacks { public static final String TAG = "Launcher"; public static final ActivityTracker ACTIVITY_TRACKER = new ActivityTracker<>(); @@ -619,7 +620,7 @@ public class Launcher extends StatefulActivity implements Launche @Override public void setLauncherOverlay(LauncherOverlay overlay) { if (overlay != null) { - overlay.setOverlayCallbacks(new LauncherOverlayCallbacksImpl()); + overlay.setOverlayCallbacks(this); } mWorkspace.setLauncherOverlay(overlay); } @@ -1123,12 +1124,15 @@ public class Launcher extends StatefulActivity implements Launche mAppWidgetHost.setActivityResumed(false); } - class LauncherOverlayCallbacksImpl implements LauncherOverlayCallbacks { - - public void onScrollChanged(float progress) { - if (mWorkspace != null) { - mWorkspace.onOverlayScrollChanged(progress); - } + /** + * {@code LauncherOverlayCallbacks} scroll amount. + * Indicates transition progress to -1 screen. + * @param progress From 0 to 1. + */ + @Override + public void onScrollChanged(float progress) { + if (mWorkspace != null) { + mWorkspace.onOverlayScrollChanged(progress); } } From bda98de9f81600eb93ff1ecdb1791f7dc8a01473 Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Mon, 16 Aug 2021 15:25:01 -0700 Subject: [PATCH 11/66] New app animation specs. - New values and interpolators. Bug: 173107751 Test: open apps from different parts of the home screen Change-Id: I81bec0221aec9c04dac0bb3e926c879999699e57 --- quickstep/res/interpolator/app_open_x.xml | 21 ++++++ .../three_point_fast_out_extra_slow_in.xml | 21 ++++++ .../launcher3/QuickstepTransitionManager.java | 75 ++++++++----------- 3 files changed, 72 insertions(+), 45 deletions(-) create mode 100644 quickstep/res/interpolator/app_open_x.xml create mode 100644 quickstep/res/interpolator/three_point_fast_out_extra_slow_in.xml diff --git a/quickstep/res/interpolator/app_open_x.xml b/quickstep/res/interpolator/app_open_x.xml new file mode 100644 index 0000000000..5fa0bcb9ae --- /dev/null +++ b/quickstep/res/interpolator/app_open_x.xml @@ -0,0 +1,21 @@ + + + + diff --git a/quickstep/res/interpolator/three_point_fast_out_extra_slow_in.xml b/quickstep/res/interpolator/three_point_fast_out_extra_slow_in.xml new file mode 100644 index 0000000000..70c4231140 --- /dev/null +++ b/quickstep/res/interpolator/three_point_fast_out_extra_slow_in.xml @@ -0,0 +1,21 @@ + + + + diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java index 5bb76d6a67..b557779a26 100644 --- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java @@ -32,7 +32,6 @@ import static com.android.launcher3.Utilities.postAsyncCallback; import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE; import static com.android.launcher3.anim.Interpolators.DEACCEL_1_5; import static com.android.launcher3.anim.Interpolators.DEACCEL_1_7; -import static com.android.launcher3.anim.Interpolators.EXAGGERATED_EASE; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.config.FeatureFlags.ENABLE_SCRIM_FOR_APP_LAUNCH; import static com.android.launcher3.config.FeatureFlags.KEYGUARD_ANIMATION; @@ -72,6 +71,7 @@ import android.view.SurfaceControl; import android.view.View; import android.view.ViewRootImpl; import android.view.ViewTreeObserver; +import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; import android.view.animation.PathInterpolator; @@ -142,21 +142,11 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener private static final String CONTROL_REMOTE_APP_TRANSITION_PERMISSION = "android.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS"; - private static final long APP_LAUNCH_DURATION = 450; - // Use a shorter duration for x or y translation to create a curve effect - private static final long APP_LAUNCH_CURVED_DURATION = 250; + private static final long APP_LAUNCH_DURATION = 500; + private static final long APP_LAUNCH_ALPHA_DURATION = 50; private static final long APP_LAUNCH_ALPHA_START_DELAY = 25; - // We scale the durations for the downward app launch animations (minus the scale animation). - private static final float APP_LAUNCH_DOWN_DUR_SCALE_FACTOR = 0.8f; - private static final long APP_LAUNCH_DOWN_DURATION = - (long) (APP_LAUNCH_DURATION * APP_LAUNCH_DOWN_DUR_SCALE_FACTOR); - private static final long APP_LAUNCH_DOWN_CURVED_DURATION = - (long) (APP_LAUNCH_CURVED_DURATION * APP_LAUNCH_DOWN_DUR_SCALE_FACTOR); - private static final long APP_LAUNCH_ALPHA_DOWN_DURATION = - (long) (APP_LAUNCH_ALPHA_DURATION * APP_LAUNCH_DOWN_DUR_SCALE_FACTOR); - public static final int ANIMATION_NAV_FADE_IN_DURATION = 266; public static final int ANIMATION_NAV_FADE_OUT_DURATION = 133; public static final long ANIMATION_DELAY_NAV_FADE_IN = @@ -166,9 +156,6 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener public static final Interpolator NAV_FADE_OUT_INTERPOLATOR = new PathInterpolator(0.2f, 0f, 1f, 1f); - private static final long CROP_DURATION = 375; - private static final long RADIUS_DURATION = 375; - public static final int RECENTS_LAUNCH_DURATION = 336; private static final int LAUNCHER_RESUME_START_DELAY = 100; private static final int CLOSING_TRANSITION_DURATION_MS = 250; @@ -222,6 +209,9 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener // Will never be larger than MAX_NUM_TASKS private LinkedHashMap> mTaskStartParams; + private final Interpolator mOpeningXInterpolator; + private final Interpolator mOpeningInterpolator; + public QuickstepTransitionManager(Context context) { mLauncher = Launcher.cast(Launcher.getLauncher(context)); mDragLayer = mLauncher.getDragLayer(); @@ -248,6 +238,10 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener SystemUiProxy.INSTANCE.get(mLauncher).setStartingWindowListener( mStartingWindowListener); } + + mOpeningXInterpolator = AnimationUtils.loadInterpolator(context, R.interpolator.app_open_x); + mOpeningInterpolator = AnimationUtils.loadInterpolator(context, + R.interpolator.three_point_fast_out_extra_slow_in); } @Override @@ -651,27 +645,29 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener final float finalShadowRadius = appTargetsAreTranslucent ? 0 : mMaxShadowRadius; MultiValueUpdateListener listener = new MultiValueUpdateListener() { - FloatProp mDx = new FloatProp(0, prop.dX, 0, prop.xDuration, AGGRESSIVE_EASE); - FloatProp mDy = new FloatProp(0, prop.dY, 0, prop.yDuration, AGGRESSIVE_EASE); + FloatProp mDx = new FloatProp(0, prop.dX, 0, APP_LAUNCH_DURATION, + mOpeningXInterpolator); + FloatProp mDy = new FloatProp(0, prop.dY, 0, APP_LAUNCH_DURATION, + mOpeningInterpolator); FloatProp mIconScaleToFitScreen = new FloatProp(prop.initialAppIconScale, - prop.finalAppIconScale, 0, APP_LAUNCH_DURATION, EXAGGERATED_EASE); + prop.finalAppIconScale, 0, APP_LAUNCH_DURATION, mOpeningInterpolator); FloatProp mIconAlpha = new FloatProp(prop.iconAlphaStart, 0f, - APP_LAUNCH_ALPHA_START_DELAY, prop.alphaDuration, LINEAR); + APP_LAUNCH_ALPHA_START_DELAY, APP_LAUNCH_ALPHA_DURATION, LINEAR); FloatProp mWindowRadius = new FloatProp(initialWindowRadius, finalWindowRadius, 0, - RADIUS_DURATION, EXAGGERATED_EASE); + APP_LAUNCH_DURATION, mOpeningInterpolator); FloatProp mShadowRadius = new FloatProp(0, finalShadowRadius, 0, - APP_LAUNCH_DURATION, EXAGGERATED_EASE); + APP_LAUNCH_DURATION, mOpeningInterpolator); FloatProp mCropRectCenterX = new FloatProp(prop.cropCenterXStart, prop.cropCenterXEnd, - 0, CROP_DURATION, EXAGGERATED_EASE); + 0, APP_LAUNCH_DURATION, mOpeningInterpolator); FloatProp mCropRectCenterY = new FloatProp(prop.cropCenterYStart, prop.cropCenterYEnd, - 0, CROP_DURATION, EXAGGERATED_EASE); + 0, APP_LAUNCH_DURATION, mOpeningInterpolator); FloatProp mCropRectWidth = new FloatProp(prop.cropWidthStart, prop.cropWidthEnd, 0, - CROP_DURATION, EXAGGERATED_EASE); + APP_LAUNCH_DURATION, mOpeningInterpolator); FloatProp mCropRectHeight = new FloatProp(prop.cropHeightStart, prop.cropHeightEnd, 0, - CROP_DURATION, EXAGGERATED_EASE); + APP_LAUNCH_DURATION, mOpeningInterpolator); FloatProp mNavFadeOut = new FloatProp(1f, 0f, 0, ANIMATION_NAV_FADE_OUT_DURATION, NAV_FADE_OUT_INTERPOLATOR); @@ -873,22 +869,23 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener WIDGET_CROSSFADE_DURATION_MILLIS / 2 /* delay */, WIDGET_CROSSFADE_DURATION_MILLIS / 2 /* duration */, LINEAR); final FloatProp mWindowRadius = new FloatProp(initialWindowRadius, finalWindowRadius, - 0 /* start */, RADIUS_DURATION, LINEAR); - final FloatProp mCornerRadiusProgress = new FloatProp(0, 1, 0, RADIUS_DURATION, LINEAR); + 0 /* start */, APP_LAUNCH_DURATION, mOpeningInterpolator); + final FloatProp mCornerRadiusProgress = new FloatProp(0, 1, 0, APP_LAUNCH_DURATION, + mOpeningInterpolator); // Window & widget background positioning bounds final FloatProp mDx = new FloatProp(widgetBackgroundBounds.centerX(), - windowTargetBounds.centerX(), 0 /* delay */, APP_LAUNCH_CURVED_DURATION, - EXAGGERATED_EASE); + windowTargetBounds.centerX(), 0 /* delay */, APP_LAUNCH_DURATION, + mOpeningXInterpolator); final FloatProp mDy = new FloatProp(widgetBackgroundBounds.centerY(), windowTargetBounds.centerY(), 0 /* delay */, APP_LAUNCH_DURATION, - EXAGGERATED_EASE); + mOpeningInterpolator); final FloatProp mWidth = new FloatProp(widgetBackgroundBounds.width(), windowTargetBounds.width(), 0 /* delay */, APP_LAUNCH_DURATION, - EXAGGERATED_EASE); + mOpeningInterpolator); final FloatProp mHeight = new FloatProp(widgetBackgroundBounds.height(), windowTargetBounds.height(), 0 /* delay */, APP_LAUNCH_DURATION, - EXAGGERATED_EASE); + mOpeningInterpolator); final FloatProp mNavFadeOut = new FloatProp(1f, 0f, 0, ANIMATION_NAV_FADE_OUT_DURATION, NAV_FADE_OUT_INTERPOLATOR); @@ -1424,10 +1421,6 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener public final float dX; public final float dY; - public final long xDuration; - public final long yDuration; - public final long alphaDuration; - public final float initialAppIconScale; public final float finalAppIconScale; @@ -1459,14 +1452,6 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener dX = centerX - launcherIconBounds.centerX(); dY = centerY - launcherIconBounds.centerY(); - boolean useUpwardAnimation = launcherIconBounds.top > centerY - || Math.abs(dY) < dp.cellHeightPx; - xDuration = useUpwardAnimation ? APP_LAUNCH_CURVED_DURATION - : APP_LAUNCH_DOWN_DURATION; - yDuration = useUpwardAnimation ? APP_LAUNCH_DURATION - : APP_LAUNCH_DOWN_CURVED_DURATION; - alphaDuration = useUpwardAnimation ? APP_LAUNCH_ALPHA_DURATION - : APP_LAUNCH_ALPHA_DOWN_DURATION; iconAlphaStart = hasSplashScreen && !hasDifferentAppIcon ? 0 : 1f; final int windowIconSize = ResourceUtils.getDimenByName("starting_surface_icon_size", From a8382dc0528588041bb43b964035a95675e6d64c Mon Sep 17 00:00:00 2001 From: Lucas Dupin Date: Mon, 9 Aug 2021 16:11:14 -0700 Subject: [PATCH 12/66] Act on scrim visibility The scrim visibility drives whether the launcher window is opaque or not. We should track it and apply the flag instead of trying to catch it through other Launcher life cycles. Fixes: 195365607 Bug: 196403152 Test: tap on home button while launching app from overview Change-Id: I2a00b86b602b5dd12c901433b92adcf0170be15e (cherry picked from commit e4a9469156c16b19edf156bd7770b81d07674f12) --- .../statehandlers/DepthController.java | 20 ++++++++--- .../android/launcher3/views/ScrimView.java | 36 ++++++++++++++++++- 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java index 370fb8ef7c..000d69d400 100644 --- a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java +++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java @@ -108,6 +108,13 @@ public class DepthController implements StateHandler, } }; + private final Runnable mOpaquenessListener = new Runnable() { + @Override + public void run() { + dispatchTransactionSurface(mDepth); + } + }; + private final Launcher mLauncher; /** * Blur radius when completely zoomed out, in pixels. @@ -150,23 +157,28 @@ public class DepthController implements StateHandler, if (windowToken != null) { mWallpaperManager.setWallpaperZoomOut(windowToken, mDepth); } - CrossWindowBlurListeners.getInstance().addListener(mLauncher.getMainExecutor(), - mCrossWindowBlurListener); + onAttached(); } @Override public void onViewDetachedFromWindow(View view) { CrossWindowBlurListeners.getInstance().removeListener(mCrossWindowBlurListener); + mLauncher.getScrimView().removeOpaquenessListener(mOpaquenessListener); } }; mLauncher.getRootView().addOnAttachStateChangeListener(mOnAttachListener); if (mLauncher.getRootView().isAttachedToWindow()) { - CrossWindowBlurListeners.getInstance().addListener(mLauncher.getMainExecutor(), - mCrossWindowBlurListener); + onAttached(); } } } + private void onAttached() { + CrossWindowBlurListeners.getInstance().addListener(mLauncher.getMainExecutor(), + mCrossWindowBlurListener); + mLauncher.getScrimView().addOpaquenessListener(mOpaquenessListener); + } + /** * Sets if the underlying activity is started or not */ diff --git a/src/com/android/launcher3/views/ScrimView.java b/src/com/android/launcher3/views/ScrimView.java index 1eb79ad550..4c0bfde682 100644 --- a/src/com/android/launcher3/views/ScrimView.java +++ b/src/com/android/launcher3/views/ScrimView.java @@ -25,23 +25,27 @@ import android.graphics.drawable.ColorDrawable; import android.util.AttributeSet; import android.view.View; +import androidx.annotation.NonNull; import androidx.core.graphics.ColorUtils; import com.android.launcher3.BaseActivity; import com.android.launcher3.Insettable; import com.android.launcher3.util.SystemUiController; +import java.util.ArrayList; + /** * Simple scrim which draws a flat color */ public class ScrimView extends View implements Insettable { private static final float STATUS_BAR_COLOR_FORCE_UPDATE_THRESHOLD = 0.9f; + private final ArrayList mOpaquenessListeners = new ArrayList<>(1); private SystemUiController mSystemUiController; - private ScrimDrawingController mDrawingController; private int mBackgroundColor; private boolean mIsVisible = true; + private boolean mLastDispatchedOpaqueness; public ScrimView(Context context, AttributeSet attrs) { super(context, attrs); @@ -60,6 +64,7 @@ public class ScrimView extends View implements Insettable { @Override protected boolean onSetAlpha(int alpha) { updateSysUiColors(); + dispatchVisibilityListenersIfNeeded(); return super.onSetAlpha(alpha); } @@ -67,6 +72,7 @@ public class ScrimView extends View implements Insettable { public void setBackgroundColor(int color) { mBackgroundColor = color; updateSysUiColors(); + dispatchVisibilityListenersIfNeeded(); super.setBackgroundColor(color); } @@ -74,6 +80,7 @@ public class ScrimView extends View implements Insettable { public void onVisibilityAggregated(boolean isVisible) { super.onVisibilityAggregated(isVisible); mIsVisible = isVisible; + dispatchVisibilityListenersIfNeeded(); } public boolean isFullyOpaque() { @@ -108,6 +115,17 @@ public class ScrimView extends View implements Insettable { } } + private void dispatchVisibilityListenersIfNeeded() { + boolean fullyOpaque = isFullyOpaque(); + if (mLastDispatchedOpaqueness == fullyOpaque) { + return; + } + mLastDispatchedOpaqueness = fullyOpaque; + for (int i = 0; i < mOpaquenessListeners.size(); i++) { + mOpaquenessListeners.get(i).run(); + } + } + private SystemUiController getSystemUiController() { if (mSystemUiController == null) { mSystemUiController = BaseActivity.fromContext(getContext()).getSystemUiController(); @@ -135,6 +153,22 @@ public class ScrimView extends View implements Insettable { } } + /** + * Registers a listener to be notified of whether the scrim is occluding other UI elements. + * @see #isFullyOpaque() + */ + public void addOpaquenessListener(@NonNull Runnable listener) { + mOpaquenessListeners.add(listener); + } + + /** + * Removes previously registered listener. + * @see #addOpaquenessListener(Runnable) + */ + public void removeOpaquenessListener(@NonNull Runnable listener) { + mOpaquenessListeners.remove(listener); + } + /** * A Utility interface allowing for other surfaces to draw on ScrimView */ From df2b9e14d67b0cfbbde7b0f5a5aebb091f670614 Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Wed, 18 Aug 2021 18:39:46 +0100 Subject: [PATCH 13/66] Fix animation problem when swipeing up app to screen edge and release - Consider scroll diff between currentPage and primary scroll when calculating adjacent page offset - Removed setEnableFreeScroll call in onPrepareGestureAnimation that calls setCurrentPage and causes jumping Fixes: 197012570 Fixes: 195740577 Test: Swipe up from app to end of screen, adjacent task should come from screen edge, and app should snap smoothly to position Test: Swipe up from app, scroll immediately, free scroll should be enabled Test: Swipe up immediately after quick switch, task thumbnails are loaded Change-Id: Id88266634183dfcb18d5ba8a803883b7d6f50ab4 Merged-In: I1964b8c3bd82b22396340d2352833b2aee73a6fc (cherry picked from commit 8ebd11af143b09c5892810d6f8d2e1dfda888864) --- .../src/com/android/quickstep/views/RecentsView.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index fa4d6a1003..11a4884827 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -1764,8 +1764,6 @@ public abstract class RecentsView -1) { // When there is a midpoint reference task, adjacent tasks have less distance to travel - // to reach offscreen. Offset the task position to the task's starting point. - int midpointScroll = getScrollForPage(midpointIndex); + // to reach offscreen. Offset the task position to the task's starting point, and offset + // by current page's scroll diff. + int midpointScroll = getScrollForPage(midpointIndex) + + mOrientationHandler.getPrimaryScroll(this) - getScrollForPage(mCurrentPage); + getPersistentChildPosition(midpointIndex, midpointScroll, taskPosition); float midpointStart = mOrientationHandler.getStart(taskPosition); From 0a2076e8d37cdc33ebfa0c3654ba433707d2db10 Mon Sep 17 00:00:00 2001 From: Lucas Dupin Date: Tue, 24 Aug 2021 13:36:41 -0700 Subject: [PATCH 14/66] Synchronize surface transaction Until now the SurfaceControl transaction was being applied asynchronously, which could lead to it being executed out of sync with launcher drawing. This became an issue at higher refresh rates, where frames are produced at a much faster pace. In order to fix this issue, we can use BLAST transactions, which are annotated with a frame number. Test: record video, go through it manually Fixes: 194320152 Change-Id: I1636a1ded4f9dd84c54ba12239e3549b92ed7567 Merged-In: I1636a1ded4f9dd84c54ba12239e3549b92ed7567 --- .../launcher3/statehandlers/DepthController.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java index 000d69d400..8c9ac12bd4 100644 --- a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java +++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java @@ -26,6 +26,7 @@ import android.animation.ObjectAnimator; import android.os.IBinder; import android.os.SystemProperties; import android.util.FloatProperty; +import android.view.AttachedSurfaceControl; import android.view.CrossWindowBlurListeners; import android.view.SurfaceControl; import android.view.View; @@ -282,10 +283,15 @@ public class DepthController implements StateHandler, int blur = opaque || isOverview || !mCrossWindowBlursEnabled || mBlurDisabledForAppLaunch ? 0 : (int) (depth * mMaxBlurRadius); - new SurfaceControl.Transaction() + SurfaceControl.Transaction transaction = new SurfaceControl.Transaction() .setBackgroundBlurRadius(mSurface, blur) - .setOpaque(mSurface, opaque) - .apply(); + .setOpaque(mSurface, opaque); + + AttachedSurfaceControl rootSurfaceControl = + mLauncher.getRootView().getRootSurfaceControl(); + if (rootSurfaceControl != null) { + rootSurfaceControl.applyTransactionOnDraw(transaction); + } } return true; } From 6d7a006302bcbdfdfb36feb54f8b5376a58ebb4f Mon Sep 17 00:00:00 2001 From: Lucas Dupin Date: Fri, 13 Aug 2021 15:57:41 -0700 Subject: [PATCH 15/66] Constrain scroll amount Test: scroll vertically and horizontally Fixes: 196309367 Change-Id: Ibf16fb72cf95e29ed820d5f511e764a388c93bb0 Merged-In: Ibf16fb72cf95e29ed820d5f511e764a388c93bb0 (cherry picked from commit b259a896f5e4280fce236061d6f12a28b9ba6355) --- .../com/android/launcher3/statehandlers/DepthController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java index d22abf6851..bb58f451ce 100644 --- a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java +++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java @@ -271,7 +271,7 @@ public class DepthController implements StateHandler, public void onOverlayScrollChanged(float progress) { // Round out the progress to dedupe frequent, non-perceptable updates int progressI = (int) (progress * 256); - float progressF = progressI / 256f; + float progressF = Utilities.boundToRange(progressI / 256f, 0f, 1f); if (Float.compare(mOverlayScrollProgress, progressF) == 0) { return; } From 58dd9353483c7dc0946c0a89729b1dbedb8dafe9 Mon Sep 17 00:00:00 2001 From: Alan Viverette Date: Wed, 25 Aug 2021 22:06:47 +0000 Subject: [PATCH 16/66] Disable eager initialization of Jetpack libraries Bug: 197780098 Test: Launcher3 tests Change-Id: I8f921ae26e873822ac2340ad78449cf1040af4cf Merged-In: I8f921ae26e873822ac2340ad78449cf1040af4cf (cherry picked from commit a88802ee922bec27ef7ce3a45471fc163afbb7a7) --- AndroidManifest-common.xml | 7 +++++++ tests/AndroidManifest-common.xml | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/AndroidManifest-common.xml b/AndroidManifest-common.xml index d725a16f80..3b6141b47f 100644 --- a/AndroidManifest-common.xml +++ b/AndroidManifest-common.xml @@ -19,6 +19,7 @@ --> + diff --git a/tests/AndroidManifest-common.xml b/tests/AndroidManifest-common.xml index 918ec4af1a..4d980c47e0 100644 --- a/tests/AndroidManifest-common.xml +++ b/tests/AndroidManifest-common.xml @@ -16,6 +16,7 @@ @@ -235,5 +236,11 @@ + + + From ca34b4d57185ef13e6ec17cb1b60f655b0c948bf Mon Sep 17 00:00:00 2001 From: Alan Viverette Date: Thu, 26 Aug 2021 03:27:13 +0000 Subject: [PATCH 17/66] Temporarily disable Launcher3 tests affected by fling changes Bug: 197802324 Test: TaplTestsLauncher3 Change-Id: I3958bd9fb5521d09fa7cae642128b9f5e11b8e2e Merged-In: I3958bd9fb5521d09fa7cae642128b9f5e11b8e2e (cherry picked from commit bc4dc49c6c48bc716df63def3b25c476a414a757) --- .../tests/src/com/android/quickstep/TaplTestsQuickstep.java | 2 ++ tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java | 1 + 2 files changed, 3 insertions(+) diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java index a5038a1fb0..b856e0b560 100644 --- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java +++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java @@ -44,6 +44,7 @@ import com.android.quickstep.views.RecentsView; import org.junit.After; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; @@ -218,6 +219,7 @@ public class TaplTestsQuickstep extends AbstractQuickStepTest { } @Test + @Ignore("b/197802324") @PortraitLandscape public void testAllAppsFromHome() throws Exception { // Test opening all apps diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java index 4dd44f4193..d8576df947 100644 --- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java +++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java @@ -247,6 +247,7 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest { } @Test + @Ignore("b/197802324") @PortraitLandscape public void testWidgets() throws Exception { // Test opening widgets. From 6e72c8bbba3ed580151d71aba9adbbd352fdb076 Mon Sep 17 00:00:00 2001 From: Hyunyoung Song Date: Wed, 25 Aug 2021 02:04:09 -0700 Subject: [PATCH 18/66] All apps memory leak fix / unregister data observer Bug: 197702957 Test: adb shell dumpsys meminfo com.google.android.apps.nexuslauncher, ahat Change-Id: Ia5732cced959e4a199d9c2b59f1f3941a2e23552 --- .../allapps/AllAppsContainerView.java | 6 ++++-- .../launcher3/allapps/AllAppsRecyclerView.java | 18 +++++++++++++----- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java index d2c71b2afe..f420ec2f08 100644 --- a/src/com/android/launcher3/allapps/AllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java @@ -499,8 +499,10 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo private void replaceRVContainer(boolean showTabs) { for (int i = 0; i < mAH.length; i++) { - if (mAH[i].recyclerView != null) { - mAH[i].recyclerView.setLayoutManager(null); + AllAppsRecyclerView rv = mAH[i].recyclerView; + if (rv != null) { + rv.setLayoutManager(null); + rv.setAdapter(null); } } View oldView = getRecyclerViewContainer(); diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java index 2c84a3d4b9..bddbbd00b2 100644 --- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java +++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java @@ -63,6 +63,13 @@ public class AllAppsRecyclerView extends BaseRecyclerView { private final SparseIntArray mCachedScrollPositions = new SparseIntArray(); private final AllAppsFastScrollHelper mFastScrollHelper; + + private final AdapterDataObserver mObserver = new RecyclerView.AdapterDataObserver() { + public void onChanged() { + mCachedScrollPositions.clear(); + } + }; + // The empty-search result background private AllAppsBackgroundDrawable mEmptySearchBackground; private int mEmptySearchBackgroundTopOffset; @@ -247,12 +254,13 @@ public class AllAppsRecyclerView extends BaseRecyclerView { @Override public void setAdapter(Adapter adapter) { + if (getAdapter() != null) { + getAdapter().unregisterAdapterDataObserver(mObserver); + } super.setAdapter(adapter); - adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() { - public void onChanged() { - mCachedScrollPositions.clear(); - } - }); + if (adapter != null) { + adapter.registerAdapterDataObserver(mObserver); + } } @Override From 155a13de9f964ebdd5e8cc5ff5584b10d2810364 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Fri, 27 Aug 2021 05:37:03 +0000 Subject: [PATCH 19/66] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: Ib8df9d449d6109c352a2e537cd425c716e2f017c --- quickstep/res/values-ka/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quickstep/res/values-ka/strings.xml b/quickstep/res/values-ka/strings.xml index ab3715aafb..d9420c826c 100644 --- a/quickstep/res/values-ka/strings.xml +++ b/quickstep/res/values-ka/strings.xml @@ -58,7 +58,7 @@ "გადაფურცლეთ ზემოთ." "თქვენ შეასრულეთ მთავარ ეკრანზე დაბრუნების ჟესტი. ახლა კი შევიტყოთ, თუ როგორ დავბრუნდეთ უკან." "თქვენ შეასრულეთ მთავარ ეკრანზე დაბრუნების ჟესტი." - "მთავარ გვერდზე გადასასვლელად გადაფურცლეთ" + "მთავარი გვერდის სანახავად გადაფურცლეთ" "გადაფურცლეთ ეკრანის ქვედა კიდიდან ზემოთ. ამ ჟესტს ყოველთვის მთავარი გვერდის ეკრანზე გადაყავხართ." "გადაფურცლეთ ეკრანის ქვედა კიდიდან ზემოთ." "უფრო ხანგრძლივად დააჭირეთ თითი ფანჯარას, რომ არ დაიხუროს." From 268fed7bccfb878742df2c3a26f09f751f6e6658 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Fri, 27 Aug 2021 05:37:36 +0000 Subject: [PATCH 20/66] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I432b16f415344cedf760195ccdc303909c67724b --- quickstep/res/values-ka/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quickstep/res/values-ka/strings.xml b/quickstep/res/values-ka/strings.xml index ab3715aafb..d9420c826c 100644 --- a/quickstep/res/values-ka/strings.xml +++ b/quickstep/res/values-ka/strings.xml @@ -58,7 +58,7 @@ "გადაფურცლეთ ზემოთ." "თქვენ შეასრულეთ მთავარ ეკრანზე დაბრუნების ჟესტი. ახლა კი შევიტყოთ, თუ როგორ დავბრუნდეთ უკან." "თქვენ შეასრულეთ მთავარ ეკრანზე დაბრუნების ჟესტი." - "მთავარ გვერდზე გადასასვლელად გადაფურცლეთ" + "მთავარი გვერდის სანახავად გადაფურცლეთ" "გადაფურცლეთ ეკრანის ქვედა კიდიდან ზემოთ. ამ ჟესტს ყოველთვის მთავარი გვერდის ეკრანზე გადაყავხართ." "გადაფურცლეთ ეკრანის ქვედა კიდიდან ზემოთ." "უფრო ხანგრძლივად დააჭირეთ თითი ფანჯარას, რომ არ დაიხუროს." From e44a274170f5e8475d620930fa405a7244bc22cc Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Fri, 27 Aug 2021 05:39:06 +0000 Subject: [PATCH 21/66] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I4560e9785fd11e7beccde0a92d140d90562e436f --- go/quickstep/res/values-gu/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/quickstep/res/values-gu/strings.xml b/go/quickstep/res/values-gu/strings.xml index 28a2d3852d..e1a568f874 100644 --- a/go/quickstep/res/values-gu/strings.xml +++ b/go/quickstep/res/values-gu/strings.xml @@ -4,7 +4,7 @@ "ઍપ શેર કરો" "સાંભળો" "અનુવાદ કરો" - "Lens" + "લેન્સ" "સમજાઈ ગયું" "રદ કરો" "સેટિંગ" From 4c67a7bbf7eba3f9b712f32f86efde2622a6e8aa Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Fri, 27 Aug 2021 05:39:33 +0000 Subject: [PATCH 22/66] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: If885af101a48eff6d7861e8f204df79442d55346 --- go/quickstep/res/values-gu/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/quickstep/res/values-gu/strings.xml b/go/quickstep/res/values-gu/strings.xml index 28a2d3852d..e1a568f874 100644 --- a/go/quickstep/res/values-gu/strings.xml +++ b/go/quickstep/res/values-gu/strings.xml @@ -4,7 +4,7 @@ "ઍપ શેર કરો" "સાંભળો" "અનુવાદ કરો" - "Lens" + "લેન્સ" "સમજાઈ ગયું" "રદ કરો" "સેટિંગ" From 9ecead562966b609f4a3fb157acd2052c64b1588 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Fri, 27 Aug 2021 05:40:37 +0000 Subject: [PATCH 23/66] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I5bfa5dd2771d0823eed4da674991b55202bb5ac6 --- res/values-as/strings.xml | 2 +- res/values-kn/strings.xml | 2 +- res/values-ml/strings.xml | 2 +- res/values-or/strings.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml index 9bc08e3b6d..a66b9b6e46 100644 --- a/res/values-as/strings.xml +++ b/res/values-as/strings.xml @@ -120,7 +120,7 @@ "নতুন এপসমূহৰ বাবে" "অজ্ঞাত" "আঁতৰাওক" - "Search" + "সন্ধান কৰক" "এই এপটো ইনষ্টল কৰা হোৱা নাই" "এই আইকনৰ এপটো ইনষ্টল কৰা হোৱা নাই। আপুনি এইটো আঁতৰাব পাৰে অথবা এপটো বিচাৰি মেনুৱেলভাৱে ইনষ্টল কৰিব পাৰে।" "%1$s ইনষ্টল কৰি থকা হৈছে, %2$s সম্পূৰ্ণ হৈছে" diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml index 3fa8ac76d3..26d1c8c0ec 100644 --- a/res/values-kn/strings.xml +++ b/res/values-kn/strings.xml @@ -120,7 +120,7 @@ "ಹೊಸ ಅಪ್ಲಿಕೇಶನ್‌ಗಳಿಗೆ" "ಅಪರಿಚಿತ" "ತೆಗೆದುಹಾಕಿ" - "Search" + "ಹುಡುಕಿ" "ಈ ಅಪ್ಲಿಕೇಶನ್ ಸ್ಥಾಪನೆಗೊಂಡಿಲ್ಲ" "ಈ ಐಕಾನ್ ಅಪ್ಲಿಕೇಶನ್ ಸ್ಥಾಪನೆಗೊಂಡಿಲ್ಲ. ನೀವು ಅದನ್ನು ತೆಗೆದುಹಾಕಬಹುದು ಅಥವಾ ಅಪ್ಲಿಕೇಶನ್ ಹುಡುಕಬಹುದು ಮತ್ತು ಹಸ್ತಚಾಲಿತವಾಗಿ ಅದನ್ನು ಸ್ಥಾಪಿಸಬಹುದು." "%1$s ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಲಾಗುತ್ತಿದೆ, %2$s ಪೂರ್ಣಗೊಂಡಿದೆ" diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml index f282bd1db4..67b999d1e8 100644 --- a/res/values-ml/strings.xml +++ b/res/values-ml/strings.xml @@ -120,7 +120,7 @@ "പുതിയ ആപ്പുകൾക്ക്" "അജ്ഞാതം" "നീക്കംചെയ്യുക" - "Search" + "തിരയുക" "ഈ അപ്ലിക്കേഷൻ ഇൻസ്റ്റാളുചെയ്‌തിട്ടില്ല" "ഈ ഐക്കണുവേണ്ടി അപ്ലിക്കേഷൻ ഇൻസ്റ്റാളുചെയ്‌തിട്ടില്ല. നിങ്ങൾക്കത് നീക്കംചെയ്യാനാകും അല്ലെങ്കിൽ അപ്ലിക്കേഷനുവേണ്ടി തിരഞ്ഞുകൊണ്ട് അത് സ്വമേധയാ ഇൻസ്റ്റാളുചെയ്യുക." "%1$s ഇൻസ്‌റ്റാൾ ചെയ്യുന്നു, %2$s പൂർത്തിയായി" diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml index b1d644551d..e0f1865ca9 100644 --- a/res/values-or/strings.xml +++ b/res/values-or/strings.xml @@ -120,7 +120,7 @@ "ନୂଆ ଆପ୍‌ ପାଇଁ" "ଅଜଣା" "କାଢ଼ି ଦିଅନ୍ତୁ" - "Search" + "ସନ୍ଧାନ କରନ୍ତୁ" "ଏହି ଆପ୍‌ ଇନଷ୍ଟଲ୍‌ ହୋଇନାହିଁ" "ଏହି ଆଇକନ୍‌ ପାଇଁ ଆପ୍‌ ଇନଷ୍ଟଲ୍‌ ହୋଇନାହିଁ। ଏହାକୁ ଆପଣ ଆପ୍‌ ପାଇଁ ବାହାର କରିପାରିବେ କିମ୍ୱା ସର୍ଚ୍ଚ କରି ପାରିବେ ଏବଂ ଏହାକୁ ମାନୁଆଲ୍‌ ଭାବରେ ଇନଷ୍ଟଲ୍‌ କରିପାରିବେ।" "%1$s ଇନଷ୍ଟଲ୍ କରାଯାଉଛି, %2$s ସମ୍ପୂର୍ଣ୍ଣ ହୋଇଛି" From e57d9636a7531b5ca37c694e74d4e4b4589304f9 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Fri, 27 Aug 2021 05:41:16 +0000 Subject: [PATCH 24/66] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I17fda4d6bb542e6b3dd90db73acaf140ba966e12 --- res/values-as/strings.xml | 2 +- res/values-kn/strings.xml | 2 +- res/values-ml/strings.xml | 2 +- res/values-or/strings.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml index 9bc08e3b6d..a66b9b6e46 100644 --- a/res/values-as/strings.xml +++ b/res/values-as/strings.xml @@ -120,7 +120,7 @@ "নতুন এপসমূহৰ বাবে" "অজ্ঞাত" "আঁতৰাওক" - "Search" + "সন্ধান কৰক" "এই এপটো ইনষ্টল কৰা হোৱা নাই" "এই আইকনৰ এপটো ইনষ্টল কৰা হোৱা নাই। আপুনি এইটো আঁতৰাব পাৰে অথবা এপটো বিচাৰি মেনুৱেলভাৱে ইনষ্টল কৰিব পাৰে।" "%1$s ইনষ্টল কৰি থকা হৈছে, %2$s সম্পূৰ্ণ হৈছে" diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml index 3fa8ac76d3..26d1c8c0ec 100644 --- a/res/values-kn/strings.xml +++ b/res/values-kn/strings.xml @@ -120,7 +120,7 @@ "ಹೊಸ ಅಪ್ಲಿಕೇಶನ್‌ಗಳಿಗೆ" "ಅಪರಿಚಿತ" "ತೆಗೆದುಹಾಕಿ" - "Search" + "ಹುಡುಕಿ" "ಈ ಅಪ್ಲಿಕೇಶನ್ ಸ್ಥಾಪನೆಗೊಂಡಿಲ್ಲ" "ಈ ಐಕಾನ್ ಅಪ್ಲಿಕೇಶನ್ ಸ್ಥಾಪನೆಗೊಂಡಿಲ್ಲ. ನೀವು ಅದನ್ನು ತೆಗೆದುಹಾಕಬಹುದು ಅಥವಾ ಅಪ್ಲಿಕೇಶನ್ ಹುಡುಕಬಹುದು ಮತ್ತು ಹಸ್ತಚಾಲಿತವಾಗಿ ಅದನ್ನು ಸ್ಥಾಪಿಸಬಹುದು." "%1$s ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಲಾಗುತ್ತಿದೆ, %2$s ಪೂರ್ಣಗೊಂಡಿದೆ" diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml index f282bd1db4..67b999d1e8 100644 --- a/res/values-ml/strings.xml +++ b/res/values-ml/strings.xml @@ -120,7 +120,7 @@ "പുതിയ ആപ്പുകൾക്ക്" "അജ്ഞാതം" "നീക്കംചെയ്യുക" - "Search" + "തിരയുക" "ഈ അപ്ലിക്കേഷൻ ഇൻസ്റ്റാളുചെയ്‌തിട്ടില്ല" "ഈ ഐക്കണുവേണ്ടി അപ്ലിക്കേഷൻ ഇൻസ്റ്റാളുചെയ്‌തിട്ടില്ല. നിങ്ങൾക്കത് നീക്കംചെയ്യാനാകും അല്ലെങ്കിൽ അപ്ലിക്കേഷനുവേണ്ടി തിരഞ്ഞുകൊണ്ട് അത് സ്വമേധയാ ഇൻസ്റ്റാളുചെയ്യുക." "%1$s ഇൻസ്‌റ്റാൾ ചെയ്യുന്നു, %2$s പൂർത്തിയായി" diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml index b1d644551d..e0f1865ca9 100644 --- a/res/values-or/strings.xml +++ b/res/values-or/strings.xml @@ -120,7 +120,7 @@ "ନୂଆ ଆପ୍‌ ପାଇଁ" "ଅଜଣା" "କାଢ଼ି ଦିଅନ୍ତୁ" - "Search" + "ସନ୍ଧାନ କରନ୍ତୁ" "ଏହି ଆପ୍‌ ଇନଷ୍ଟଲ୍‌ ହୋଇନାହିଁ" "ଏହି ଆଇକନ୍‌ ପାଇଁ ଆପ୍‌ ଇନଷ୍ଟଲ୍‌ ହୋଇନାହିଁ। ଏହାକୁ ଆପଣ ଆପ୍‌ ପାଇଁ ବାହାର କରିପାରିବେ କିମ୍ୱା ସର୍ଚ୍ଚ କରି ପାରିବେ ଏବଂ ଏହାକୁ ମାନୁଆଲ୍‌ ଭାବରେ ଇନଷ୍ଟଲ୍‌ କରିପାରିବେ।" "%1$s ଇନଷ୍ଟଲ୍ କରାଯାଉଛି, %2$s ସମ୍ପୂର୍ଣ୍ଣ ହୋଇଛି" From 349c7c82f46c91577b7bd0548e470c0f957a69eb Mon Sep 17 00:00:00 2001 From: Hyunyoung Song Date: Wed, 25 Aug 2021 02:04:09 -0700 Subject: [PATCH 25/66] All apps memory leak fix / unregister data observer Bug: 197702957 Test: adb shell dumpsys meminfo com.google.android.apps.nexuslauncher, ahat Change-Id: Ia5732cced959e4a199d9c2b59f1f3941a2e23552 Merged-In: Ia5732cced959e4a199d9c2b59f1f3941a2e23552 (cherry picked from commit 6e72c8bbba3ed580151d71aba9adbbd352fdb076) --- .../allapps/AllAppsContainerView.java | 6 ++++-- .../launcher3/allapps/AllAppsRecyclerView.java | 18 +++++++++++++----- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java index d2c71b2afe..f420ec2f08 100644 --- a/src/com/android/launcher3/allapps/AllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java @@ -499,8 +499,10 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo private void replaceRVContainer(boolean showTabs) { for (int i = 0; i < mAH.length; i++) { - if (mAH[i].recyclerView != null) { - mAH[i].recyclerView.setLayoutManager(null); + AllAppsRecyclerView rv = mAH[i].recyclerView; + if (rv != null) { + rv.setLayoutManager(null); + rv.setAdapter(null); } } View oldView = getRecyclerViewContainer(); diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java index 2c84a3d4b9..bddbbd00b2 100644 --- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java +++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java @@ -63,6 +63,13 @@ public class AllAppsRecyclerView extends BaseRecyclerView { private final SparseIntArray mCachedScrollPositions = new SparseIntArray(); private final AllAppsFastScrollHelper mFastScrollHelper; + + private final AdapterDataObserver mObserver = new RecyclerView.AdapterDataObserver() { + public void onChanged() { + mCachedScrollPositions.clear(); + } + }; + // The empty-search result background private AllAppsBackgroundDrawable mEmptySearchBackground; private int mEmptySearchBackgroundTopOffset; @@ -247,12 +254,13 @@ public class AllAppsRecyclerView extends BaseRecyclerView { @Override public void setAdapter(Adapter adapter) { + if (getAdapter() != null) { + getAdapter().unregisterAdapterDataObserver(mObserver); + } super.setAdapter(adapter); - adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() { - public void onChanged() { - mCachedScrollPositions.clear(); - } - }); + if (adapter != null) { + adapter.registerAdapterDataObserver(mObserver); + } } @Override From ee44c4dc1ee00e126334a0505b9c95850f3bdc73 Mon Sep 17 00:00:00 2001 From: Vadim Caen Date: Fri, 27 Aug 2021 19:17:03 +0200 Subject: [PATCH 26/66] Disable splash screen for launches from widget. The transition from a widget to the splash screen icon feels odd because of the difference in shapes. Disable for S and rework that in T. Test: Manually tested with clock and Calendar Bug: 197504657 Change-Id: Ia375885af967d6ad282dcc7325ad905731c8734d --- .../launcher3/uioverrides/QuickstepInteractionHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java index c2c721adf8..1cf50f7f64 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java @@ -71,7 +71,7 @@ class QuickstepInteractionHandler implements RemoteViews.InteractionHandler { } } activityOptions.options.setPendingIntentLaunchFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - activityOptions.options.setSplashscreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_ICON); + activityOptions.options.setSplashscreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_EMPTY); Object itemInfo = hostView.getTag(); if (itemInfo instanceof ItemInfo) { mLauncher.addLaunchCookie((ItemInfo) itemInfo, activityOptions.options); From 61212d12f949ebc00f15d163a0ff9a62d2263696 Mon Sep 17 00:00:00 2001 From: y Date: Wed, 25 Aug 2021 11:58:46 -0700 Subject: [PATCH 27/66] [Work] Fix duplicate work button issue Bug: 195623679 Test: manual Change-Id: I882c5f7a196e07fa0dab3a2f27437abd233ec782 (cherry picked from commit cb5bb989e3e8b2d0b43f8a97aeefdfc1389eeaae) --- .../allapps/AllAppsContainerView.java | 20 ++++++++++--------- .../launcher3/allapps/WorkModeSwitch.java | 12 +++++------ 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java index f420ec2f08..9c61c1b69f 100644 --- a/src/com/android/launcher3/allapps/AllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java @@ -454,7 +454,6 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo mAllAppsStore.unregisterIconContainer(mAH[AdapterHolder.WORK].recyclerView); if (mUsingTabs) { - setupWorkToggle(); mAH[AdapterHolder.MAIN].setup(mViewPager.getChildAt(0), mPersonalMatcher); mAH[AdapterHolder.WORK].setup(mViewPager.getChildAt(1), mWorkMatcher); mAH[AdapterHolder.WORK].recyclerView.setId(R.id.apps_list_view_work); @@ -485,6 +484,7 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo } private void setupWorkToggle() { + removeWorkToggle(); if (Utilities.ATLEAST_P) { mWorkModeSwitch = (WorkModeSwitch) mLauncher.getLayoutInflater().inflate( R.layout.work_mode_fab, this, false); @@ -497,6 +497,14 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo } } + private void removeWorkToggle() { + if (mWorkModeSwitch == null) return; + if (mWorkModeSwitch.getParent() == this) { + this.removeView(mWorkModeSwitch); + } + mWorkModeSwitch = null; + } + private void replaceRVContainer(boolean showTabs) { for (int i = 0; i < mAH.length; i++) { AllAppsRecyclerView rv = mAH[i].recyclerView; @@ -519,8 +527,10 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo mViewPager = (AllAppsPagedView) newView; mViewPager.initParentViews(this); mViewPager.getPageIndicator().setOnActivePageChangedListener(this); + setupWorkToggle(); } else { mViewPager = null; + removeWorkToggle(); } } @@ -539,14 +549,6 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo mWorkModeSwitch.setWorkTabVisible(currentActivePage == AdapterHolder.WORK && mAllAppsStore.hasModelFlag( FLAG_HAS_SHORTCUT_PERMISSION | FLAG_QUIET_MODE_CHANGE_PERMISSION)); - - if (currentActivePage == AdapterHolder.WORK) { - if (mWorkModeSwitch.getParent() == null) { - addView(mWorkModeSwitch); - } - } else { - removeView(mWorkModeSwitch); - } } } diff --git a/src/com/android/launcher3/allapps/WorkModeSwitch.java b/src/com/android/launcher3/allapps/WorkModeSwitch.java index a800d34758..5d3af08b46 100644 --- a/src/com/android/launcher3/allapps/WorkModeSwitch.java +++ b/src/com/android/launcher3/allapps/WorkModeSwitch.java @@ -51,6 +51,7 @@ public class WorkModeSwitch extends Button implements Insettable, View.OnClickLi @Nullable private KeyboardInsetAnimationCallback mKeyboardInsetAnimationCallback; + private boolean mWorkTabVisible; public WorkModeSwitch(Context context) { this(context, null, 0); @@ -91,11 +92,10 @@ public class WorkModeSwitch extends Button implements Insettable, View.OnClickLi */ public void setWorkTabVisible(boolean workTabVisible) { clearAnimation(); - if (workTabVisible) { + mWorkTabVisible = workTabVisible; + if (workTabVisible && mWorkEnabled) { setEnabled(true); - if (mWorkEnabled) { - setVisibility(VISIBLE); - } + setVisibility(VISIBLE); setAlpha(0); animate().alpha(1).start(); } else { @@ -105,7 +105,7 @@ public class WorkModeSwitch extends Button implements Insettable, View.OnClickLi @Override public void onClick(View view) { - if (Utilities.ATLEAST_P) { + if (Utilities.ATLEAST_P && mWorkTabVisible) { setEnabled(false); Launcher.fromContext(getContext()).getStatsLogManager().logger().log( LAUNCHER_TURN_OFF_WORK_APPS_TAP); @@ -137,7 +137,7 @@ public class WorkModeSwitch extends Button implements Insettable, View.OnClickLi @Override public WindowInsets onApplyWindowInsets(WindowInsets insets) { - if (Utilities.ATLEAST_R) { + if (Utilities.ATLEAST_R && mWorkTabVisible) { setTranslationY(0); if (insets.isVisible(WindowInsets.Type.ime())) { Insets keyboardInsets = insets.getInsets(WindowInsets.Type.ime()); From f3bbd98bf8958f593c08c70539ba9815b97ce908 Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Fri, 13 Aug 2021 13:53:14 -0700 Subject: [PATCH 28/66] Allow users to dismiss notifications in popup view. Bug: 193014051 Test: - dismiss notifications (left/right) - open popup, dismiss notification from shade and ensure popup gets updates - open popup, trigger new notification and ensure popup gets updated Change-Id: Iea4d458218cbf5cb22f5f89aa0a4cc1bee18cc73 --- res/layout/notification_content.xml | 12 +- res/layout/popup_container.xml | 7 +- res/values/dimens.xml | 2 + .../notification/NotificationContainer.java | 283 ++++++++++++++++++ .../notification/NotificationItemView.java | 179 ----------- .../notification/NotificationMainView.java | 231 +++++++++++--- .../android/launcher3/popup/ArrowPopup.java | 7 + .../popup/PopupContainerWithArrow.java | 57 ++-- 8 files changed, 513 insertions(+), 265 deletions(-) create mode 100644 src/com/android/launcher3/notification/NotificationContainer.java delete mode 100644 src/com/android/launcher3/notification/NotificationItemView.java diff --git a/res/layout/notification_content.xml b/res/layout/notification_content.xml index 84822a671b..91897e9e75 100644 --- a/res/layout/notification_content.xml +++ b/res/layout/notification_content.xml @@ -14,10 +14,11 @@ limitations under the License. --> - + android:layout_height="wrap_content" + android:orientation="vertical"> - - - \ No newline at end of file + + \ No newline at end of file diff --git a/res/layout/popup_container.xml b/res/layout/popup_container.xml index 18014bb1d0..9327287018 100644 --- a/res/layout/popup_container.xml +++ b/res/layout/popup_container.xml @@ -31,12 +31,9 @@ android:elevation="@dimen/deep_shortcuts_elevation" android:orientation="vertical"/> - + android:visibility="gone"/> \ No newline at end of file diff --git a/res/values/dimens.xml b/res/values/dimens.xml index f434644996..7d8012fb12 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -271,6 +271,8 @@ 8dp + 8dp + 8dp 16dp 18dp 14sp diff --git a/src/com/android/launcher3/notification/NotificationContainer.java b/src/com/android/launcher3/notification/NotificationContainer.java new file mode 100644 index 0000000000..9eb05cd40f --- /dev/null +++ b/src/com/android/launcher3/notification/NotificationContainer.java @@ -0,0 +1,283 @@ +/* + * Copyright (C) 2021 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.notification; + +import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity; +import static com.android.launcher3.touch.SingleAxisSwipeDetector.HORIZONTAL; + +import android.animation.Animator; +import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; +import android.content.Context; +import android.graphics.Rect; +import android.util.AttributeSet; +import android.util.FloatProperty; +import android.view.MotionEvent; +import android.view.View; +import android.widget.FrameLayout; + +import com.android.launcher3.R; +import com.android.launcher3.anim.AnimationSuccessListener; +import com.android.launcher3.popup.PopupContainerWithArrow; +import com.android.launcher3.touch.BaseSwipeDetector; +import com.android.launcher3.touch.OverScroll; +import com.android.launcher3.touch.SingleAxisSwipeDetector; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * Class to manage the notification UI in a {@link PopupContainerWithArrow}. + * + * - Has two {@link NotificationMainView} that represent the top two notifications + * - Handles dismissing a notification + */ +public class NotificationContainer extends FrameLayout implements SingleAxisSwipeDetector.Listener { + + private static final FloatProperty DRAG_TRANSLATION_X = + new FloatProperty("notificationProgress") { + @Override + public void setValue(NotificationContainer view, float transX) { + view.setDragTranslationX(transX); + } + + @Override + public Float get(NotificationContainer view) { + return view.mDragTranslationX; + } + }; + + private static final Rect sTempRect = new Rect(); + + private final SingleAxisSwipeDetector mSwipeDetector; + private final List mNotificationInfos = new ArrayList<>(); + private boolean mIgnoreTouch = false; + + private final ObjectAnimator mContentTranslateAnimator; + private float mDragTranslationX = 0; + + private final NotificationMainView mPrimaryView; + private final NotificationMainView mSecondaryView; + private PopupContainerWithArrow mPopupContainer; + + public NotificationContainer(Context context) { + this(context, null, 0); + } + + public NotificationContainer(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public NotificationContainer(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + mSwipeDetector = new SingleAxisSwipeDetector(getContext(), this, HORIZONTAL); + mSwipeDetector.setDetectableScrollConditions(SingleAxisSwipeDetector.DIRECTION_BOTH, false); + mContentTranslateAnimator = ObjectAnimator.ofFloat(this, DRAG_TRANSLATION_X, 0); + + mPrimaryView = (NotificationMainView) View.inflate(getContext(), + R.layout.notification_content, null); + mSecondaryView = (NotificationMainView) View.inflate(getContext(), + R.layout.notification_content, null); + mSecondaryView.setAlpha(0); + + addView(mSecondaryView); + addView(mPrimaryView); + + } + + public void setPopupView(PopupContainerWithArrow popupView) { + mPopupContainer = popupView; + } + + /** + * Returns true if we should intercept the swipe. + */ + public boolean onInterceptSwipeEvent(MotionEvent ev) { + if (ev.getAction() == MotionEvent.ACTION_DOWN) { + sTempRect.set(getLeft(), getTop(), getRight(), getBottom()); + mIgnoreTouch = !sTempRect.contains((int) ev.getX(), (int) ev.getY()); + if (!mIgnoreTouch) { + mPopupContainer.getParent().requestDisallowInterceptTouchEvent(true); + } + } + if (mIgnoreTouch) { + return false; + } + if (mPrimaryView.getNotificationInfo() == null) { + // The notification hasn't been populated yet. + return false; + } + + mSwipeDetector.onTouchEvent(ev); + return mSwipeDetector.isDraggingOrSettling(); + } + + /** + * Returns true when we should handle the swipe. + */ + public boolean onSwipeEvent(MotionEvent ev) { + if (mIgnoreTouch) { + return false; + } + if (mPrimaryView.getNotificationInfo() == null) { + // The notification hasn't been populated yet. + return false; + } + return mSwipeDetector.onTouchEvent(ev); + } + + /** + * Applies the list of @param notificationInfos to this container. + */ + public void applyNotificationInfos(final List notificationInfos) { + mNotificationInfos.clear(); + if (notificationInfos.isEmpty()) { + mPrimaryView.applyNotificationInfo(null); + mSecondaryView.applyNotificationInfo(null); + return; + } + mNotificationInfos.addAll(notificationInfos); + + NotificationInfo mainNotification = notificationInfos.get(0); + mPrimaryView.applyNotificationInfo(mainNotification); + mSecondaryView.applyNotificationInfo(notificationInfos.size() > 1 + ? notificationInfos.get(1) + : null); + } + + /** + * Trims the notifications. + * @param notificationKeys List of all valid notification keys. + */ + public void trimNotifications(final List notificationKeys) { + Iterator iterator = mNotificationInfos.iterator(); + while (iterator.hasNext()) { + if (!notificationKeys.contains(iterator.next().notificationKey)) { + iterator.remove(); + } + } + + NotificationInfo primaryInfo = mNotificationInfos.size() > 0 + ? mNotificationInfos.get(0) + : null; + NotificationInfo secondaryInfo = mNotificationInfos.size() > 1 + ? mNotificationInfos.get(1) + : null; + + mPrimaryView.applyNotificationInfo(primaryInfo); + mSecondaryView.applyNotificationInfo(secondaryInfo); + + mPrimaryView.onPrimaryDrag(0); + mSecondaryView.onSecondaryDrag(0); + } + + private void setDragTranslationX(float translationX) { + mDragTranslationX = translationX; + + float progress = translationX / getWidth(); + mPrimaryView.onPrimaryDrag(progress); + if (mSecondaryView.getNotificationInfo() == null) { + mSecondaryView.setAlpha(0f); + } else { + mSecondaryView.onSecondaryDrag(progress); + } + } + + // SingleAxisSwipeDetector.Listener's + @Override + public void onDragStart(boolean start, float startDisplacement) { + mPopupContainer.showArrow(false); + } + + @Override + public boolean onDrag(float displacement) { + if (!mPrimaryView.canChildBeDismissed()) { + displacement = OverScroll.dampedScroll(displacement, getWidth()); + } + + float progress = displacement / getWidth(); + mPrimaryView.onPrimaryDrag(progress); + if (mSecondaryView.getNotificationInfo() == null) { + mSecondaryView.setAlpha(0f); + } else { + mSecondaryView.onSecondaryDrag(progress); + } + mContentTranslateAnimator.cancel(); + return true; + } + + @Override + public void onDragEnd(float velocity) { + final boolean willExit; + final float endTranslation; + final float startTranslation = mPrimaryView.getTranslationX(); + final float width = getWidth(); + + if (!mPrimaryView.canChildBeDismissed()) { + willExit = false; + endTranslation = 0; + } else if (mSwipeDetector.isFling(velocity)) { + willExit = true; + endTranslation = velocity < 0 ? -width : width; + } else if (Math.abs(startTranslation) > width / 2f) { + willExit = true; + endTranslation = (startTranslation < 0 ? -width : width); + } else { + willExit = false; + endTranslation = 0; + } + + long duration = BaseSwipeDetector.calculateDuration(velocity, + (endTranslation - startTranslation) / width); + + mContentTranslateAnimator.removeAllListeners(); + mContentTranslateAnimator.setDuration(duration) + .setInterpolator(scrollInterpolatorForVelocity(velocity)); + mContentTranslateAnimator.setFloatValues(startTranslation, endTranslation); + + NotificationMainView current = mPrimaryView; + mContentTranslateAnimator.addListener(new AnimationSuccessListener() { + @Override + public void onAnimationSuccess(Animator animator) { + mSwipeDetector.finishedScrolling(); + if (willExit) { + current.onChildDismissed(); + } + mPopupContainer.showArrow(true); + } + }); + mContentTranslateAnimator.start(); + } + + /** + * Animates the background color to a new color. + * @param color The color to change to. + * @param animatorSetOut The AnimatorSet where we add the color animator to. + */ + public void updateBackgroundColor(int color, AnimatorSet animatorSetOut) { + mPrimaryView.updateBackgroundColor(color, animatorSetOut); + mSecondaryView.updateBackgroundColor(color, animatorSetOut); + } + + /** + * Updates the header with a new @param notificationCount. + */ + public void updateHeader(int notificationCount) { + mPrimaryView.updateHeader(notificationCount); + mSecondaryView.updateHeader(notificationCount - 1); + } +} diff --git a/src/com/android/launcher3/notification/NotificationItemView.java b/src/com/android/launcher3/notification/NotificationItemView.java deleted file mode 100644 index af943a6933..0000000000 --- a/src/com/android/launcher3/notification/NotificationItemView.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.launcher3.notification; - -import android.animation.AnimatorSet; -import android.content.Context; -import android.graphics.Outline; -import android.graphics.Rect; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewGroup.MarginLayoutParams; -import android.view.ViewOutlineProvider; -import android.widget.TextView; - -import com.android.launcher3.R; -import com.android.launcher3.popup.PopupContainerWithArrow; -import com.android.launcher3.util.Themes; - -import java.util.ArrayList; -import java.util.List; - -/** - * Utility class to manage notification UI - */ -public class NotificationItemView { - - private static final Rect sTempRect = new Rect(); - - private final Context mContext; - private final PopupContainerWithArrow mPopupContainer; - private final ViewGroup mRootView; - - private final TextView mHeaderCount; - private final NotificationMainView mMainView; - - private final View mHeader; - - private View mGutter; - - private boolean mIgnoreTouch = false; - private List mNotificationInfos = new ArrayList<>(); - - public NotificationItemView(PopupContainerWithArrow container, ViewGroup rootView) { - mPopupContainer = container; - mRootView = rootView; - mContext = container.getContext(); - - mHeaderCount = container.findViewById(R.id.notification_count); - mMainView = container.findViewById(R.id.main_view); - - mHeader = container.findViewById(R.id.header); - - float radius = Themes.getDialogCornerRadius(mContext); - rootView.setClipToOutline(true); - rootView.setOutlineProvider(new ViewOutlineProvider() { - @Override - public void getOutline(View view, Outline outline) { - outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), radius); - } - }); - } - - /** - * Animates the background color to a new color. - * @param color The color to change to. - * @param animatorSetOut The AnimatorSet where we add the color animator to. - */ - public void updateBackgroundColor(int color, AnimatorSet animatorSetOut) { - mMainView.updateBackgroundColor(color, animatorSetOut); - } - - public void addGutter() { - if (mGutter == null) { - mGutter = mPopupContainer.inflateAndAdd(R.layout.notification_gutter, mRootView); - } - } - - public void inverseGutterMargin() { - MarginLayoutParams lp = (MarginLayoutParams) mGutter.getLayoutParams(); - int top = lp.topMargin; - lp.topMargin = lp.bottomMargin; - lp.bottomMargin = top; - } - - public void removeAllViews() { - mRootView.removeView(mMainView); - mRootView.removeView(mHeader); - if (mGutter != null) { - mRootView.removeView(mGutter); - } - } - - /** - * Updates the header text. - * @param notificationCount The number of notifications. - */ - public void updateHeader(int notificationCount) { - final String text; - final int visibility; - if (notificationCount <= 1) { - text = ""; - visibility = View.INVISIBLE; - } else { - text = String.valueOf(notificationCount); - visibility = View.VISIBLE; - - } - mHeaderCount.setText(text); - mHeaderCount.setVisibility(visibility); - } - - public boolean onInterceptTouchEvent(MotionEvent ev) { - if (ev.getAction() == MotionEvent.ACTION_DOWN) { - sTempRect.set(mRootView.getLeft(), mRootView.getTop(), - mRootView.getRight(), mRootView.getBottom()); - mIgnoreTouch = !sTempRect.contains((int) ev.getX(), (int) ev.getY()); - if (!mIgnoreTouch) { - mPopupContainer.getParent().requestDisallowInterceptTouchEvent(true); - } - } - if (mIgnoreTouch) { - return false; - } - if (mMainView.getNotificationInfo() == null) { - // The notification hasn't been populated yet. - return false; - } - - return false; - } - - public void applyNotificationInfos(final List notificationInfos) { - mNotificationInfos.clear(); - if (notificationInfos.isEmpty()) { - return; - } - mNotificationInfos.addAll(notificationInfos); - - NotificationInfo mainNotification = notificationInfos.get(0); - mMainView.applyNotificationInfo(mainNotification, false); - } - - public void trimNotifications(final List notificationKeys) { - NotificationInfo currentMainNotificationInfo = mMainView.getNotificationInfo(); - boolean shouldUpdateMainNotification = !notificationKeys.contains( - currentMainNotificationInfo.notificationKey); - - if (shouldUpdateMainNotification) { - int size = notificationKeys.size(); - NotificationInfo nextNotification = null; - // We get the latest notification by finding the notification after the one that was - // just dismissed. - for (int i = 0; i < size; ++i) { - if (currentMainNotificationInfo == mNotificationInfos.get(i) && i + 1 < size) { - nextNotification = mNotificationInfos.get(i + 1); - break; - } - } - if (nextNotification != null) { - mMainView.applyNotificationInfo(nextNotification, true); - } - } - } -} diff --git a/src/com/android/launcher3/notification/NotificationMainView.java b/src/com/android/launcher3/notification/NotificationMainView.java index b8aa8246fb..f9ff8a6e56 100644 --- a/src/com/android/launcher3/notification/NotificationMainView.java +++ b/src/com/android/launcher3/notification/NotificationMainView.java @@ -16,62 +16,70 @@ package com.android.launcher3.notification; +import static com.android.launcher3.Utilities.mapToRange; +import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NOTIFICATION_DISMISSED; import android.animation.AnimatorSet; -import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.annotation.TargetApi; import android.content.Context; -import android.graphics.Color; -import android.graphics.drawable.ColorDrawable; +import android.graphics.Outline; +import android.graphics.Rect; +import android.graphics.drawable.GradientDrawable; import android.os.Build; import android.text.TextUtils; import android.util.AttributeSet; -import android.util.FloatProperty; import android.view.View; import android.view.ViewGroup; -import android.widget.FrameLayout; +import android.view.ViewOutlineProvider; +import android.widget.LinearLayout; import android.widget.TextView; +import androidx.annotation.Nullable; + import com.android.launcher3.Launcher; import com.android.launcher3.R; +import com.android.launcher3.Utilities; import com.android.launcher3.model.data.ItemInfo; -import com.android.launcher3.touch.SingleAxisSwipeDetector; +import com.android.launcher3.util.Themes; /** * A {@link android.widget.FrameLayout} that contains a single notification, * e.g. icon + title + text. */ @TargetApi(Build.VERSION_CODES.N) -public class NotificationMainView extends FrameLayout { - - private static final FloatProperty CONTENT_TRANSLATION = - new FloatProperty("contentTranslation") { - @Override - public void setValue(NotificationMainView view, float v) { - view.setContentTranslation(v); - } - - @Override - public Float get(NotificationMainView view) { - return view.mTextAndBackground.getTranslationX(); - } - }; +public class NotificationMainView extends LinearLayout { // This is used only to track the notification view, so that it can be properly logged. public static final ItemInfo NOTIFICATION_ITEM_INFO = new ItemInfo(); + // Value when the primary notification main view will be gone (zero alpha). + private static final float PRIMARY_GONE_PROGRESS = 0.7f; + private static final float PRIMARY_MIN_PROGRESS = 0.40f; + private static final float PRIMARY_MAX_PROGRESS = 0.60f; + private static final float SECONDARY_MIN_PROGRESS = 0.30f; + private static final float SECONDARY_MAX_PROGRESS = 0.50f; + private static final float SECONDARY_CONTENT_MAX_PROGRESS = 0.6f; + private NotificationInfo mNotificationInfo; - private ViewGroup mTextAndBackground; private int mBackgroundColor; private TextView mTitleView; private TextView mTextView; private View mIconView; - private SingleAxisSwipeDetector mSwipeDetector; + private View mHeader; + private View mMainView; - private final ColorDrawable mColorDrawable; + private TextView mHeaderCount; + private final Rect mOutline = new Rect(); + + // Space between notifications during swipe + private final int mNotificationSpace; + private final int mMaxTransX; + private final int mMaxElevation; + + private final GradientDrawable mBackground; public NotificationMainView(Context context) { this(context, null, 0); @@ -82,28 +90,77 @@ public class NotificationMainView extends FrameLayout { } public NotificationMainView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); + this(context, attrs, defStyle, 0); + } - mColorDrawable = new ColorDrawable(Color.TRANSPARENT); + public NotificationMainView(Context context, AttributeSet attrs, int defStyle, int defStylRes) { + super(context, attrs, defStyle, defStylRes); + + float outlineRadius = Themes.getDialogCornerRadius(context); + + mBackground = new GradientDrawable(); + mBackground.setColor(Themes.getAttrColor(context, R.attr.popupColorPrimary)); + mBackground.setCornerRadius(outlineRadius); + setBackground(mBackground); + + mMaxElevation = getResources().getDimensionPixelSize(R.dimen.deep_shortcuts_elevation); + setElevation(mMaxElevation); + + mMaxTransX = getResources().getDimensionPixelSize(R.dimen.notification_max_trans); + mNotificationSpace = getResources().getDimensionPixelSize(R.dimen.notification_space); + + setClipToOutline(true); + setOutlineProvider(new ViewOutlineProvider() { + @Override + public void getOutline(View view, Outline outline) { + outline.setRoundRect(mOutline, outlineRadius); + } + }); + } + + /** + * Updates the header text. + * @param notificationCount The number of notifications. + */ + public void updateHeader(int notificationCount) { + final String text; + final int visibility; + if (notificationCount <= 1) { + text = ""; + visibility = View.INVISIBLE; + } else { + text = String.valueOf(notificationCount); + visibility = View.VISIBLE; + + } + mHeaderCount.setText(text); + mHeaderCount.setVisibility(visibility); } @Override protected void onFinishInflate() { super.onFinishInflate(); - mTextAndBackground = findViewById(R.id.text_and_background); - mTitleView = mTextAndBackground.findViewById(R.id.title); - mTextView = mTextAndBackground.findViewById(R.id.text); + ViewGroup textAndBackground = findViewById(R.id.text_and_background); + mTitleView = textAndBackground.findViewById(R.id.title); + mTextView = textAndBackground.findViewById(R.id.text); mIconView = findViewById(R.id.popup_item_icon); + mHeaderCount = findViewById(R.id.notification_count); - ColorDrawable colorBackground = (ColorDrawable) mTextAndBackground.getBackground(); - updateBackgroundColor(colorBackground.getColor()); + mHeader = findViewById(R.id.header); + mMainView = findViewById(R.id.main_view); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + mOutline.set(0, 0, getWidth(), getHeight()); + invalidateOutline(); } private void updateBackgroundColor(int color) { mBackgroundColor = color; - mColorDrawable.setColor(color); - mTextAndBackground.setBackground(mColorDrawable); + mBackground.setColor(color); if (mNotificationInfo != null) { mIconView.setBackground(mNotificationInfo.getIconForBackground(getContext(), mBackgroundColor)); @@ -128,8 +185,11 @@ public class NotificationMainView extends FrameLayout { /** * Sets the content of this view, animating it after a new icon shifts up if necessary. */ - public void applyNotificationInfo(NotificationInfo mainNotification, boolean animate) { - mNotificationInfo = mainNotification; + public void applyNotificationInfo(NotificationInfo notificationInfo) { + mNotificationInfo = notificationInfo; + if (notificationInfo == null) { + return; + } NotificationListener listener = NotificationListener.getInstanceIfConnected(); if (listener != null) { listener.setNotificationsShown(new String[] {mNotificationInfo.notificationKey}); @@ -149,25 +209,112 @@ public class NotificationMainView extends FrameLayout { if (mNotificationInfo.intent != null) { setOnClickListener(mNotificationInfo); } - setContentTranslation(0); + // Add a stub ItemInfo so that logging populates the correct container and item types // instead of DEFAULT_CONTAINERTYPE and DEFAULT_ITEMTYPE, respectively. setTag(NOTIFICATION_ITEM_INFO); - if (animate) { - ObjectAnimator.ofFloat(mTextAndBackground, ALPHA, 0, 1).setDuration(150).start(); + } + + /** + * Sets the alpha of only the child views. + */ + public void setContentAlpha(float alpha) { + mHeader.setAlpha(alpha); + mMainView.setAlpha(alpha); + } + + /** + * Sets the translation of only the child views. + */ + public void setContentTranslationX(float transX) { + mHeader.setTranslationX(transX); + mMainView.setTranslationX(transX); + } + + /** + * Updates the alpha, content alpha, and elevation of this view. + * + * @param progress Range from [0, 1] or [-1, 0] + * When 0: Full alpha + * When 1/-1: zero alpha + */ + public void onPrimaryDrag(float progress) { + float absProgress = Math.abs(progress); + final int width = getWidth(); + + float min = PRIMARY_MIN_PROGRESS; + float max = PRIMARY_MAX_PROGRESS; + + if (absProgress < min) { + setAlpha(1f); + setContentAlpha(1); + setElevation(mMaxElevation); + } else if (absProgress < max) { + setAlpha(1f); + setContentAlpha(mapToRange(absProgress, min, max, 1f, 0f, LINEAR)); + setElevation(Utilities.mapToRange(absProgress, min, max, mMaxElevation, 0, LINEAR)); + } else { + setAlpha(mapToRange(absProgress, max, PRIMARY_GONE_PROGRESS, 1f, 0f, LINEAR)); + setContentAlpha(0f); + setElevation(0f); } + + setTranslationX(width * progress); } - public void setContentTranslation(float translation) { - mTextAndBackground.setTranslationX(translation); - mIconView.setTranslationX(translation); + /** + * Updates the alpha, content alpha, elevation, and clipping of this view. + * @param progress Range from [0, 1] or [-1, 0] + * When 0: Smallest clipping, zero alpha + * When 1/-1: Full clip, full alpha + */ + public void onSecondaryDrag(float progress) { + final float absProgress = Math.abs(progress); + + float min = SECONDARY_MIN_PROGRESS; + float max = SECONDARY_MAX_PROGRESS; + float contentMax = SECONDARY_CONTENT_MAX_PROGRESS; + + if (absProgress < min) { + setAlpha(0f); + setContentAlpha(0); + setElevation(0f); + } else if (absProgress < max) { + setAlpha(mapToRange(absProgress, min, max, 0, 1f, LINEAR)); + setContentAlpha(0f); + setElevation(0f); + } else { + setAlpha(1f); + setContentAlpha(absProgress > contentMax + ? 1f + : mapToRange(absProgress, max, contentMax, 0, 1f, LINEAR)); + setElevation(Utilities.mapToRange(absProgress, max, 1, 0, mMaxElevation, LINEAR)); + } + + final int width = getWidth(); + int crop = (int) (width * absProgress); + int space = (int) (absProgress > PRIMARY_GONE_PROGRESS + ? mapToRange(absProgress, PRIMARY_GONE_PROGRESS, 1f, mNotificationSpace, 0, LINEAR) + : mNotificationSpace); + if (progress < 0) { + mOutline.left = Math.max(0, getWidth() - crop + space); + mOutline.right = getWidth(); + } else { + mOutline.right = Math.min(getWidth(), crop - space); + mOutline.left = 0; + } + + float contentTransX = mMaxTransX * (1f - absProgress); + setContentTranslationX(progress < 0 + ? contentTransX + : -contentTransX); + invalidateOutline(); } - public NotificationInfo getNotificationInfo() { + public @Nullable NotificationInfo getNotificationInfo() { return mNotificationInfo; } - public boolean canChildBeDismissed() { return mNotificationInfo != null && mNotificationInfo.dismissable; } diff --git a/src/com/android/launcher3/popup/ArrowPopup.java b/src/com/android/launcher3/popup/ArrowPopup.java index a534ee3eb4..5d3ba75bc0 100644 --- a/src/com/android/launcher3/popup/ArrowPopup.java +++ b/src/com/android/launcher3/popup/ArrowPopup.java @@ -487,6 +487,13 @@ public abstract class ArrowPopup> return getMeasuredWidth() - mArrowOffsetHorizontal - mArrowWidth; } + /** + * @param show If true, shows arrow (when applicable), otherwise hides arrow. + */ + public void showArrow(boolean show) { + mArrow.setVisibility(show && shouldAddArrow() ? VISIBLE : INVISIBLE); + } + private void addArrow() { getPopupContainer().addView(mArrow); mArrow.setX(getX() + getArrowLeft()); diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java index 18f263a8ec..bc3419aa81 100644 --- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java +++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java @@ -58,8 +58,8 @@ import com.android.launcher3.dragndrop.DraggableView; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.ItemInfoWithIcon; import com.android.launcher3.model.data.WorkspaceItemInfo; +import com.android.launcher3.notification.NotificationContainer; import com.android.launcher3.notification.NotificationInfo; -import com.android.launcher3.notification.NotificationItemView; import com.android.launcher3.notification.NotificationKeyData; import com.android.launcher3.popup.PopupDataProvider.PopupDataChangeListener; import com.android.launcher3.shortcuts.DeepShortcutView; @@ -92,9 +92,8 @@ public class PopupContainerWithArrow> private final int mStartDragThreshold; private BubbleTextView mOriginalIcon; - private NotificationItemView mNotificationItemView; private int mNumNotifications; - private ViewGroup mNotificationContainer; + private NotificationContainer mNotificationContainer; private ViewGroup mWidgetContainer; @@ -128,8 +127,8 @@ public class PopupContainerWithArrow> if (ev.getAction() == MotionEvent.ACTION_DOWN) { mInterceptTouchDown.set(ev.getX(), ev.getY()); } - if (mNotificationItemView != null - && mNotificationItemView.onInterceptTouchEvent(ev)) { + if (mNotificationContainer != null + && mNotificationContainer.onInterceptSwipeEvent(ev)) { return true; } // Stop sending touch events to deep shortcut views if user moved beyond touch slop. @@ -137,6 +136,14 @@ public class PopupContainerWithArrow> > squaredTouchSlop(getContext()); } + @Override + public boolean onTouchEvent(MotionEvent ev) { + if (mNotificationContainer != null) { + return mNotificationContainer.onSwipeEvent(ev) || super.onTouchEvent(ev); + } + return super.onTouchEvent(ev); + } + @Override protected boolean isOfType(int type) { return (type & TYPE_ACTION_POPUP) != 0; @@ -172,8 +179,8 @@ public class PopupContainerWithArrow> @Override protected void setChildColor(View view, int color, AnimatorSet animatorSetOut) { super.setChildColor(view, color, animatorSetOut); - if (view.getId() == R.id.notification_container && mNotificationItemView != null) { - mNotificationItemView.updateBackgroundColor(color, animatorSetOut); + if (view.getId() == R.id.notification_container && mNotificationContainer != null) { + mNotificationContainer.updateBackgroundColor(color, animatorSetOut); } } @@ -232,13 +239,6 @@ public class PopupContainerWithArrow> mNotificationContainer); } - @Override - protected void onInflationComplete(boolean isReversed) { - if (isReversed && mNotificationItemView != null) { - mNotificationItemView.inverseGutterMargin(); - } - } - @TargetApi(Build.VERSION_CODES.P) public void populateAndShow(final BubbleTextView originalIcon, int shortcutCount, final List notificationKeys, List systemShortcuts) { @@ -261,9 +261,10 @@ public class PopupContainerWithArrow> if (mNotificationContainer == null) { mNotificationContainer = findViewById(R.id.notification_container); mNotificationContainer.setVisibility(VISIBLE); + mNotificationContainer.setPopupView(this); + } else { + mNotificationContainer.setVisibility(GONE); } - View.inflate(getContext(), R.layout.notification_content, mNotificationContainer); - mNotificationItemView = new NotificationItemView(this, mNotificationContainer); updateNotificationHeader(); } int viewsToFlip = getChildCount(); @@ -274,10 +275,6 @@ public class PopupContainerWithArrow> if (hasDeepShortcuts) { mDeepShortcutContainer.setVisibility(View.VISIBLE); - if (mNotificationItemView != null) { - mNotificationItemView.addGutter(); - } - for (int i = shortcutCount; i > 0; i--) { DeepShortcutView v = inflateAndAdd(R.layout.deep_shortcut, mDeepShortcutContainer); v.getLayoutParams().width = containerWidth; @@ -309,10 +306,6 @@ public class PopupContainerWithArrow> } else { mDeepShortcutContainer.setVisibility(View.GONE); if (!systemShortcuts.isEmpty()) { - if (mNotificationItemView != null) { - mNotificationItemView.addGutter(); - } - for (SystemShortcut shortcut : systemShortcuts) { initializeSystemShortcut(R.layout.system_shortcut, this, shortcut); } @@ -355,13 +348,13 @@ public class PopupContainerWithArrow> } public void applyNotificationInfos(List notificationInfos) { - if (mNotificationItemView != null) { - mNotificationItemView.applyNotificationInfos(notificationInfos); + if (mNotificationContainer != null) { + mNotificationContainer.applyNotificationInfos(notificationInfos); } } private void updateHiddenShortcuts() { - int allowedCount = mNotificationItemView != null + int allowedCount = mNotificationContainer != null ? MAX_SHORTCUTS_IF_NOTIFICATIONS : MAX_SHORTCUTS; int total = mShortcuts.size(); @@ -447,8 +440,8 @@ public class PopupContainerWithArrow> private void updateNotificationHeader() { ItemInfoWithIcon itemInfo = (ItemInfoWithIcon) mOriginalIcon.getTag(); DotInfo dotInfo = mLauncher.getDotInfoForItem(itemInfo); - if (mNotificationItemView != null && dotInfo != null) { - mNotificationItemView.updateHeader(dotInfo.getNotificationCount()); + if (mNotificationContainer != null && dotInfo != null) { + mNotificationContainer.updateHeader(dotInfo.getNotificationCount()); } } @@ -590,20 +583,18 @@ public class PopupContainerWithArrow> @Override public void trimNotifications(Map updatedDots) { - if (mNotificationItemView == null) { + if (mNotificationContainer == null) { return; } ItemInfo originalInfo = (ItemInfo) mOriginalIcon.getTag(); DotInfo dotInfo = updatedDots.get(PackageUserKey.fromItemInfo(originalInfo)); if (dotInfo == null || dotInfo.getNotificationKeys().size() == 0) { // No more notifications, remove the notification views and expand all shortcuts. - mNotificationItemView.removeAllViews(); - mNotificationItemView = null; mNotificationContainer.setVisibility(GONE); updateHiddenShortcuts(); assignMarginsAndBackgrounds(PopupContainerWithArrow.this); } else { - mNotificationItemView.trimNotifications( + mNotificationContainer.trimNotifications( NotificationKeyData.extractKeysOnly(dotInfo.getNotificationKeys())); } } From 53900282f8f58bc6d02f6a836c3a25c051757d2f Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Thu, 2 Sep 2021 04:39:00 +0000 Subject: [PATCH 29/66] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I6d36dc91926963e14ece7d0e2c51c7c13364ed53 --- res/values-ta/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml index 25a1739c3e..94f534362a 100644 --- a/res/values-ta/strings.xml +++ b/res/values-ta/strings.xml @@ -138,7 +138,7 @@ "நிலை %1$sக்கு நகர்த்து" "விரும்பும் நிலை %1$sக்கு நகர்த்து" "உருப்படி நகர்த்தப்பட்டது" - "இந்தக் கோப்புறையில் சேர்க்கும்: %1$s" + "இந்த ஃபோல்டரில் சேர்க்கும்: %1$s" "%1$s உள்ள கோப்புறையில் சேர்க்கும்" "கோப்புறையில் உருப்படி சேர்க்கப்பட்டது" "இதனுடன் கோப்புறையை உருவாக்கும்: %1$s" From 3c4e89d0f772b3155fad837ff19f2b4177973fbf Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Thu, 2 Sep 2021 04:39:39 +0000 Subject: [PATCH 30/66] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I44b996552c244ac05c8155883514a0a17b9681b7 --- res/values-ta/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml index 25a1739c3e..94f534362a 100644 --- a/res/values-ta/strings.xml +++ b/res/values-ta/strings.xml @@ -138,7 +138,7 @@ "நிலை %1$sக்கு நகர்த்து" "விரும்பும் நிலை %1$sக்கு நகர்த்து" "உருப்படி நகர்த்தப்பட்டது" - "இந்தக் கோப்புறையில் சேர்க்கும்: %1$s" + "இந்த ஃபோல்டரில் சேர்க்கும்: %1$s" "%1$s உள்ள கோப்புறையில் சேர்க்கும்" "கோப்புறையில் உருப்படி சேர்க்கப்பட்டது" "இதனுடன் கோப்புறையை உருவாக்கும்: %1$s" From dacb37c1435e68be5c96d374ba18cd58c37a19dd Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Wed, 1 Sep 2021 18:43:40 +0100 Subject: [PATCH 31/66] Only call setCurrentPage in applyLoadPlan if mCurrentPage is outdated - Apply the same for all 3 setCurrentPage cases as they can all causes page jumping Bug: 197493120 Test: manual Change-Id: I5f7013ce3ce4d6fe84c67123618c3bebeeffc43a Merged-In: I5f7013ce3ce4d6fe84c67123618c3bebeeffc43a --- .../src/com/android/quickstep/views/RecentsView.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index ce79125be1..388706071c 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -1146,20 +1146,24 @@ public abstract class RecentsView 0) { - setCurrentPage(indexOfChild(getTaskViewAt(0))); + targetPage = indexOfChild(getTaskViewAt(0)); } } else if (currentTaskId != -1) { currentTaskView = getTaskView(currentTaskId); if (currentTaskView != null) { - setCurrentPage(indexOfChild(currentTaskView)); + targetPage = indexOfChild(currentTaskView); } } + if (targetPage != -1 && mCurrentPage != targetPage) { + setCurrentPage(targetPage); + } if (mIgnoreResetTaskId != -1 && getTaskView(mIgnoreResetTaskId) != ignoreResetTaskView) { // If the taskView mapping is changing, do not preserve the visuals. Since we are From ca685ffcf79a640e2f89061f3e0e16e293479a70 Mon Sep 17 00:00:00 2001 From: y Date: Mon, 23 Aug 2021 22:44:11 -0700 Subject: [PATCH 32/66] [Search] Update AllApps header protection - Disables header protection on AOSP - Fades in/out search box pill instead of sudden movements - Work tabs protection shows and hides based on scroll position Bug: 194106968 [APK attached] Test: Manual Change-Id: I5532847ddba3d4555003b0934b8fc846dc5a5cc7 --- res/values/config.xml | 3 + .../android/launcher3/ExtendedEditText.java | 14 +++- .../allapps/AllAppsContainerView.java | 49 ++++++++----- .../launcher3/allapps/FloatingHeaderView.java | 71 +++++++++---------- 4 files changed, 78 insertions(+), 59 deletions(-) diff --git a/res/values/config.xml b/res/values/config.xml index 04c359ede3..72959b2d5c 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -34,6 +34,9 @@ popup_container_iterate_children + + false + diff --git a/src/com/android/launcher3/ExtendedEditText.java b/src/com/android/launcher3/ExtendedEditText.java index a4e1af6fb3..21bc479c22 100644 --- a/src/com/android/launcher3/ExtendedEditText.java +++ b/src/com/android/launcher3/ExtendedEditText.java @@ -99,8 +99,18 @@ public class ExtendedEditText extends EditText { } } - // inherited class can override to change the appearance of the edit text. - public void show() {} + /** + * Sets whether EditText background should be visible + * @param maxAlpha defines the maximum alpha the background should animates to + */ + public void setBackgroundVisibility(boolean visible, float maxAlpha) {} + + /** + * Returns whether a visible background is set on EditText + */ + public boolean getBackgroundVisibility() { + return getBackground() != null; + } public void showKeyboard() { mShowImeAfterFirstLayout = !showSoftInput(); diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java index f420ec2f08..5775ce6211 100644 --- a/src/com/android/launcher3/allapps/AllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java @@ -59,6 +59,7 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener; import com.android.launcher3.DragSource; import com.android.launcher3.DropTarget.DragObject; +import com.android.launcher3.ExtendedEditText; import com.android.launcher3.Insettable; import com.android.launcher3.InsettableFrameLayout; import com.android.launcher3.R; @@ -118,7 +119,7 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo private SpannableStringBuilder mSearchQueryBuilder = null; protected boolean mUsingTabs; - private boolean mSearchModeWhileUsingTabs = false; + private boolean mIsSearching; protected RecyclerViewFastScroller mTouchHandler; protected final Point mFastScrollerOffset = new Point(); @@ -132,6 +133,7 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo private final float mHeaderThreshold; private ScrimView mScrimView; private int mHeaderColor; + private int mTabsProtectionAlpha; public AllAppsContainerView(Context context) { this(context, null); @@ -623,18 +625,19 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo for (int i = 0; i < mAH.length; i++) { mAH[i].adapter.setLastSearchQuery(query); } + mIsSearching = true; if (mUsingTabs) { - mSearchModeWhileUsingTabs = true; rebindAdapters(false); // hide tabs } mHeader.setCollapsed(true); } public void onClearSearchResult() { - if (mSearchModeWhileUsingTabs) { + if (mUsingTabs) { rebindAdapters(true); // show tabs - mSearchModeWhileUsingTabs = false; } + mIsSearching = false; + getActiveRecyclerView().scrollToTop(); } public void onSearchResultsChanged() { @@ -708,13 +711,12 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo mHeaderPaint.setColor(mHeaderColor); mHeaderPaint.setAlpha((int) (getAlpha() * Color.alpha(mHeaderColor))); if (mHeaderPaint.getColor() != mScrimColor && mHeaderPaint.getColor() != 0) { - int bottom = mUsingTabs && mHeader.mHeaderCollapsed ? mHeader.getVisibleBottomBound() - : mSearchContainer.getBottom(); - canvas.drawRect(0, 0, canvas.getWidth(), bottom + getTranslationY(), - mHeaderPaint); - - if (FeatureFlags.ENABLE_DEVICE_SEARCH.get() && getTranslationY() == 0) { - mSearchUiManager.getEditText().setBackground(null); + int bottom = (int) (mSearchContainer.getBottom() + getTranslationY()); + canvas.drawRect(0, 0, canvas.getWidth(), bottom, mHeaderPaint); + int tabsHeight = getFloatingHeaderView().getPeripheralProtectionHeight(); + if (mTabsProtectionAlpha > 0 && tabsHeight != 0) { + mHeaderPaint.setAlpha((int) (getAlpha() * mTabsProtectionAlpha)); + canvas.drawRect(0, bottom, canvas.getWidth(), bottom + tabsHeight, mHeaderPaint); } } } @@ -794,18 +796,29 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo protected void updateHeaderScroll(int scrolledOffset) { - float prog = Math.max(0, Math.min(1, (float) scrolledOffset / mHeaderThreshold)); + + float prog = Utilities.boundToRange((float) scrolledOffset / mHeaderThreshold, 0f, 1f); int viewBG = ColorUtils.blendARGB(mScrimColor, mHeaderProtectionColor, prog); int headerColor = ColorUtils.setAlphaComponent(viewBG, (int) (getSearchView().getAlpha() * 255)); - if (headerColor != mHeaderColor) { + int tabsAlpha = mHeader.getPeripheralProtectionHeight() == 0 ? 0 + : (int) (Utilities.boundToRange( + (scrolledOffset + mHeader.mSnappedScrolledY) / mHeaderThreshold, 0f, 1f) + * 255); + if (headerColor != mHeaderColor || mTabsProtectionAlpha != tabsAlpha) { mHeaderColor = headerColor; - getSearchView().setBackgroundColor(viewBG); - getFloatingHeaderView().setHeaderColor(viewBG); + mTabsProtectionAlpha = tabsAlpha; invalidateHeader(); - if (scrolledOffset == 0 && mSearchUiManager.getEditText() != null) { - mSearchUiManager.getEditText().show(); + } + if (mSearchUiManager.getEditText() != null) { + ExtendedEditText editText = mSearchUiManager.getEditText(); + boolean bgVisible = editText.getBackgroundVisibility(); + if (scrolledOffset == 0 && !mIsSearching) { + bgVisible = true; + } else if (scrolledOffset > mHeaderThreshold) { + bgVisible = false; } + editText.setBackgroundVisibility(bgVisible, 1 - prog); } } @@ -813,7 +826,7 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo * redraws header protection */ public void invalidateHeader() { - if (mScrimView != null && FeatureFlags.ENABLE_DEVICE_SEARCH.get()) { + if (mScrimView != null && mHeader.isHeaderProtectionSupported()) { mScrimView.invalidate(); } } diff --git a/src/com/android/launcher3/allapps/FloatingHeaderView.java b/src/com/android/launcher3/allapps/FloatingHeaderView.java index 8ea83d56ac..debb5b20c1 100644 --- a/src/com/android/launcher3/allapps/FloatingHeaderView.java +++ b/src/com/android/launcher3/allapps/FloatingHeaderView.java @@ -17,9 +17,6 @@ package com.android.launcher3.allapps; import android.animation.ValueAnimator; import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; import android.graphics.Point; import android.graphics.Rect; import android.util.ArrayMap; @@ -50,11 +47,10 @@ public class FloatingHeaderView extends LinearLayout implements ValueAnimator.AnimatorUpdateListener, PluginListener, Insettable, OnHeightUpdatedListener { - private final Rect mClip = new Rect(0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE); + private final Rect mRVClip = new Rect(0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE); + private final Rect mHeaderClip = new Rect(0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE); private final ValueAnimator mAnimator = ValueAnimator.ofInt(0, 0); - private final ValueAnimator mHeaderAnimator = ValueAnimator.ofInt(0, 1).setDuration(100); private final Point mTempOffset = new Point(); - private final Paint mBGPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private final RecyclerView.OnScrollListener mOnScrollListener = new RecyclerView.OnScrollListener() { @Override @@ -82,19 +78,19 @@ public class FloatingHeaderView extends LinearLayout implements } }; - private final int mHeaderTopPadding; - protected final Map mPluginRows = new ArrayMap<>(); + private final int mHeaderTopPadding; + private final boolean mHeaderProtectionSupported; + protected ViewGroup mTabLayout; private AllAppsRecyclerView mMainRV; private AllAppsRecyclerView mWorkRV; private AllAppsRecyclerView mCurrentRV; private ViewGroup mParent; public boolean mHeaderCollapsed; - private int mSnappedScrolledY; + protected int mSnappedScrolledY; private int mTranslationY; - private int mHeaderColor; private boolean mForwardToRecyclerView; @@ -120,6 +116,8 @@ public class FloatingHeaderView extends LinearLayout implements super(context, attrs); mHeaderTopPadding = context.getResources() .getDimensionPixelSize(R.dimen.all_apps_header_top_padding); + mHeaderProtectionSupported = context.getResources().getBoolean( + R.bool.config_header_protection_supported); } @Override @@ -138,7 +136,6 @@ public class FloatingHeaderView extends LinearLayout implements } mFixedRows = rows.toArray(new FloatingHeaderRow[rows.size()]); mAllRows = mFixedRows; - mHeaderAnimator.addUpdateListener(valueAnimator -> invalidate()); } @Override @@ -285,7 +282,7 @@ public class FloatingHeaderView extends LinearLayout implements mHeaderCollapsed = false; } mTranslationY = currentScrollY; - } else if (!mHeaderCollapsed) { + } else { mTranslationY = currentScrollY - mSnappedScrolledY - mMaxTranslation; // update state vars @@ -295,31 +292,10 @@ public class FloatingHeaderView extends LinearLayout implements } else if (mTranslationY <= -mMaxTranslation) { // hide or stay hidden mHeaderCollapsed = true; mSnappedScrolledY = -mMaxTranslation; - mHeaderAnimator.setCurrentFraction(0); - mHeaderAnimator.start(); } } } - /** - * Set current header protection background color - */ - public void setHeaderColor(int color) { - mHeaderColor = color; - invalidate(); - } - - @Override - protected void dispatchDraw(Canvas canvas) { - if (mHeaderCollapsed && !mCollapsed && mTabLayout.getVisibility() == VISIBLE - && mHeaderColor != Color.TRANSPARENT && FeatureFlags.ENABLE_DEVICE_SEARCH.get()) { - mBGPaint.setColor(mHeaderColor); - mBGPaint.setAlpha((int) (255 * mHeaderAnimator.getAnimatedFraction())); - canvas.drawRect(0, 0, getWidth(), getHeight() + mTranslationY, mBGPaint); - } - super.dispatchDraw(canvas); - } - protected void applyVerticalMove() { int uncappedTranslationY = mTranslationY; mTranslationY = Math.max(mTranslationY, -mMaxTranslation); @@ -336,11 +312,15 @@ public class FloatingHeaderView extends LinearLayout implements } mTabLayout.setTranslationY(mTranslationY); - mClip.top = mMaxTranslation + mTranslationY; + + int clipHeight = mHeaderTopPadding - getPaddingBottom(); + mRVClip.top = mTabsHidden ? clipHeight : 0; + mHeaderClip.top = clipHeight; // clipping on a draw might cause additional redraw - mMainRV.setClipBounds(mClip); + setClipBounds(mHeaderClip); + mMainRV.setClipBounds(mRVClip); if (mWorkRV != null) { - mWorkRV.setClipBounds(mClip); + mWorkRV.setClipBounds(mRVClip); } } @@ -421,6 +401,10 @@ public class FloatingHeaderView extends LinearLayout implements return false; } + public boolean isHeaderProtectionSupported() { + return mHeaderProtectionSupported; + } + @Override public boolean hasOverlappingRendering() { return false; @@ -444,10 +428,19 @@ public class FloatingHeaderView extends LinearLayout implements } /** - * Returns visible height of FloatingHeaderView contents + * Returns visible height of FloatingHeaderView contents requiring header protection */ - public int getVisibleBottomBound() { - return getBottom() + mTranslationY; + public int getPeripheralProtectionHeight() { + if (!mHeaderProtectionSupported) { + return 0; + } + + // we only want to show protection when work tab is available and header is either + // collapsed or animating to/from collapsed state + if (mTabsHidden || !mHeaderCollapsed) { + return 0; + } + return Math.max(getHeight() - getPaddingTop() + mTranslationY, 0); } } From ac6884205979d1339f5f15b8e4822a5dcfa9419a Mon Sep 17 00:00:00 2001 From: y Date: Wed, 1 Sep 2021 16:59:20 -0700 Subject: [PATCH 33/66] Remove HotseatEduActivity from AOSP Bug: 191882450 Test: manual Change-Id: Ic60ef6fec6c3d8162cb3d11b0ed3c9f89f6b5704 --- quickstep/AndroidManifest.xml | 20 ------- .../hybridhotseat/HotseatEduActivity.java | 60 ------------------- 2 files changed, 80 deletions(-) delete mode 100644 quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduActivity.java diff --git a/quickstep/AndroidManifest.xml b/quickstep/AndroidManifest.xml index b43d8d1a4b..dc92731e16 100644 --- a/quickstep/AndroidManifest.xml +++ b/quickstep/AndroidManifest.xml @@ -22,11 +22,6 @@ xmlns:tools="http://schemas.android.com/tools" package="com.android.launcher3"> - - @@ -41,7 +36,6 @@ - - - - - - - - diff --git a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduActivity.java b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduActivity.java deleted file mode 100644 index 3a7d821ed6..0000000000 --- a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduActivity.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.launcher3.hybridhotseat; - -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; - -import com.android.launcher3.BaseActivity; -import com.android.launcher3.Launcher; -import com.android.launcher3.uioverrides.QuickstepLauncher; -import com.android.launcher3.util.ActivityTracker; - -/** - * Proxy activity to return user to home screen and show halfsheet education - */ -public class HotseatEduActivity extends Activity { - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - Intent homeIntent = new Intent(Intent.ACTION_MAIN) - .addCategory(Intent.CATEGORY_HOME) - .setPackage(getPackageName()) - .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - - Launcher.ACTIVITY_TRACKER.registerCallback(new HotseatActivityTracker()); - startActivity(homeIntent); - finish(); - } - - static class HotseatActivityTracker implements - ActivityTracker.SchedulerCallback { - - @Override - public boolean init(BaseActivity activity, boolean alreadyOnHome) { - QuickstepLauncher launcher = (QuickstepLauncher) activity; - if (launcher != null) { - launcher.getHotseatPredictionController().showEdu(); - } - return false; - } - - } -} From 5a36b919b5bd91ba37f907ae98df96c2f749e094 Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Fri, 3 Sep 2021 15:00:08 -0700 Subject: [PATCH 34/66] Call onUserUnlocked() before adding callbacks This gives us a chance to initialize things in onUserUnlocked() if we're already unlocked, before doing any other logic that might use those variables. Test: None (unable to reproduce) Fixes: 184773649 Change-Id: I72ed91ae6202ec816f9bdceb4d9fd03b9a002816 --- .../com/android/quickstep/TouchInteractionService.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index db5c93c503..0f5671c543 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -331,12 +331,14 @@ public class TouchInteractionService extends Service implements PluginListener Date: Wed, 8 Sep 2021 12:07:35 -0700 Subject: [PATCH 35/66] Don't allow starting DeveloperOptionsFragment on non-debug builds Test: adb shell am start -n com.google.android.apps.nexuslauncher/com.android.launcher3.settings.SettingsActivity --es ":settings:fragment" "com.android.launcher3.settings.DeveloperOptionsFragment" Fixes: 199302659 Change-Id: I33dd4db3444c0ccabbe4dc3bb80db4167aec6a03 --- src/com/android/launcher3/settings/SettingsActivity.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/com/android/launcher3/settings/SettingsActivity.java b/src/com/android/launcher3/settings/SettingsActivity.java index 915e140aaf..f348a339fd 100644 --- a/src/com/android/launcher3/settings/SettingsActivity.java +++ b/src/com/android/launcher3/settings/SettingsActivity.java @@ -62,8 +62,9 @@ public class SettingsActivity extends FragmentActivity SharedPreferences.OnSharedPreferenceChangeListener{ /** List of fragments that can be hosted by this activity. */ - private static final List VALID_PREFERENCE_FRAGMENTS = Collections.singletonList( - DeveloperOptionsFragment.class.getName()); + private static final List VALID_PREFERENCE_FRAGMENTS = + !Utilities.IS_DEBUG_DEVICE ? Collections.emptyList() + : Collections.singletonList(DeveloperOptionsFragment.class.getName()); private static final String DEVELOPER_OPTIONS_KEY = "pref_developer_options"; private static final String FLAGS_PREFERENCE_KEY = "flag_toggler"; From eb500d53d974b9427c6708f13707414da20d61e3 Mon Sep 17 00:00:00 2001 From: Samuel Fufa Date: Mon, 23 Aug 2021 15:19:34 -0700 Subject: [PATCH 36/66] [AllApps] Polish views according to specs Bug: 196391749 Update work edu button stroke color Bug: 195497351 Update header font size for work apps paused state Bug: 192673256 Show ArrowTip elevation Bug: 192668800 Support for two line PopupOption view Test: visual Change-Id: I65f8c6152f54306756d6cb66de2581aff45b8d47 Merged-In: I65f8c6152f54306756d6cb66de2581aff45b8d47 --- res/drawable/padded_rounded_action_button.xml | 13 ++--- res/drawable/rounded_action_button.xml | 4 +- res/layout/arrow_toast.xml | 6 +-- res/layout/system_shortcut.xml | 3 +- res/layout/system_shortcut_content.xml | 47 +++++++++++++++++++ res/layout/work_apps_paused.xml | 2 +- res/values/dimens.xml | 3 ++ 7 files changed, 61 insertions(+), 17 deletions(-) create mode 100644 res/layout/system_shortcut_content.xml diff --git a/res/drawable/padded_rounded_action_button.xml b/res/drawable/padded_rounded_action_button.xml index 6432efd539..6863f92f0c 100644 --- a/res/drawable/padded_rounded_action_button.xml +++ b/res/drawable/padded_rounded_action_button.xml @@ -14,18 +14,11 @@ ~ limitations under the License. --> - + - - - - - + android:bottom="@dimen/padded_rounded_button_padding" /> - diff --git a/res/drawable/rounded_action_button.xml b/res/drawable/rounded_action_button.xml index f04389399f..b9942c0c92 100644 --- a/res/drawable/rounded_action_button.xml +++ b/res/drawable/rounded_action_button.xml @@ -19,7 +19,9 @@ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" android:shape="rectangle"> - + diff --git a/res/layout/arrow_toast.xml b/res/layout/arrow_toast.xml index 9a6f8c35bd..88a92eb565 100644 --- a/res/layout/arrow_toast.xml +++ b/res/layout/arrow_toast.xml @@ -27,15 +27,13 @@ android:gravity="center" android:padding="16dp" android:background="@drawable/arrow_toast_rounded_background" - android:elevation="2dp" - android:outlineProvider="none" + android:elevation="@dimen/arrow_toast_elevation" android:textColor="@color/arrow_tip_view_content" android:textSize="14sp"/> diff --git a/res/layout/system_shortcut.xml b/res/layout/system_shortcut.xml index de091c51c7..331d2be3aa 100644 --- a/res/layout/system_shortcut.xml +++ b/res/layout/system_shortcut.xml @@ -18,7 +18,8 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:launcher="http://schemas.android.com/apk/res-auto" android:layout_width="@dimen/bg_popup_item_width" - android:layout_height="@dimen/bg_popup_item_height" + android:layout_height="wrap_content" + android:minHeight="@dimen/bg_popup_item_height" android:elevation="@dimen/deep_shortcuts_elevation" android:background="@drawable/middle_item_primary" android:theme="@style/PopupItem" > diff --git a/res/layout/system_shortcut_content.xml b/res/layout/system_shortcut_content.xml new file mode 100644 index 0000000000..feab13d318 --- /dev/null +++ b/res/layout/system_shortcut_content.xml @@ -0,0 +1,47 @@ + + + + + + + + diff --git a/res/layout/work_apps_paused.xml b/res/layout/work_apps_paused.xml index ec34b47364..79bce70287 100644 --- a/res/layout/work_apps_paused.xml +++ b/res/layout/work_apps_paused.xml @@ -28,7 +28,7 @@ android:layout_marginTop="40dp" android:text="@string/work_apps_paused_title" android:textAlignment="center" - android:textSize="22sp" /> + android:textSize="18sp" /> 8dp 2dp + 2dp 10dp @@ -241,6 +242,7 @@ 2dp 216dp 56dp + 12dp 6dp 16dp @@ -333,4 +335,5 @@ 48dp 32dp 8dp + From 57d4f748b89b2a07e2b33acdfdbcc3767df0aa41 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Fri, 6 Aug 2021 11:52:10 -0700 Subject: [PATCH 37/66] Fixing ModelPreload cancelling existing load When a model preload call was made while the loader task is running (eg: on enabling/disabling icon theme, Launcher reloads and then launcher preview start a model-preload), it would cancel the original loader and then start a new loader with empty callbacks. So the model indeed get loaded, but the original callbacks never got notified of it. > Instead we only start preload if an existing task is not running. > Also when preloading, we use existing callbacks, instead of using empty callbacks Bug: 193851085 Bug: 195155924 Test: Verified repro steps Change-Id: I0a96310be8489756f364aa2a12e4345e1418733d --- src/com/android/launcher3/LauncherModel.java | 33 ++++---- .../graphics/PreviewSurfaceRenderer.java | 18 ++--- .../android/launcher3/model/ModelPreload.java | 76 ------------------- 3 files changed, 22 insertions(+), 105 deletions(-) delete mode 100644 src/com/android/launcher3/model/ModelPreload.java diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java index eef3980f96..545f4c3999 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -72,6 +72,7 @@ import java.util.HashSet; import java.util.List; import java.util.concurrent.CancellationException; import java.util.concurrent.Executor; +import java.util.function.Consumer; import java.util.function.Supplier; /** @@ -376,7 +377,13 @@ public class LauncherModel extends LauncherApps.Callback implements InstallSessi loaderResults.bindWidgets(); return true; } else { - startLoaderForResults(loaderResults); + stopLoader(); + mLoaderTask = new LoaderTask( + mApp, mBgAllAppsList, mBgDataModel, mModelDelegate, loaderResults); + + // Always post the loader task, instead of running directly + // (even on same thread) so that we exit any nested synchronized blocks + MODEL_EXECUTOR.post(mLoaderTask); } } } @@ -399,25 +406,17 @@ public class LauncherModel extends LauncherApps.Callback implements InstallSessi } } - public void startLoaderForResults(LoaderResults results) { + /** + * Loads the model if not loaded + * @param callback called with the data model upon successful load or null on model thread. + */ + public void loadAsync(Consumer callback) { synchronized (mLock) { - stopLoader(); - mLoaderTask = new LoaderTask( - mApp, mBgAllAppsList, mBgDataModel, mModelDelegate, results); - - // Always post the loader task, instead of running directly (even on same thread) so - // that we exit any nested synchronized blocks - MODEL_EXECUTOR.post(mLoaderTask); - } - } - - public void startLoaderForResultsIfNotLoaded(LoaderResults results) { - synchronized (mLock) { - if (!isModelLoaded()) { - Log.d(TAG, "Workspace not loaded, loading now"); - startLoaderForResults(results); + if (!mModelLoaded && !mIsLoaderTaskRunning) { + startLoader(); } } + MODEL_EXECUTOR.post(() -> callback.accept(isModelLoaded() ? mBgDataModel : null)); } @Override diff --git a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java index df493599ed..3b140a06bd 100644 --- a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java +++ b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java @@ -49,7 +49,6 @@ import com.android.launcher3.model.GridSizeMigrationTask; import com.android.launcher3.model.GridSizeMigrationTaskV2; import com.android.launcher3.model.LoaderTask; import com.android.launcher3.model.ModelDelegate; -import com.android.launcher3.model.ModelPreload; import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.RunnableList; import com.android.launcher3.util.Themes; @@ -174,18 +173,13 @@ public class PreviewSurfaceRenderer { } }.run(); } else { - new ModelPreload() { - - @Override - public void onComplete(boolean isSuccess) { - if (isSuccess) { - MAIN_EXECUTOR.execute(() -> - renderView(inflationContext, getBgDataModel(), null)); - } else { - Log.e(TAG, "Model loading failed"); - } + LauncherAppState.getInstance(inflationContext).getModel().loadAsync(dataModel -> { + if (dataModel != null) { + MAIN_EXECUTOR.execute(() -> renderView(inflationContext, dataModel, null)); + } else { + Log.e(TAG, "Model loading failed"); } - }.start(inflationContext); + }); } } diff --git a/src/com/android/launcher3/model/ModelPreload.java b/src/com/android/launcher3/model/ModelPreload.java deleted file mode 100644 index 756b7da759..0000000000 --- a/src/com/android/launcher3/model/ModelPreload.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.launcher3.model; - -import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; - -import android.content.Context; -import android.util.Log; - -import androidx.annotation.WorkerThread; - -import com.android.launcher3.LauncherAppState; -import com.android.launcher3.LauncherModel; -import com.android.launcher3.LauncherModel.ModelUpdateTask; -import com.android.launcher3.model.BgDataModel.Callbacks; - -import java.util.concurrent.Executor; - -/** - * Utility class to preload LauncherModel - */ -public class ModelPreload implements ModelUpdateTask { - - private static final String TAG = "ModelPreload"; - - private LauncherAppState mApp; - private LauncherModel mModel; - private BgDataModel mBgDataModel; - private AllAppsList mAllAppsList; - - @Override - public final void init(LauncherAppState app, LauncherModel model, BgDataModel dataModel, - AllAppsList allAppsList, Executor uiExecutor) { - mApp = app; - mModel = model; - mBgDataModel = dataModel; - mAllAppsList = allAppsList; - } - - @Override - public final void run() { - mModel.startLoaderForResultsIfNotLoaded( - new LoaderResults(mApp, mBgDataModel, mAllAppsList, new Callbacks[0])); - MODEL_EXECUTOR.post(() -> { - Log.d(TAG, "Preload completed : " + mModel.isModelLoaded()); - onComplete(mModel.isModelLoaded()); - }); - } - - public BgDataModel getBgDataModel() { - return mBgDataModel; - } - - /** - * Called when the task is complete - */ - @WorkerThread - public void onComplete(boolean isSuccess) { } - - public void start(Context context) { - LauncherAppState.getInstance(context).getModel().enqueueModelUpdateTask(this); - } -} \ No newline at end of file From d1d6713700a7caa42d21f30505277383adf65ae2 Mon Sep 17 00:00:00 2001 From: Brian Isganitis Date: Thu, 10 Jun 2021 17:54:57 -0400 Subject: [PATCH 38/66] Add flag for widgets in Launcher preview Test: Flag available in developer options (does nothing) Bug: 185306338 Change-Id: I74063d0ef29f828f740633ce0dab860672f69d3d Merged-In: I74063d0ef29f828f740633ce0dab860672f69d3d --- src/com/android/launcher3/config/FeatureFlags.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index f066dc1e02..36953471b0 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -254,6 +254,10 @@ public final class FeatureFlags { "ENABLE_WALLPAPER_SCRIM", false, "Enables scrim over wallpaper for text protection."); + public static final BooleanFlag WIDGETS_IN_LAUNCHER_PREVIEW = getDebugFlag( + "WIDGETS_IN_LAUNCHER_PREVIEW", false, + "Enables widgets in Launcher preview for the Wallpaper app."); + public static void initialize(Context context) { synchronized (sDebugFlags) { for (DebugFlag flag : sDebugFlags) { From 828154a2b260652a5970c65155bbb77736bd55db Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Wed, 16 Jun 2021 15:22:32 -0700 Subject: [PATCH 39/66] Fixing widget not laid-out properly in preview Bug: 185306338 Test: Manual Change-Id: Ib1ec8a53e4701f6813813b86bf481b837127a909 Merged-In: Ib1ec8a53e4701f6813813b86bf481b837127a909 --- .../launcher3/ShortcutAndWidgetContainer.java | 18 +++++++++--------- .../graphics/LauncherPreviewRenderer.java | 8 +++++++- .../widget/NavigableAppWidgetHostView.java | 3 +-- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/com/android/launcher3/ShortcutAndWidgetContainer.java b/src/com/android/launcher3/ShortcutAndWidgetContainer.java index 519b63d58e..bebbf4f622 100644 --- a/src/com/android/launcher3/ShortcutAndWidgetContainer.java +++ b/src/com/android/launcher3/ShortcutAndWidgetContainer.java @@ -31,7 +31,7 @@ import android.view.ViewGroup; import com.android.launcher3.CellLayout.ContainerType; import com.android.launcher3.folder.FolderIcon; import com.android.launcher3.views.ActivityContext; -import com.android.launcher3.widget.LauncherAppWidgetHostView; +import com.android.launcher3.widget.NavigableAppWidgetHostView; public class ShortcutAndWidgetContainer extends ViewGroup implements FolderIcon.FolderIconParent { static final String TAG = "ShortcutAndWidgetContainer"; @@ -104,9 +104,9 @@ public class ShortcutAndWidgetContainer extends ViewGroup implements FolderIcon. public void setupLp(View child) { CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams(); - if (child instanceof LauncherAppWidgetHostView) { + if (child instanceof NavigableAppWidgetHostView) { DeviceProfile profile = mActivity.getDeviceProfile(); - ((LauncherAppWidgetHostView) child).getWidgetInset(profile, mTempRect); + ((NavigableAppWidgetHostView) child).getWidgetInset(profile, mTempRect); lp.setup(mCellWidth, mCellHeight, invertLayoutHorizontally(), mCountX, mCountY, profile.appWidgetScale.x, profile.appWidgetScale.y, mBorderSpacing, mTempRect); } else { @@ -129,8 +129,8 @@ public class ShortcutAndWidgetContainer extends ViewGroup implements FolderIcon. CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams(); final DeviceProfile dp = mActivity.getDeviceProfile(); - if (child instanceof LauncherAppWidgetHostView) { - ((LauncherAppWidgetHostView) child).getWidgetInset(dp, mTempRect); + if (child instanceof NavigableAppWidgetHostView) { + ((NavigableAppWidgetHostView) child).getWidgetInset(dp, mTempRect); lp.setup(mCellWidth, mCellHeight, invertLayoutHorizontally(), mCountX, mCountY, dp.appWidgetScale.x, dp.appWidgetScale.y, mBorderSpacing, mTempRect); } else { @@ -178,16 +178,16 @@ public class ShortcutAndWidgetContainer extends ViewGroup implements FolderIcon. */ public void layoutChild(View child) { CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams(); - if (child instanceof LauncherAppWidgetHostView) { - LauncherAppWidgetHostView lahv = (LauncherAppWidgetHostView) child; + if (child instanceof NavigableAppWidgetHostView) { + NavigableAppWidgetHostView nahv = (NavigableAppWidgetHostView) child; // Scale and center the widget to fit within its cells. DeviceProfile profile = mActivity.getDeviceProfile(); float scaleX = profile.appWidgetScale.x; float scaleY = profile.appWidgetScale.y; - lahv.setScaleToFit(Math.min(scaleX, scaleY)); - lahv.setTranslationForCentering(-(lp.width - (lp.width * scaleX)) / 2.0f, + nahv.setScaleToFit(Math.min(scaleX, scaleY)); + nahv.setTranslationForCentering(-(lp.width - (lp.width * scaleX)) / 2.0f, -(lp.height - (lp.height * scaleY)) / 2.0f); } diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java index 7a31ea01b5..e624cc0552 100644 --- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java +++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java @@ -89,6 +89,7 @@ import com.android.launcher3.views.ActivityContext; import com.android.launcher3.views.BaseDragLayer; import com.android.launcher3.widget.LauncherAppWidgetProviderInfo; import com.android.launcher3.widget.LocalColorExtractor; +import com.android.launcher3.widget.NavigableAppWidgetHostView; import com.android.launcher3.widget.custom.CustomWidgetManager; import java.util.ArrayList; @@ -372,7 +373,12 @@ public class LauncherPreviewRenderer extends ContextWrapper private void inflateAndAddWidgets( LauncherAppWidgetInfo info, LauncherAppWidgetProviderInfo providerInfo) { - AppWidgetHostView view = new AppWidgetHostView(mContext); + AppWidgetHostView view = new NavigableAppWidgetHostView(this) { + @Override + protected boolean shouldAllowDirectClick() { + return false; + } + }; view.setAppWidget(-1, providerInfo); view.updateAppWidget(null); view.setTag(info); diff --git a/src/com/android/launcher3/widget/NavigableAppWidgetHostView.java b/src/com/android/launcher3/widget/NavigableAppWidgetHostView.java index 6163b5199c..d12fe74637 100644 --- a/src/com/android/launcher3/widget/NavigableAppWidgetHostView.java +++ b/src/com/android/launcher3/widget/NavigableAppWidgetHostView.java @@ -26,7 +26,6 @@ import android.view.View; import android.view.ViewDebug; import android.view.ViewGroup; -import com.android.launcher3.BaseActivity; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Reorderable; import com.android.launcher3.dragndrop.DraggableView; @@ -59,7 +58,7 @@ public abstract class NavigableAppWidgetHostView extends AppWidgetHostView @ViewDebug.ExportedProperty(category = "launcher") private boolean mChildrenFocused; - protected final BaseActivity mActivity; + protected final ActivityContext mActivity; public NavigableAppWidgetHostView(Context context) { super(context); From 62a6271d9c1771763fa407aad54f8239643a5d66 Mon Sep 17 00:00:00 2001 From: Brian Isganitis Date: Thu, 17 Jun 2021 19:56:30 -0400 Subject: [PATCH 40/66] Load widgets in wallpaper app launcher preview Test: Widgets in wallpaper app launcher preview rendered Bug: 185306338 Change-Id: I38569d2ff0b64ba55eb188afa42fba4100aae7ff Merged-In: I38569d2ff0b64ba55eb188afa42fba4100aae7ff --- .../graphics/LauncherPreviewRenderer.java | 56 +++++++-- .../widget/BaseLauncherAppWidgetHostView.java | 119 ++++++++++++++++++ .../widget/LauncherAppWidgetHostView.java | 83 +----------- 3 files changed, 169 insertions(+), 89 deletions(-) create mode 100644 src/com/android/launcher3/widget/BaseLauncherAppWidgetHostView.java diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java index e624cc0552..fb25954e1d 100644 --- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java +++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java @@ -29,6 +29,7 @@ import android.annotation.TargetApi; import android.app.Fragment; import android.app.WallpaperColors; import android.app.WallpaperManager; +import android.appwidget.AppWidgetHost; import android.appwidget.AppWidgetHostView; import android.appwidget.AppWidgetProviderInfo; import android.content.Context; @@ -87,6 +88,8 @@ import com.android.launcher3.util.IntArray; import com.android.launcher3.util.MainThreadInitializedObject; import com.android.launcher3.views.ActivityContext; import com.android.launcher3.views.BaseDragLayer; +import com.android.launcher3.widget.BaseLauncherAppWidgetHostView; +import com.android.launcher3.widget.LauncherAppWidgetHost; import com.android.launcher3.widget.LauncherAppWidgetProviderInfo; import com.android.launcher3.widget.LocalColorExtractor; import com.android.launcher3.widget.NavigableAppWidgetHostView; @@ -208,6 +211,7 @@ public class LauncherPreviewRenderer extends ContextWrapper private final Hotseat mHotseat; private final CellLayout mWorkspace; private final SparseIntArray mWallpaperColorResources; + private final AppWidgetHost mAppWidgetHost; public LauncherPreviewRenderer(Context context, InvariantDeviceProfile idp, @@ -274,6 +278,9 @@ public class LauncherPreviewRenderer extends ContextWrapper } else { mWallpaperColorResources = null; } + mAppWidgetHost = FeatureFlags.WIDGETS_IN_LAUNCHER_PREVIEW.get() + ? new LauncherPreviewAppWidgetHost(context) + : null; } /** Populate preview and render it. */ @@ -373,14 +380,20 @@ public class LauncherPreviewRenderer extends ContextWrapper private void inflateAndAddWidgets( LauncherAppWidgetInfo info, LauncherAppWidgetProviderInfo providerInfo) { - AppWidgetHostView view = new NavigableAppWidgetHostView(this) { - @Override - protected boolean shouldAllowDirectClick() { - return false; - } - }; - view.setAppWidget(-1, providerInfo); - view.updateAppWidget(null); + AppWidgetHostView view; + if (FeatureFlags.WIDGETS_IN_LAUNCHER_PREVIEW.get()) { + view = mAppWidgetHost.createView(mContext, info.appWidgetId, providerInfo); + } else { + view = new NavigableAppWidgetHostView(this) { + @Override + protected boolean shouldAllowDirectClick() { + return false; + } + }; + view.setAppWidget(-1, providerInfo); + view.updateAppWidget(null); + } + view.setTag(info); if (mWallpaperColorResources != null) { @@ -510,4 +523,31 @@ public class LauncherPreviewRenderer extends ContextWrapper return true; } } + + private class LauncherPreviewAppWidgetHost extends AppWidgetHost { + + private LauncherPreviewAppWidgetHost(Context context) { + super(context, LauncherAppWidgetHost.APPWIDGET_HOST_ID); + } + + @Override + protected AppWidgetHostView onCreateView( + Context context, + int appWidgetId, + AppWidgetProviderInfo appWidget) { + return new LauncherPreviewAppWidgetHostView(LauncherPreviewRenderer.this); + } + } + + private static class LauncherPreviewAppWidgetHostView extends BaseLauncherAppWidgetHostView { + + private LauncherPreviewAppWidgetHostView(Context context) { + super(context); + } + + @Override + protected boolean shouldAllowDirectClick() { + return false; + } + } } diff --git a/src/com/android/launcher3/widget/BaseLauncherAppWidgetHostView.java b/src/com/android/launcher3/widget/BaseLauncherAppWidgetHostView.java new file mode 100644 index 0000000000..2742882b1f --- /dev/null +++ b/src/com/android/launcher3/widget/BaseLauncherAppWidgetHostView.java @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2021 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.widget; + +import android.content.Context; +import android.graphics.Outline; +import android.graphics.Rect; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewOutlineProvider; +import android.widget.RemoteViews; + +import androidx.annotation.UiThread; + +import com.android.launcher3.R; +import com.android.launcher3.util.Executors; + +/** + * Launcher AppWidgetHostView with support for rounded corners and a fallback View. + */ +public abstract class BaseLauncherAppWidgetHostView extends NavigableAppWidgetHostView { + + protected final LayoutInflater mInflater; + + private final Rect mEnforcedRectangle = new Rect(); + private final float mEnforcedCornerRadius; + private final ViewOutlineProvider mCornerRadiusEnforcementOutline = new ViewOutlineProvider() { + @Override + public void getOutline(View view, Outline outline) { + if (mEnforcedRectangle.isEmpty() || mEnforcedCornerRadius <= 0) { + outline.setEmpty(); + } else { + outline.setRoundRect(mEnforcedRectangle, mEnforcedCornerRadius); + } + } + }; + + public BaseLauncherAppWidgetHostView(Context context) { + super(context); + + setExecutor(Executors.THREAD_POOL_EXECUTOR); + + mInflater = LayoutInflater.from(context); + mEnforcedCornerRadius = RoundedCornerEnforcement.computeEnforcedRadius(getContext()); + } + + @Override + protected View getErrorView() { + return mInflater.inflate(R.layout.appwidget_error, this, false); + } + + /** + * Fall back to error layout instead of showing widget. + */ + public void switchToErrorView() { + // Update the widget with 0 Layout id, to reset the view to error view. + updateAppWidget(new RemoteViews(getAppWidgetInfo().provider.getPackageName(), 0)); + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + try { + super.onLayout(changed, left, top, right, bottom); + } catch (final RuntimeException e) { + post(this::switchToErrorView); + } + + enforceRoundedCorners(); + } + + @UiThread + private void resetRoundedCorners() { + setOutlineProvider(ViewOutlineProvider.BACKGROUND); + setClipToOutline(false); + } + + @UiThread + private void enforceRoundedCorners() { + if (mEnforcedCornerRadius <= 0 || !RoundedCornerEnforcement.isRoundedCornerEnabled()) { + resetRoundedCorners(); + return; + } + View background = RoundedCornerEnforcement.findBackground(this); + if (background == null + || RoundedCornerEnforcement.hasAppWidgetOptedOut(this, background)) { + resetRoundedCorners(); + return; + } + RoundedCornerEnforcement.computeRoundedRectangle(this, + background, + mEnforcedRectangle); + setOutlineProvider(mCornerRadiusEnforcementOutline); + setClipToOutline(true); + } + + /** Returns the corner radius currently enforced, in pixels. */ + public float getEnforcedCornerRadius() { + return mEnforcedCornerRadius; + } + + /** Returns true if the corner radius are enforced for this App Widget. */ + public boolean hasEnforcedCornerRadius() { + return getClipToOutline(); + } +} diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java index 63bc416fa4..fb6de9fb5e 100644 --- a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java +++ b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java @@ -20,19 +20,16 @@ import android.appwidget.AppWidgetProviderInfo; import android.content.Context; import android.content.res.Configuration; import android.graphics.Canvas; -import android.graphics.Outline; import android.graphics.Rect; import android.graphics.RectF; import android.os.Handler; import android.os.SystemClock; import android.util.SparseBooleanArray; import android.util.SparseIntArray; -import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewDebug; import android.view.ViewGroup; -import android.view.ViewOutlineProvider; import android.view.accessibility.AccessibilityNodeInfo; import android.widget.AdapterView; import android.widget.Advanceable; @@ -40,7 +37,6 @@ import android.widget.RemoteViews; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.annotation.UiThread; import com.android.launcher3.CheckLongPressHelper; import com.android.launcher3.Launcher; @@ -51,7 +47,6 @@ import com.android.launcher3.dragndrop.DragLayer; import com.android.launcher3.keyboard.ViewGroupFocusHelper; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.LauncherAppWidgetInfo; -import com.android.launcher3.util.Executors; import com.android.launcher3.util.Themes; import com.android.launcher3.views.BaseDragLayer.TouchCompleteListener; import com.android.launcher3.widget.dragndrop.AppWidgetHostViewDragListener; @@ -61,7 +56,7 @@ import java.util.List; /** * {@inheritDoc} */ -public class LauncherAppWidgetHostView extends NavigableAppWidgetHostView +public class LauncherAppWidgetHostView extends BaseLauncherAppWidgetHostView implements TouchCompleteListener, View.OnLongClickListener, LocalColorExtractor.Listener { @@ -76,8 +71,6 @@ public class LauncherAppWidgetHostView extends NavigableAppWidgetHostView // Maximum duration for which updates can be deferred. private static final long UPDATE_LOCK_TIMEOUT_MILLIS = 1000; - protected final LayoutInflater mInflater; - private final CheckLongPressHelper mLongPressHelper; protected final Launcher mLauncher; private final Workspace mWorkspace; @@ -101,18 +94,6 @@ public class LauncherAppWidgetHostView extends NavigableAppWidgetHostView private final Rect mWidgetSizeAtDrag = new Rect(); private final RectF mTempRectF = new RectF(); - private final Rect mEnforcedRectangle = new Rect(); - private final float mEnforcedCornerRadius; - private final ViewOutlineProvider mCornerRadiusEnforcementOutline = new ViewOutlineProvider() { - @Override - public void getOutline(View view, Outline outline) { - if (mEnforcedRectangle.isEmpty() || mEnforcedCornerRadius <= 0) { - outline.setEmpty(); - } else { - outline.setRoundRect(mEnforcedRectangle, mEnforcedCornerRadius); - } - } - }; private final Object mUpdateLock = new Object(); private final ViewGroupFocusHelper mDragLayerRelativeCoordinateHelper; private long mDeferUpdatesUntilMillis = 0; @@ -126,18 +107,15 @@ public class LauncherAppWidgetHostView extends NavigableAppWidgetHostView mLauncher = Launcher.getLauncher(context); mWorkspace = mLauncher.getWorkspace(); mLongPressHelper = new CheckLongPressHelper(this, this); - mInflater = LayoutInflater.from(context); setAccessibilityDelegate(mLauncher.getAccessibilityDelegate()); setBackgroundResource(R.drawable.widget_internal_focus_bg); - setExecutor(Executors.THREAD_POOL_EXECUTOR); if (Utilities.ATLEAST_Q && Themes.getAttrBoolean(mLauncher, R.attr.isWorkspaceDarkText)) { setOnLightBackground(true); } mColorExtractor = LocalColorExtractor.newInstance(getContext()); mColorExtractor.setListener(this); - mEnforcedCornerRadius = RoundedCornerEnforcement.computeEnforcedRadius(getContext()); mDragLayerRelativeCoordinateHelper = new ViewGroupFocusHelper(mLauncher.getDragLayer()); } @@ -168,11 +146,6 @@ public class LauncherAppWidgetHostView extends NavigableAppWidgetHostView return true; } - @Override - protected View getErrorView() { - return mInflater.inflate(R.layout.appwidget_error, this, false); - } - @Override public void updateAppWidget(RemoteViews remoteViews) { synchronized (mUpdateLock) { @@ -329,28 +302,12 @@ public class LauncherAppWidgetHostView extends NavigableAppWidgetHostView } } - public void switchToErrorView() { - // Update the widget with 0 Layout id, to reset the view to error view. - updateAppWidget(new RemoteViews(getAppWidgetInfo().provider.getPackageName(), 0)); - } - @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { - try { - super.onLayout(changed, left, top, right, bottom); - } catch (final RuntimeException e) { - post(new Runnable() { - @Override - public void run() { - switchToErrorView(); - } - }); - } + super.onLayout(changed, left, top, right, bottom); mIsScrollable = checkScrollableRecursively(this); updateColorExtraction(); - - enforceRoundedCorners(); } /** Starts the drag mode. */ @@ -564,40 +521,4 @@ public class LauncherAppWidgetHostView extends NavigableAppWidgetHostView } return false; } - - @UiThread - private void resetRoundedCorners() { - setOutlineProvider(ViewOutlineProvider.BACKGROUND); - setClipToOutline(false); - } - - @UiThread - private void enforceRoundedCorners() { - if (mEnforcedCornerRadius <= 0 || !RoundedCornerEnforcement.isRoundedCornerEnabled()) { - resetRoundedCorners(); - return; - } - View background = RoundedCornerEnforcement.findBackground(this); - if (background == null - || RoundedCornerEnforcement.hasAppWidgetOptedOut(this, background)) { - resetRoundedCorners(); - return; - } - RoundedCornerEnforcement.computeRoundedRectangle(this, - background, - mEnforcedRectangle); - setOutlineProvider(mCornerRadiusEnforcementOutline); - setClipToOutline(true); - } - - /** Returns the corner radius currently enforced, in pixels. */ - public float getEnforcedCornerRadius() { - return mEnforcedCornerRadius; - } - - /** Returns true if the corner radius are enforced for this App Widget. */ - public boolean hasEnforcedCornerRadius() { - return getClipToOutline(); - } - } From 21faa2a3de01dfc66536ba72897f8be8c825590e Mon Sep 17 00:00:00 2001 From: Brian Isganitis Date: Mon, 21 Jun 2021 16:14:52 -0400 Subject: [PATCH 41/66] Enable widgets in launcher preview flag Test: Widgets fully load in launcher preview with correct size and color Fix: 185306338, 191499358 Change-Id: I2d02d7a1328ed9ef5d3dfbec090dc1f9908dd527 Merged-In: I2d02d7a1328ed9ef5d3dfbec090dc1f9908dd527 --- src/com/android/launcher3/config/FeatureFlags.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 36953471b0..18e40866ac 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -255,7 +255,7 @@ public final class FeatureFlags { "Enables scrim over wallpaper for text protection."); public static final BooleanFlag WIDGETS_IN_LAUNCHER_PREVIEW = getDebugFlag( - "WIDGETS_IN_LAUNCHER_PREVIEW", false, + "WIDGETS_IN_LAUNCHER_PREVIEW", true, "Enables widgets in Launcher preview for the Wallpaper app."); public static void initialize(Context context) { From 6434f8eae596ba1a33e72c45f552c01834fb04a3 Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Tue, 14 Sep 2021 10:50:43 -0700 Subject: [PATCH 42/66] Show all TaskViews when doing seamless overview rotation * If user is scrolling and rotates overview in fake landscape, we wouldn't change the alpha to show if it was hidden previously. Now we only skip changing the alpha if it's already visible. Bug: 194715506 Test: Scroll overview in fake landscape and rotate. No more invisible task. Change-Id: Idb519125fbb5ec7be33e0d7b6dd313fb4df684db --- quickstep/src/com/android/quickstep/views/RecentsView.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 884ad1f8f8..070714ac25 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -1729,10 +1729,10 @@ public abstract class RecentsView Date: Thu, 12 Aug 2021 14:25:23 +0800 Subject: [PATCH 43/66] extract text conversions from composing text and send them for search Bug: 196294479 Test: manually Change-Id: Iba9f1097b6ab8ef1339979ca2a0b4e26cd07144c --- .../search/AllAppsSearchBarController.java | 22 ++++++++++++++++--- .../launcher3/search/SearchAlgorithm.java | 7 ++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java index 79718fb6df..0137e2a2c0 100644 --- a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java +++ b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java @@ -18,8 +18,10 @@ package com.android.launcher3.allapps.search; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_FOCUSED_ITEM_SELECTED_WITH_IME; import android.text.Editable; +import android.text.SpannableStringBuilder; import android.text.TextUtils; import android.text.TextWatcher; +import android.text.style.SuggestionSpan; import android.view.KeyEvent; import android.view.View; import android.view.View.OnFocusChangeListener; @@ -47,6 +49,7 @@ public class AllAppsSearchBarController protected SearchCallback mCallback; protected ExtendedEditText mInput; protected String mQuery; + private String[] mTextConversions; protected SearchAlgorithm mSearchAlgorithm; @@ -78,7 +81,20 @@ public class AllAppsSearchBarController @Override public void onTextChanged(CharSequence s, int start, int before, int count) { - // Do nothing + mTextConversions = extractTextConversions(s); + } + + private static String[] extractTextConversions(CharSequence text) { + if (text instanceof SpannableStringBuilder) { + SpannableStringBuilder spanned = (SpannableStringBuilder) text; + SuggestionSpan[] suggestionSpans = + spanned.getSpans(0, text.length(), SuggestionSpan.class); + if (suggestionSpans != null && suggestionSpans.length > 0) { + spanned.removeSpan(suggestionSpans[0]); + return suggestionSpans[0].getSuggestions(); + } + } + return null; } @Override @@ -89,7 +105,7 @@ public class AllAppsSearchBarController mCallback.clearSearchResult(); } else { mSearchAlgorithm.cancel(false); - mSearchAlgorithm.doSearch(mQuery, mCallback); + mSearchAlgorithm.doSearch(mQuery, mTextConversions, mCallback); } } @@ -154,4 +170,4 @@ public class AllAppsSearchBarController public boolean isSearchFieldFocused() { return mInput.isFocused(); } -} \ No newline at end of file +} diff --git a/src/com/android/launcher3/search/SearchAlgorithm.java b/src/com/android/launcher3/search/SearchAlgorithm.java index a1720c733b..96a15f4912 100644 --- a/src/com/android/launcher3/search/SearchAlgorithm.java +++ b/src/com/android/launcher3/search/SearchAlgorithm.java @@ -27,6 +27,13 @@ public interface SearchAlgorithm { */ void doSearch(String query, SearchCallback callback); + /** + * Performs search with {@code query} and the {@code suggestedQueries}/ + */ + default void doSearch(String query, String[] suggestedQueries, SearchCallback callback) { + doSearch(query, callback); + } + /** * Cancels any active request. */ From c7f09e8c48e22857b98c7ef17310f1b7417db1be Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sat, 18 Sep 2021 14:07:16 +0000 Subject: [PATCH 44/66] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I65f321856ccbf90b30625632532dc626dd8f8e72 --- quickstep/res/values-as/strings.xml | 4 ++-- quickstep/res/values-eu/strings.xml | 2 +- quickstep/res/values-mr/strings.xml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/quickstep/res/values-as/strings.xml b/quickstep/res/values-as/strings.xml index 2551fc41a3..aa114fac72 100644 --- a/quickstep/res/values-as/strings.xml +++ b/quickstep/res/values-as/strings.xml @@ -22,7 +22,7 @@ "পিন" "Freeform" "কোনো শেহতীয়া বস্তু নাই" - "এপে ব্যৱহাৰ কৰা ডেটাৰ ছেটিংসমূহ" + "এপে ব্যৱহাৰ কৰা ডেটাৰ ছেটিং" "সকলো মচক" "শেহতীয়া এপসমূহ" "%1$s, %2$s" @@ -38,7 +38,7 @@ "আপোনাৰ সকলোতকৈ বেছিকৈ ব্যৱহৃত এপ্‌সমূহ গৃহ স্ক্ৰীনতে সহজে এক্সেছ কৰক। আপোনাৰ ৰুটিনসমূহৰ ভিত্তিত পৰামর্শসমূহ সলনি হ\'ব। একেবাৰে তলৰ শাৰীটোত থকা এপ্‌সমূহ এটা নতুন ফ\'ল্ডাৰলৈ যাব।" "এপৰ পৰামর্শসমূহ পাওক" "নালাগে, ধন্যবাদ" - "ছেটিংসমূহ" + "ছেটিং" "সকলোতকৈ বেছিকৈ ব্যৱহৃত এপ্‌সমূহ ইয়াত প্ৰদর্শিত হয় আৰু ৰুটিনসমূহ ওপৰত ভিত্তি কৰি সলনি হয়" "এপৰ পৰামর্শসমূহ পাবলৈ একেবাৰে তলৰ শাৰীত থকা এপ্‌সমূহ টানি আঁতৰাওক" "খালী ঠাইত এপৰ পৰামর্শসমূহ যোগ কৰা হ\'ল" diff --git a/quickstep/res/values-eu/strings.xml b/quickstep/res/values-eu/strings.xml index bd016e9384..12a0dbc740 100644 --- a/quickstep/res/values-eu/strings.xml +++ b/quickstep/res/values-eu/strings.xml @@ -37,7 +37,7 @@ "Atzitu erraz aplikazio erabilienak hasierako pantailatik bertatik. Ohituren arabera aldatuko dira iradokizunak. Gogokoen errenkadako aplikazioak hasierako pantailara eramango ditugu." "Atzitu erraz aplikazio erabilienak hasierako pantailatik bertatik. Ohituren arabera aldatuko dira iradokizunak. Karpeta berri batera eramango dira beheko errenkadan dauden aplikazioak." "Jaso aplikazioen iradokizunak" - "Ez" + "Ez, eskerrik asko" "Ezarpenak" "Hemen agertzen dira aplikazio erabilienak, eta ohituren arabera aldatzen dira" "Arrastatu aplikazioak beheko errenkadatik aplikazioen iradokizunak jasotzeko" diff --git a/quickstep/res/values-mr/strings.xml b/quickstep/res/values-mr/strings.xml index 8618f85e70..176dc3a5a9 100644 --- a/quickstep/res/values-mr/strings.xml +++ b/quickstep/res/values-mr/strings.xml @@ -72,7 +72,7 @@ "सेटिंग्ज" "पुन्हा प्रयत्न करा" "छान!" - "ट्युटोरियल %1$d/%2$d" + "ट्यूटोरियल %1$d/%2$d" "सर्व तयार आहे!" "होम वर जाण्यासाठी वरती स्वाइप करा" "तुम्ही तुमचा फोन वापरण्यास सुरुवात करू शकता" @@ -80,7 +80,7 @@ "शेअर करा" "स्क्रीनशॉट" "अ‍ॅप किंवा तुमच्या संस्थेद्वारे ही क्रिया करण्याची अनुमती नाही" - "नेव्हिगेशन ट्युटोरियल वगळायचे आहे का?" + "नेव्हिगेशन ट्यूटोरियल वगळायचे आहे का?" "तुम्हाला हे नंतर %1$s ॲपमध्ये मिळेल" "रद्द करा" "वगळा" From b49bed150e120239b8c2e12baad9bb42997b5ac7 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sat, 18 Sep 2021 14:07:52 +0000 Subject: [PATCH 45/66] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I4f6ff15783d06d527fbae6de0b211a258795b34e --- quickstep/res/values-as/strings.xml | 4 ++-- quickstep/res/values-eu/strings.xml | 2 +- quickstep/res/values-mr/strings.xml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/quickstep/res/values-as/strings.xml b/quickstep/res/values-as/strings.xml index 2551fc41a3..aa114fac72 100644 --- a/quickstep/res/values-as/strings.xml +++ b/quickstep/res/values-as/strings.xml @@ -22,7 +22,7 @@ "পিন" "Freeform" "কোনো শেহতীয়া বস্তু নাই" - "এপে ব্যৱহাৰ কৰা ডেটাৰ ছেটিংসমূহ" + "এপে ব্যৱহাৰ কৰা ডেটাৰ ছেটিং" "সকলো মচক" "শেহতীয়া এপসমূহ" "%1$s, %2$s" @@ -38,7 +38,7 @@ "আপোনাৰ সকলোতকৈ বেছিকৈ ব্যৱহৃত এপ্‌সমূহ গৃহ স্ক্ৰীনতে সহজে এক্সেছ কৰক। আপোনাৰ ৰুটিনসমূহৰ ভিত্তিত পৰামর্শসমূহ সলনি হ\'ব। একেবাৰে তলৰ শাৰীটোত থকা এপ্‌সমূহ এটা নতুন ফ\'ল্ডাৰলৈ যাব।" "এপৰ পৰামর্শসমূহ পাওক" "নালাগে, ধন্যবাদ" - "ছেটিংসমূহ" + "ছেটিং" "সকলোতকৈ বেছিকৈ ব্যৱহৃত এপ্‌সমূহ ইয়াত প্ৰদর্শিত হয় আৰু ৰুটিনসমূহ ওপৰত ভিত্তি কৰি সলনি হয়" "এপৰ পৰামর্শসমূহ পাবলৈ একেবাৰে তলৰ শাৰীত থকা এপ্‌সমূহ টানি আঁতৰাওক" "খালী ঠাইত এপৰ পৰামর্শসমূহ যোগ কৰা হ\'ল" diff --git a/quickstep/res/values-eu/strings.xml b/quickstep/res/values-eu/strings.xml index bd016e9384..12a0dbc740 100644 --- a/quickstep/res/values-eu/strings.xml +++ b/quickstep/res/values-eu/strings.xml @@ -37,7 +37,7 @@ "Atzitu erraz aplikazio erabilienak hasierako pantailatik bertatik. Ohituren arabera aldatuko dira iradokizunak. Gogokoen errenkadako aplikazioak hasierako pantailara eramango ditugu." "Atzitu erraz aplikazio erabilienak hasierako pantailatik bertatik. Ohituren arabera aldatuko dira iradokizunak. Karpeta berri batera eramango dira beheko errenkadan dauden aplikazioak." "Jaso aplikazioen iradokizunak" - "Ez" + "Ez, eskerrik asko" "Ezarpenak" "Hemen agertzen dira aplikazio erabilienak, eta ohituren arabera aldatzen dira" "Arrastatu aplikazioak beheko errenkadatik aplikazioen iradokizunak jasotzeko" diff --git a/quickstep/res/values-mr/strings.xml b/quickstep/res/values-mr/strings.xml index 8618f85e70..176dc3a5a9 100644 --- a/quickstep/res/values-mr/strings.xml +++ b/quickstep/res/values-mr/strings.xml @@ -72,7 +72,7 @@ "सेटिंग्ज" "पुन्हा प्रयत्न करा" "छान!" - "ट्युटोरियल %1$d/%2$d" + "ट्यूटोरियल %1$d/%2$d" "सर्व तयार आहे!" "होम वर जाण्यासाठी वरती स्वाइप करा" "तुम्ही तुमचा फोन वापरण्यास सुरुवात करू शकता" @@ -80,7 +80,7 @@ "शेअर करा" "स्क्रीनशॉट" "अ‍ॅप किंवा तुमच्या संस्थेद्वारे ही क्रिया करण्याची अनुमती नाही" - "नेव्हिगेशन ट्युटोरियल वगळायचे आहे का?" + "नेव्हिगेशन ट्यूटोरियल वगळायचे आहे का?" "तुम्हाला हे नंतर %1$s ॲपमध्ये मिळेल" "रद्द करा" "वगळा" From 4146464bf5888ba4008e67bcd1f625c8e4023951 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sat, 18 Sep 2021 14:09:18 +0000 Subject: [PATCH 46/66] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: Icaa03a2eefc4d7436c02f023cffd7354d905e977 --- go/quickstep/res/values-gu/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/quickstep/res/values-gu/strings.xml b/go/quickstep/res/values-gu/strings.xml index e1a568f874..7c627e18f8 100644 --- a/go/quickstep/res/values-gu/strings.xml +++ b/go/quickstep/res/values-gu/strings.xml @@ -9,7 +9,7 @@ "રદ કરો" "સેટિંગ" "સ્ક્રીન પરની ટેક્સ્ટનો અનુવાદ કરો અથવા સાંભળો" - "તમારી સ્ક્રીન પરની ટેક્સ્ટ, વેબ ઍડ્રેસ અને સ્ક્રીનશૉટ જેવી માહિતી Google સાથે શેર કરવામાં આવી શકે છે.\n\nતમે શેર કરતા હો તેવી માહિતીમાં ફેરફાર કરવા માટે, ""સેટિંગ > ઍપ > ડિફૉલ્ટ ઍપ > ડિજિટલ Assistant ઍપ"" પર જાઓ." + "તમારી સ્ક્રીન પરની ટેક્સ્ટ, વેબ ઍડ્રેસ અને સ્ક્રીનશૉટ જેવી માહિતી Google સાથે શેર કરવામાં આવી શકે છે.\n\nતમે શેર કરતા હો તેવી માહિતીમાં ફેરફાર કરવા માટે, ""સેટિંગ > ઍપ > ડિફૉલ્ટ ઍપ > ડિજિટલ આસિસ્ટંટ ઍપ"" પર જાઓ." "આ સુવિધાનો ઉપયોગ કરવા માટે આસિસ્ટંટ પસંદ કરો" "તમારી સ્ક્રીન પર ટેક્સ્ટ સાંભળવા માટે અથવા તેનો અનુવાદ કરવા માટે, સેટિંગમાં જઈને ડિજિટલ આસિસ્ટંટ ઍપ પસંદ કરો" "આ સુવિધાનો ઉપયોગ કરવા માટે તમારું આસિસ્ટંટ બદલો" From fb93c7540c9d0b9e058caf5846f8bf859af8819a Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sat, 18 Sep 2021 14:09:45 +0000 Subject: [PATCH 47/66] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I3e96286c27cbb3a3e1da64613835a34d11088d45 --- go/quickstep/res/values-gu/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/quickstep/res/values-gu/strings.xml b/go/quickstep/res/values-gu/strings.xml index e1a568f874..7c627e18f8 100644 --- a/go/quickstep/res/values-gu/strings.xml +++ b/go/quickstep/res/values-gu/strings.xml @@ -9,7 +9,7 @@ "રદ કરો" "સેટિંગ" "સ્ક્રીન પરની ટેક્સ્ટનો અનુવાદ કરો અથવા સાંભળો" - "તમારી સ્ક્રીન પરની ટેક્સ્ટ, વેબ ઍડ્રેસ અને સ્ક્રીનશૉટ જેવી માહિતી Google સાથે શેર કરવામાં આવી શકે છે.\n\nતમે શેર કરતા હો તેવી માહિતીમાં ફેરફાર કરવા માટે, ""સેટિંગ > ઍપ > ડિફૉલ્ટ ઍપ > ડિજિટલ Assistant ઍપ"" પર જાઓ." + "તમારી સ્ક્રીન પરની ટેક્સ્ટ, વેબ ઍડ્રેસ અને સ્ક્રીનશૉટ જેવી માહિતી Google સાથે શેર કરવામાં આવી શકે છે.\n\nતમે શેર કરતા હો તેવી માહિતીમાં ફેરફાર કરવા માટે, ""સેટિંગ > ઍપ > ડિફૉલ્ટ ઍપ > ડિજિટલ આસિસ્ટંટ ઍપ"" પર જાઓ." "આ સુવિધાનો ઉપયોગ કરવા માટે આસિસ્ટંટ પસંદ કરો" "તમારી સ્ક્રીન પર ટેક્સ્ટ સાંભળવા માટે અથવા તેનો અનુવાદ કરવા માટે, સેટિંગમાં જઈને ડિજિટલ આસિસ્ટંટ ઍપ પસંદ કરો" "આ સુવિધાનો ઉપયોગ કરવા માટે તમારું આસિસ્ટંટ બદલો" From fb359eb579f80998c7e9f52b575b04dda58d4a37 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sat, 18 Sep 2021 14:10:49 +0000 Subject: [PATCH 48/66] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I35c96c357e02dd53ae4785984040b87889b09465 --- res/values-as/strings.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml index a66b9b6e46..4edac86ccc 100644 --- a/res/values-as/strings.xml +++ b/res/values-as/strings.xml @@ -94,8 +94,8 @@ %1$s%2$dটা জাননী আছে "%2$dৰ %1$d পৃষ্ঠা" - "গৃহ স্ক্ৰীণ %2$dৰ %1$d" - "গৃহ স্ক্ৰীণৰ নতুন পৃষ্ঠা" + "গৃহ স্ক্ৰীন %2$dৰ %1$d" + "গৃহ স্ক্ৰীনৰ নতুন পৃষ্ঠা" "ফ’ল্ডাৰ খোলা হ’ল, %1$d x %2$d" "ফ\'ল্ডাৰ বন্ধ কৰিবলৈ টিপক" "সলনি কৰা নাম ছেভ কৰিবলৈ টিপক" @@ -107,14 +107,14 @@ "ৱালপেপাৰ আৰু শৈলী" "গৃহ ছেটিং" "আপোনাৰ প্ৰশাসকে অক্ষম কৰি ৰাখিছে" - "গৃহ স্ক্ৰীণ ঘূৰোৱাৰ অনুমতি দিয়ক" + "গৃহ স্ক্ৰীন ঘূৰোৱাৰ অনুমতি দিয়ক" "ফ\'নটো যেতিয়া ঘূৰোৱা হয়" "জাননী বিন্দু" "অন আছে" "অফ আছে" "জাননী চাবলৈ অনুমতিৰ প্ৰয়োজন" "জাননী সম্পৰ্কীয় বিন্দুবোৰ দেখুৱাবলৈ %1$sৰ বাবে এপৰ জাননীসমূহ অন কৰক" - "ছেটিংসমূহ সলনি কৰক" + "ছেটিং সলনি কৰক" "জাননী বিন্দু দেখুৱাওক" "গৃহ স্ক্ৰীনত এপ্ চিহ্নসমূহ যোগ দিয়ক" "নতুন এপসমূহৰ বাবে" @@ -128,9 +128,9 @@ "%1$s ইনষ্টল হোৱালৈ অপেক্ষা কৰি থকা হৈছে" "ৱিজেটৰ তালিকা" "ৱিজেটৰ তালিকা বন্ধ কৰা হ’ল" - "গৃহ স্ক্ৰীণত যোগ কৰক" + "গৃহ স্ক্ৰীনত যোগ দিয়ক" "বস্তুটো ইয়ালৈ স্থানান্তৰ কৰক" - "বস্তুটো গৃহ স্ক্ৰীণত যোগ কৰা হ’ল" + "বস্তুটো গৃহ স্ক্ৰীনত যোগ কৰা হ’ল" "বস্তুটো আঁতৰোৱা হ’ল" "আনডু কৰক" "বস্তু স্থানান্তৰ কৰক" @@ -143,7 +143,7 @@ "বস্তুটো ফ\'ল্ডাৰত যোগ কৰা হ’ল" "%1$s: ৰ জৰিয়তে ফ\'ল্ডাৰ সৃষ্টি কৰক" "ফ\'ল্ডাৰ সৃষ্টি কৰা হ’ল" - "হ\'ম স্ক্ৰীণলৈ স্থানান্তৰ কৰক" + "গৃহ স্ক্ৰীনলৈ স্থানান্তৰ কৰক" "আকাৰ সলনি কৰক" "প্ৰস্থ বৃদ্ধি কৰক" "উচ্চতা বৃদ্ধি কৰক" From 49b395f86e8dc0dd8445a01c6dc2fc0a901d84b5 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sat, 18 Sep 2021 14:11:27 +0000 Subject: [PATCH 49/66] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: Icaeb9e0760dff1886f5d70bc6872a157fb2cc866 --- res/values-as/strings.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml index a66b9b6e46..4edac86ccc 100644 --- a/res/values-as/strings.xml +++ b/res/values-as/strings.xml @@ -94,8 +94,8 @@ %1$s%2$dটা জাননী আছে "%2$dৰ %1$d পৃষ্ঠা" - "গৃহ স্ক্ৰীণ %2$dৰ %1$d" - "গৃহ স্ক্ৰীণৰ নতুন পৃষ্ঠা" + "গৃহ স্ক্ৰীন %2$dৰ %1$d" + "গৃহ স্ক্ৰীনৰ নতুন পৃষ্ঠা" "ফ’ল্ডাৰ খোলা হ’ল, %1$d x %2$d" "ফ\'ল্ডাৰ বন্ধ কৰিবলৈ টিপক" "সলনি কৰা নাম ছেভ কৰিবলৈ টিপক" @@ -107,14 +107,14 @@ "ৱালপেপাৰ আৰু শৈলী" "গৃহ ছেটিং" "আপোনাৰ প্ৰশাসকে অক্ষম কৰি ৰাখিছে" - "গৃহ স্ক্ৰীণ ঘূৰোৱাৰ অনুমতি দিয়ক" + "গৃহ স্ক্ৰীন ঘূৰোৱাৰ অনুমতি দিয়ক" "ফ\'নটো যেতিয়া ঘূৰোৱা হয়" "জাননী বিন্দু" "অন আছে" "অফ আছে" "জাননী চাবলৈ অনুমতিৰ প্ৰয়োজন" "জাননী সম্পৰ্কীয় বিন্দুবোৰ দেখুৱাবলৈ %1$sৰ বাবে এপৰ জাননীসমূহ অন কৰক" - "ছেটিংসমূহ সলনি কৰক" + "ছেটিং সলনি কৰক" "জাননী বিন্দু দেখুৱাওক" "গৃহ স্ক্ৰীনত এপ্ চিহ্নসমূহ যোগ দিয়ক" "নতুন এপসমূহৰ বাবে" @@ -128,9 +128,9 @@ "%1$s ইনষ্টল হোৱালৈ অপেক্ষা কৰি থকা হৈছে" "ৱিজেটৰ তালিকা" "ৱিজেটৰ তালিকা বন্ধ কৰা হ’ল" - "গৃহ স্ক্ৰীণত যোগ কৰক" + "গৃহ স্ক্ৰীনত যোগ দিয়ক" "বস্তুটো ইয়ালৈ স্থানান্তৰ কৰক" - "বস্তুটো গৃহ স্ক্ৰীণত যোগ কৰা হ’ল" + "বস্তুটো গৃহ স্ক্ৰীনত যোগ কৰা হ’ল" "বস্তুটো আঁতৰোৱা হ’ল" "আনডু কৰক" "বস্তু স্থানান্তৰ কৰক" @@ -143,7 +143,7 @@ "বস্তুটো ফ\'ল্ডাৰত যোগ কৰা হ’ল" "%1$s: ৰ জৰিয়তে ফ\'ল্ডাৰ সৃষ্টি কৰক" "ফ\'ল্ডাৰ সৃষ্টি কৰা হ’ল" - "হ\'ম স্ক্ৰীণলৈ স্থানান্তৰ কৰক" + "গৃহ স্ক্ৰীনলৈ স্থানান্তৰ কৰক" "আকাৰ সলনি কৰক" "প্ৰস্থ বৃদ্ধি কৰক" "উচ্চতা বৃদ্ধি কৰক" From 658a58674accd827d58864467eced49fb0c9f663 Mon Sep 17 00:00:00 2001 From: Steven Ng Date: Fri, 23 Jul 2021 17:06:10 +0100 Subject: [PATCH 50/66] Remove drop target button drawable padding if text is hidden Test: manual Fix: 194320733 Change-Id: I12adeaf37cee5a0fcf383641f24b7750f14daf27 (cherry picked from commit a1dcbce15aa94b66e8e59459b5db765a96e88f61) --- res/values/dimens.xml | 1 + res/values/styles.xml | 2 +- src/com/android/launcher3/ButtonDropTarget.java | 6 ++++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 37c4bed37b..a1e4cd9bb4 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -197,6 +197,7 @@ 16sp 2dp 4dp + 8dp 30dp diff --git a/res/values/styles.xml b/res/values/styles.xml index e4a245a5c2..b7661b9798 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -259,7 +259,7 @@