From 68f5a205f47de1320bb62079f32d71208eca45a6 Mon Sep 17 00:00:00 2001 From: Charlie Anderson Date: Tue, 15 Oct 2024 15:39:33 -0400 Subject: [PATCH 01/15] Convert ItemInstallQueue to use Dagger Bug: b/372012340 Test: Presubmit Flag: EXEMPT Dagger change Change-Id: I28033f7f164d52cf6d69035b2b652fbf8eb2b393 --- .../dagger/LauncherBaseAppComponent.java | 2 ++ .../launcher3/model/ItemInstallQueue.java | 22 ++++++++++--------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java b/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java index 0fa275e4ba..be51709b9b 100644 --- a/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java +++ b/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java @@ -19,6 +19,7 @@ package com.android.launcher3.dagger; import android.content.Context; import com.android.launcher3.graphics.IconShape; +import com.android.launcher3.model.ItemInstallQueue; import com.android.launcher3.pm.InstallSessionHelper; import com.android.launcher3.util.ApiWrapper; import com.android.launcher3.util.DaggerSingletonTracker; @@ -45,6 +46,7 @@ public interface LauncherBaseAppComponent { CustomWidgetManager getCustomWidgetManager(); IconShape getIconShape(); InstallSessionHelper getInstallSessionHelper(); + ItemInstallQueue getItemInstallQueue(); RefreshRateTracker getRefreshRateTracker(); ScreenOnTracker getScreenOnTracker(); SettingsCache getSettingsCache(); diff --git a/src/com/android/launcher3/model/ItemInstallQueue.java b/src/com/android/launcher3/model/ItemInstallQueue.java index 49f75eb167..f9c6e9632b 100644 --- a/src/com/android/launcher3/model/ItemInstallQueue.java +++ b/src/com/android/launcher3/model/ItemInstallQueue.java @@ -45,16 +45,18 @@ import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherSettings.Favorites; +import com.android.launcher3.dagger.ApplicationContext; +import com.android.launcher3.dagger.LauncherAppSingleton; +import com.android.launcher3.dagger.LauncherBaseAppComponent; import com.android.launcher3.logging.FileLog; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.LauncherAppWidgetInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.shortcuts.ShortcutKey; import com.android.launcher3.shortcuts.ShortcutRequest; -import com.android.launcher3.util.MainThreadInitializedObject; +import com.android.launcher3.util.DaggerSingletonObject; import com.android.launcher3.util.PersistedItemArray; import com.android.launcher3.util.Preconditions; -import com.android.launcher3.util.SafeCloseable; import com.android.launcher3.widget.LauncherAppWidgetProviderInfo; import java.util.HashSet; @@ -62,10 +64,13 @@ import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; +import javax.inject.Inject; + /** * Class to maintain a queue of pending items to be added to the workspace. */ -public class ItemInstallQueue implements SafeCloseable { +@LauncherAppSingleton +public class ItemInstallQueue { private static final String LOG = "ItemInstallQueue"; @@ -81,9 +86,8 @@ public class ItemInstallQueue implements SafeCloseable { public static final int NEW_SHORTCUT_BOUNCE_DURATION = 450; public static final int NEW_SHORTCUT_STAGGER_DELAY = 85; - public static MainThreadInitializedObject INSTANCE = - new MainThreadInitializedObject<>(ItemInstallQueue::new); - + public static DaggerSingletonObject INSTANCE = + new DaggerSingletonObject<>(LauncherBaseAppComponent::getItemInstallQueue); private final PersistedItemArray mStorage = new PersistedItemArray<>(APPS_PENDING_INSTALL); private final Context mContext; @@ -95,13 +99,11 @@ public class ItemInstallQueue implements SafeCloseable { // Only accessed on worker thread private List mItems; - private ItemInstallQueue(Context context) { + @Inject + public ItemInstallQueue(@ApplicationContext Context context) { mContext = context; } - @Override - public void close() {} - @WorkerThread private void ensureQueueLoaded() { Preconditions.assertWorkerThread(); From 29a430fc2177ab99050e6855c8e69f0f3d1dbeb3 Mon Sep 17 00:00:00 2001 From: Sukesh Ram Date: Tue, 5 Nov 2024 00:48:43 +0000 Subject: [PATCH 02/15] [Connected Displays in Taskbar] Refactor TaskbarDelegate for Display Signals Refactor the TaskbarDelegate to support multiple pass down displayId specific signals down to the taskbar level. Flag: EXEMPT not adding new behavior Bug: 376128251 Test: Manual Change-Id: I61aef4eb746d671be69eefeb15d876d48dd9a8fa --- .../launcher3/taskbar/TaskbarManager.java | 8 +-- .../quickstep/TouchInteractionService.java | 56 +++++++++---------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java index ab4b1b6b5a..fa54f7cea5 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java @@ -560,25 +560,25 @@ public class TaskbarManager { } } - public void checkNavBarModes() { + public void checkNavBarModes(int displayId) { if (mTaskbarActivityContext != null) { mTaskbarActivityContext.checkNavBarModes(); } } - public void finishBarAnimations() { + public void finishBarAnimations(int displayId) { if (mTaskbarActivityContext != null) { mTaskbarActivityContext.finishBarAnimations(); } } - public void touchAutoDim(boolean reset) { + public void touchAutoDim(int displayId, boolean reset) { if (mTaskbarActivityContext != null) { mTaskbarActivityContext.touchAutoDim(reset); } } - public void transitionTo(@BarTransitions.TransitionMode int barMode, + public void transitionTo(int displayId, @BarTransitions.TransitionMode int barMode, boolean animate) { if (mTaskbarActivityContext != null) { mTaskbarActivityContext.transitionTo(barMode, animate); diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index e8f38be88b..5b085d2185 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -342,36 +342,36 @@ public class TouchInteractionService extends Service { @BinderThread @Override - public void checkNavBarModes() { - MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService(tis -> - executeForTaskbarManager(TaskbarManager::checkNavBarModes) - )); - } - - @BinderThread - @Override - public void finishBarAnimations() { - MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService(tis -> - executeForTaskbarManager(TaskbarManager::finishBarAnimations) - )); - } - - @BinderThread - @Override - public void touchAutoDim(boolean reset) { - MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService(tis -> - executeForTaskbarManager(taskbarManager -> taskbarManager.touchAutoDim(reset)) - )); - } - - @BinderThread - @Override - public void transitionTo(@BarTransitions.TransitionMode int barMode, - boolean animate) { + public void checkNavBarModes(int displayId) { MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService(tis -> executeForTaskbarManager( - taskbarManager -> taskbarManager.transitionTo(barMode, animate)) - )); + taskbarManager -> taskbarManager.checkNavBarModes(displayId)))); + } + + @BinderThread + @Override + public void finishBarAnimations(int displayId) { + MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService( + tis -> executeForTaskbarManager( + taskbarManager -> taskbarManager.finishBarAnimations(displayId)))); + } + + @BinderThread + @Override + public void touchAutoDim(int displayId, boolean reset) { + MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService( + tis -> executeForTaskbarManager( + taskbarManager -> taskbarManager.touchAutoDim(displayId, reset)))); + } + + @BinderThread + @Override + public void transitionTo(int displayId, @BarTransitions.TransitionMode int barMode, + boolean animate) { + MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService( + tis -> executeForTaskbarManager( + taskbarManager -> taskbarManager.transitionTo(displayId, barMode, + animate)))); } @BinderThread From cb9c8b1fc6144bee6a550a1bf9a139a61d52c058 Mon Sep 17 00:00:00 2001 From: Juan Sebastian Martinez Date: Tue, 5 Nov 2024 16:18:18 +0000 Subject: [PATCH 03/15] Adding an aconfig flag to guard MSDL in Launcher. The flag will guard the adoption of the MSDL library in launcher. Change-Id: I0eb29b67317cdc96d0e5e5ff9af0427ed7e86509 Test: presubmit Flag: NONE new flag being added Bug: 377496684 --- aconfig/launcher.aconfig | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/aconfig/launcher.aconfig b/aconfig/launcher.aconfig index 949acc1f45..5101851d78 100644 --- a/aconfig/launcher.aconfig +++ b/aconfig/launcher.aconfig @@ -506,3 +506,10 @@ flag { description: "Enable launcher app contrast tiles." bug: "341217082" } + +flag { + name: "msdl_feedback" + namespace: "launcher" + description: "Enable MSDL feedback for Launcher interactions" + bug: "377496684" +} \ No newline at end of file From 04752a3e634b68d25e1ff65a300b5919b28730e8 Mon Sep 17 00:00:00 2001 From: fbaron Date: Tue, 5 Nov 2024 10:53:44 -0800 Subject: [PATCH 04/15] Add tablet 5x8 grids Bug: 364711064 Flag: com.android.launcher3.one_grid_rotation_handling Test: n/a Change-Id: I509a52f76852a2034020efc818bf571f00dff90d --- res/xml/backupscheme.xml | 1 + res/xml/default_workspace_5x8.xml | 76 ++++++++++++++++++++ res/xml/paddings_5x8.xml | 45 ++++++++++++ src/com/android/launcher3/LauncherFiles.java | 2 + 4 files changed, 124 insertions(+) create mode 100644 res/xml/default_workspace_5x8.xml create mode 100644 res/xml/paddings_5x8.xml diff --git a/res/xml/backupscheme.xml b/res/xml/backupscheme.xml index 27fddc81d3..58916a8b76 100644 --- a/res/xml/backupscheme.xml +++ b/res/xml/backupscheme.xml @@ -2,6 +2,7 @@ + diff --git a/res/xml/default_workspace_5x8.xml b/res/xml/default_workspace_5x8.xml new file mode 100644 index 0000000000..b078cfd7f8 --- /dev/null +++ b/res/xml/default_workspace_5x8.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/xml/paddings_5x8.xml b/res/xml/paddings_5x8.xml new file mode 100644 index 0000000000..afa70c59bc --- /dev/null +++ b/res/xml/paddings_5x8.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/com/android/launcher3/LauncherFiles.java b/src/com/android/launcher3/LauncherFiles.java index 1148f7929c..95c0ee8680 100644 --- a/src/com/android/launcher3/LauncherFiles.java +++ b/src/com/android/launcher3/LauncherFiles.java @@ -16,6 +16,7 @@ public class LauncherFiles { private static final String XML = ".xml"; public static final String LAUNCHER_DB = "launcher.db"; + public static final String LAUNCHER_5_BY_8_DB = "launcher_5_by_8.db"; public static final String LAUNCHER_6_BY_5_DB = "launcher_6_by_5.db"; public static final String LAUNCHER_4_BY_5_DB = "launcher_4_by_5.db"; public static final String LAUNCHER_4_BY_6_DB = "launcher_4_by_6.db"; @@ -35,6 +36,7 @@ public class LauncherFiles { public static final List GRID_DB_FILES = Collections.unmodifiableList(Arrays.asList( LAUNCHER_DB, + LAUNCHER_5_BY_8_DB, LAUNCHER_6_BY_5_DB, LAUNCHER_4_BY_5_DB, LAUNCHER_4_BY_6_DB, From 3d534b15bce93e7ca5360ba350f95a903bfa4153 Mon Sep 17 00:00:00 2001 From: fbaron Date: Tue, 5 Nov 2024 11:13:15 -0800 Subject: [PATCH 05/15] Remove logs for resolved bug, and make some logs permanent Bug: 360462379 Flag: EXEMPT code cleanup Test: n/a Change-Id: I99d4eb55b9241a472f38c90e36ad60f2f9f3d521 --- .../launcher3/model/GridSizeMigrationDBController.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/com/android/launcher3/model/GridSizeMigrationDBController.java b/src/com/android/launcher3/model/GridSizeMigrationDBController.java index bad7577fc3..0ff437c373 100644 --- a/src/com/android/launcher3/model/GridSizeMigrationDBController.java +++ b/src/com/android/launcher3/model/GridSizeMigrationDBController.java @@ -86,6 +86,9 @@ public class GridSizeMigrationDBController { if (needsToMigrate) { Log.i(TAG, "Migration is needed. destDeviceState: " + destDeviceState + ", srcDeviceState: " + srcDeviceState); + } else { + Log.i(TAG, "Migration is not needed. destDeviceState: " + destDeviceState + + ", srcDeviceState: " + srcDeviceState); } return needsToMigrate; } @@ -118,13 +121,7 @@ public class GridSizeMigrationDBController { @NonNull DatabaseHelper target, @NonNull SQLiteDatabase source) { - Log.i("b/360462379", "Going from " + srcDeviceState.getColumns() + "x" - + srcDeviceState.getRows()); - Log.i("b/360462379", "Going to " + destDeviceState.getColumns() + "x" - + destDeviceState.getRows()); - if (!needsToMigrate(srcDeviceState, destDeviceState)) { - Log.i("b/360462379", "Does not need to migrate."); return true; } @@ -132,7 +129,6 @@ public class GridSizeMigrationDBController { && Flags.enableGridMigrationFix() && srcDeviceState.getColumns().equals(destDeviceState.getColumns()) && srcDeviceState.getRows() < destDeviceState.getRows()) { - Log.i("b/360462379", "Grid migration fix entry point."); // Only use this strategy when comparing the previous grid to the new grid and the // columns are the same and the destination has more rows copyTable(source, TABLE_NAME, target.getWritableDatabase(), TABLE_NAME, context); From 222d204314527ea74d310630b3aee90aa99f46fa Mon Sep 17 00:00:00 2001 From: Schneider Victor-Tulias Date: Tue, 5 Nov 2024 15:14:37 -0500 Subject: [PATCH 06/15] Add SystemOnBackInvokedCallback to RecentsWindowManager Flag: com.android.launcher3.enable_fallback_overview_in_window Fixes: 377542369 Test: home/app -> overview -> back gesture/button Change-Id: Iefbad3748f72a516bd07a2db433dfe5ac23edcd8 --- .../quickstep/fallback/window/RecentsWindowManager.kt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt b/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt index 74f9901fec..0d879977f5 100644 --- a/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt +++ b/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt @@ -216,6 +216,11 @@ class RecentsWindowManager(context: Context) : ) } + private val onBackInvokedCallback: () -> Unit = { + // If we are in live tile mode, launch the live task, otherwise return home + recentsView?.runningTaskView?.launchWithAnimation() ?: startHome() + } + private fun cleanupRecentsWindow() { RecentsWindowProtoLogProxy.logCleanup(isShowing()) if (isShowing()) { @@ -239,6 +244,10 @@ class RecentsWindowManager(context: Context) : } windowManager.addView(windowView, windowLayoutParams) + windowView + ?.findOnBackInvokedDispatcher() + ?.registerSystemOnBackInvokedCallback(onBackInvokedCallback) + windowView?.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or From fb51552ac707704a0abd387637824f12018a3363 Mon Sep 17 00:00:00 2001 From: Sihua Ma Date: Thu, 17 Oct 2024 22:39:14 +0000 Subject: [PATCH 07/15] Move icon factory to framework Flag: EXEMPT library moving Test: Manual Change-Id: I2d8b657b4e9d6c6431f3976d66cabc515cb6bb1b --- .../icons/MonochromeIconFactory.java | 172 ------------------ 1 file changed, 172 deletions(-) delete mode 100644 src/com/android/launcher3/icons/MonochromeIconFactory.java diff --git a/src/com/android/launcher3/icons/MonochromeIconFactory.java b/src/com/android/launcher3/icons/MonochromeIconFactory.java deleted file mode 100644 index 2854d51631..0000000000 --- a/src/com/android/launcher3/icons/MonochromeIconFactory.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2022 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.icons; - -import static android.graphics.Paint.FILTER_BITMAP_FLAG; - -import android.annotation.TargetApi; -import android.graphics.Bitmap; -import android.graphics.Bitmap.Config; -import android.graphics.BlendMode; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.ColorFilter; -import android.graphics.ColorMatrix; -import android.graphics.ColorMatrixColorFilter; -import android.graphics.Paint; -import android.graphics.PixelFormat; -import android.graphics.Rect; -import android.graphics.drawable.AdaptiveIconDrawable; -import android.graphics.drawable.Drawable; -import android.os.Build; - -import androidx.annotation.WorkerThread; - -import com.android.launcher3.icons.BaseIconFactory.ClippedMonoDrawable; - -import java.nio.ByteBuffer; - -/** - * Utility class to generate monochrome icons version for a given drawable. - */ -@TargetApi(Build.VERSION_CODES.TIRAMISU) -public class MonochromeIconFactory extends Drawable { - - private final Bitmap mFlatBitmap; - private final Canvas mFlatCanvas; - private final Paint mCopyPaint; - - private final Bitmap mAlphaBitmap; - private final Canvas mAlphaCanvas; - private final byte[] mPixels; - - private final int mBitmapSize; - private final int mEdgePixelLength; - - private final Paint mDrawPaint; - private final Rect mSrcRect; - - MonochromeIconFactory(int iconBitmapSize) { - float extraFactor = AdaptiveIconDrawable.getExtraInsetFraction(); - float viewPortScale = 1 / (1 + 2 * extraFactor); - mBitmapSize = Math.round(iconBitmapSize * 2 * viewPortScale); - mPixels = new byte[mBitmapSize * mBitmapSize]; - mEdgePixelLength = mBitmapSize * (mBitmapSize - iconBitmapSize) / 2; - - mFlatBitmap = Bitmap.createBitmap(mBitmapSize, mBitmapSize, Config.ARGB_8888); - mFlatCanvas = new Canvas(mFlatBitmap); - - mAlphaBitmap = Bitmap.createBitmap(mBitmapSize, mBitmapSize, Config.ALPHA_8); - mAlphaCanvas = new Canvas(mAlphaBitmap); - - mDrawPaint = new Paint(FILTER_BITMAP_FLAG); - mDrawPaint.setColor(Color.WHITE); - mSrcRect = new Rect(0, 0, mBitmapSize, mBitmapSize); - - mCopyPaint = new Paint(FILTER_BITMAP_FLAG); - mCopyPaint.setBlendMode(BlendMode.SRC); - - // Crate a color matrix which converts the icon to grayscale and then uses the average - // of RGB components as the alpha component. - ColorMatrix satMatrix = new ColorMatrix(); - satMatrix.setSaturation(0); - float[] vals = satMatrix.getArray(); - vals[15] = vals[16] = vals[17] = .3333f; - vals[18] = vals[19] = 0; - mCopyPaint.setColorFilter(new ColorMatrixColorFilter(vals)); - } - - private void drawDrawable(Drawable drawable) { - if (drawable != null) { - drawable.setBounds(0, 0, mBitmapSize, mBitmapSize); - drawable.draw(mFlatCanvas); - } - } - - /** - * Creates a monochrome version of the provided drawable - */ - @WorkerThread - public Drawable wrap(AdaptiveIconDrawable icon) { - mFlatCanvas.drawColor(Color.BLACK); - drawDrawable(icon.getBackground()); - drawDrawable(icon.getForeground()); - generateMono(); - return new ClippedMonoDrawable(this); - } - - @WorkerThread - private void generateMono() { - mAlphaCanvas.drawBitmap(mFlatBitmap, 0, 0, mCopyPaint); - - // Scale the end points: - ByteBuffer buffer = ByteBuffer.wrap(mPixels); - buffer.rewind(); - mAlphaBitmap.copyPixelsToBuffer(buffer); - - int min = 0xFF; - int max = 0; - for (byte b : mPixels) { - min = Math.min(min, b & 0xFF); - max = Math.max(max, b & 0xFF); - } - - if (min < max) { - // rescale pixels to increase contrast - float range = max - min; - - // In order to check if the colors should be flipped, we just take the average color - // of top and bottom edge which should correspond to be background color. If the edge - // colors have more opacity, we flip the colors; - int sum = 0; - for (int i = 0; i < mEdgePixelLength; i++) { - sum += (mPixels[i] & 0xFF); - sum += (mPixels[mPixels.length - 1 - i] & 0xFF); - } - float edgeAverage = sum / (mEdgePixelLength * 2f); - float edgeMapped = (edgeAverage - min) / range; - boolean flipColor = edgeMapped > .5f; - - for (int i = 0; i < mPixels.length; i++) { - int p = mPixels[i] & 0xFF; - int p2 = Math.round((p - min) * 0xFF / range); - mPixels[i] = flipColor ? (byte) (255 - p2) : (byte) (p2); - } - buffer.rewind(); - mAlphaBitmap.copyPixelsFromBuffer(buffer); - } - } - - @Override - public void draw(Canvas canvas) { - canvas.drawBitmap(mAlphaBitmap, mSrcRect, getBounds(), mDrawPaint); - } - - @Override - public int getOpacity() { - return PixelFormat.TRANSLUCENT; - } - - @Override - public void setAlpha(int i) { - mDrawPaint.setAlpha(i); - } - - @Override - public void setColorFilter(ColorFilter colorFilter) { - mDrawPaint.setColorFilter(colorFilter); - } -} From 8f26e042b2efb4038d379f23814a7935cb4328c2 Mon Sep 17 00:00:00 2001 From: fbaron Date: Tue, 5 Nov 2024 11:06:02 -0800 Subject: [PATCH 08/15] Remove flags that are no longer necessary Flag: EXEMPT code cleanup Test: GridSizeMigrationTest Bug: b/325286145, b/325285743 Change-Id: I056021c299b56a186b754b94b33509d0b01816e0 --- .../launcher3/InvariantDeviceProfile.java | 30 ------------------- .../model/GridSizeMigrationDBController.java | 2 -- .../launcher3/model/GridSizeMigrationLogic.kt | 2 +- .../launcher3/provider/RestoreDbTask.java | 21 +++++-------- 4 files changed, 9 insertions(+), 46 deletions(-) diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java index 7acba753ff..1b38695acf 100644 --- a/src/com/android/launcher3/InvariantDeviceProfile.java +++ b/src/com/android/launcher3/InvariantDeviceProfile.java @@ -52,7 +52,6 @@ import androidx.core.content.res.ResourcesCompat; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.icons.DotRenderer; -import com.android.launcher3.logging.FileLog; import com.android.launcher3.model.DeviceGridState; import com.android.launcher3.provider.RestoreDbTask; import com.android.launcher3.testing.shared.ResourceUtils; @@ -303,35 +302,6 @@ public class InvariantDeviceProfile implements SafeCloseable { DisplayController.INSTANCE.executeIfCreated(dc -> dc.setPriorityListener(null)); } - /** - * Reinitialize the current grid after a restore, where some grids might now be disabled. - */ - public void reinitializeAfterRestore(Context context) { - String currentGridName = getCurrentGridName(context); - String currentDbFile = dbFile; - String newGridName = initGrid(context, currentGridName); - String newDbFile = dbFile; - FileLog.d(TAG, "Reinitializing grid after restore." - + " currentGridName=" + currentGridName - + ", currentDbFile=" + currentDbFile - + ", newGridName=" + newGridName - + ", newDbFile=" + newDbFile); - if (!newDbFile.equals(currentDbFile)) { - FileLog.d(TAG, "Restored grid is disabled : " + currentGridName - + ", migrating to: " + newGridName - + ", removing all other grid db files"); - for (String gridDbFile : LauncherFiles.GRID_DB_FILES) { - if (gridDbFile.equals(currentDbFile)) { - continue; - } - if (context.getDatabasePath(gridDbFile).delete()) { - FileLog.d(TAG, "Removed old grid db file: " + gridDbFile); - } - } - setCurrentGrid(context, newGridName); - } - } - public static String getCurrentGridName(Context context) { return LauncherPrefs.get(context).get(GRID_NAME); } diff --git a/src/com/android/launcher3/model/GridSizeMigrationDBController.java b/src/com/android/launcher3/model/GridSizeMigrationDBController.java index bad7577fc3..bef2e3b92e 100644 --- a/src/com/android/launcher3/model/GridSizeMigrationDBController.java +++ b/src/com/android/launcher3/model/GridSizeMigrationDBController.java @@ -38,7 +38,6 @@ import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; -import com.android.launcher3.Flags; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.LauncherPrefs; import com.android.launcher3.LauncherSettings; @@ -129,7 +128,6 @@ public class GridSizeMigrationDBController { } if (LauncherPrefs.get(context).get(IS_FIRST_LOAD_AFTER_RESTORE) - && Flags.enableGridMigrationFix() && srcDeviceState.getColumns().equals(destDeviceState.getColumns()) && srcDeviceState.getRows() < destDeviceState.getRows()) { Log.i("b/360462379", "Grid migration fix entry point."); diff --git a/src/com/android/launcher3/model/GridSizeMigrationLogic.kt b/src/com/android/launcher3/model/GridSizeMigrationLogic.kt index 9470abf11d..07316ef0ee 100644 --- a/src/com/android/launcher3/model/GridSizeMigrationLogic.kt +++ b/src/com/android/launcher3/model/GridSizeMigrationLogic.kt @@ -339,7 +339,7 @@ class GridSizeMigrationLogic { srcDeviceState: DeviceGridState, destDeviceState: DeviceGridState, ): Boolean { - return (isFirstLoad && Flags.enableGridMigrationFix()) && + return isFirstLoad && srcDeviceState.columns == destDeviceState.columns && srcDeviceState.rows < destDeviceState.rows } diff --git a/src/com/android/launcher3/provider/RestoreDbTask.java b/src/com/android/launcher3/provider/RestoreDbTask.java index 59c27af6da..8db981f26a 100644 --- a/src/com/android/launcher3/provider/RestoreDbTask.java +++ b/src/com/android/launcher3/provider/RestoreDbTask.java @@ -51,7 +51,6 @@ import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import androidx.annotation.WorkerThread; -import com.android.launcher3.Flags; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherFiles; @@ -124,18 +123,14 @@ public class RestoreDbTask { // executed again. LauncherPrefs.get(context).removeSync(RESTORE_DEVICE); - if (Flags.enableNarrowGridRestore()) { - DeviceGridState deviceGridState = new DeviceGridState(context); - String oldPhoneFileName = deviceGridState.getDbFile(); - List previousDbs = existingDbs(context); - removeOldDBs(context, oldPhoneFileName); - // The idp before this contains data about the old phone, after this it becomes the idp - // of the current phone. - idp.reset(context); - trySettingPreviousGridAsCurrent(context, idp, oldPhoneFileName, previousDbs); - } else { - idp.reinitializeAfterRestore(context); - } + DeviceGridState deviceGridState = new DeviceGridState(context); + String oldPhoneFileName = deviceGridState.getDbFile(); + List previousDbs = existingDbs(context); + removeOldDBs(context, oldPhoneFileName); + // The idp before this contains data about the old phone, after this it becomes the idp + // of the current phone. + idp.reset(context); + trySettingPreviousGridAsCurrent(context, idp, oldPhoneFileName, previousDbs); } From 2d55010135e5b992e5d0373e104e961d0116f6f7 Mon Sep 17 00:00:00 2001 From: Anushree Ganjam Date: Wed, 23 Oct 2024 11:17:42 -0700 Subject: [PATCH 09/15] Make ContextualEduStatsManager injected by Dagger (13/n) Bug: 361850561 Test: Manual Flag: EXEMPT Dagger Integration Change-Id: I0150ad8edeac1746e27b7d919891d02e648413be --- quickstep/res/values/config.xml | 1 - .../SystemContextualEduStatsManager.java | 19 ++++++------ .../quickstep/dagger/QuickStepModule.java | 4 +++ .../quickstep/LauncherSwipeHandlerV2Test.kt | 3 +- res/values/config.xml | 1 - .../ContextualEduStatsManager.java | 29 +++++++++---------- .../dagger/LauncherBaseAppComponent.java | 2 ++ 7 files changed, 31 insertions(+), 28 deletions(-) diff --git a/quickstep/res/values/config.xml b/quickstep/res/values/config.xml index 3ae2b89da4..5c80575568 100644 --- a/quickstep/res/values/config.xml +++ b/quickstep/res/values/config.xml @@ -34,7 +34,6 @@ com.android.launcher3.taskbar.TaskbarViewCallbacksFactory com.android.quickstep.LauncherRestoreEventLoggerImpl com.android.launcher3.taskbar.TaskbarEduTooltipController - com.android.quickstep.contextualeducation.SystemContextualEduStatsManager diff --git a/quickstep/src/com/android/quickstep/contextualeducation/SystemContextualEduStatsManager.java b/quickstep/src/com/android/quickstep/contextualeducation/SystemContextualEduStatsManager.java index d470b88d44..6a725370ba 100644 --- a/quickstep/src/com/android/quickstep/contextualeducation/SystemContextualEduStatsManager.java +++ b/quickstep/src/com/android/quickstep/contextualeducation/SystemContextualEduStatsManager.java @@ -16,29 +16,28 @@ package com.android.quickstep.contextualeducation; -import android.content.Context; - import com.android.launcher3.contextualeducation.ContextualEduStatsManager; +import com.android.launcher3.dagger.LauncherAppSingleton; import com.android.quickstep.SystemUiProxy; import com.android.systemui.contextualeducation.GestureType; +import javax.inject.Inject; + /** * A class to update contextual education data via {@link SystemUiProxy} */ +@LauncherAppSingleton public class SystemContextualEduStatsManager extends ContextualEduStatsManager { - private Context mContext; + private final SystemUiProxy mSystemUiProxy; - public SystemContextualEduStatsManager(Context context) { - mContext = context; + @Inject + public SystemContextualEduStatsManager(SystemUiProxy systemUiProxy) { + mSystemUiProxy = systemUiProxy; } @Override public void updateEduStats(boolean isTrackpadGesture, GestureType gestureType) { - SystemUiProxy.INSTANCE.get(mContext).updateContextualEduStats(isTrackpadGesture, + mSystemUiProxy.updateContextualEduStats(isTrackpadGesture, gestureType.name()); } - - @Override - public void close() { - } } diff --git a/quickstep/src/com/android/quickstep/dagger/QuickStepModule.java b/quickstep/src/com/android/quickstep/dagger/QuickStepModule.java index 3870b9b4c4..9f6360b1a3 100644 --- a/quickstep/src/com/android/quickstep/dagger/QuickStepModule.java +++ b/quickstep/src/com/android/quickstep/dagger/QuickStepModule.java @@ -15,10 +15,12 @@ */ package com.android.quickstep.dagger; +import com.android.launcher3.contextualeducation.ContextualEduStatsManager; import com.android.launcher3.uioverrides.SystemApiWrapper; import com.android.launcher3.uioverrides.plugins.PluginManagerWrapperImpl; import com.android.launcher3.util.ApiWrapper; import com.android.launcher3.util.PluginManagerWrapper; +import com.android.quickstep.contextualeducation.SystemContextualEduStatsManager; import dagger.Binds; import dagger.Module; @@ -28,4 +30,6 @@ public abstract class QuickStepModule { @Binds abstract PluginManagerWrapper bindPluginManagerWrapper(PluginManagerWrapperImpl impl); @Binds abstract ApiWrapper bindApiWrapper(SystemApiWrapper systemApiWrapper); + @Binds abstract ContextualEduStatsManager bindContextualEduStatsManager( + SystemContextualEduStatsManager manager); } diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt index c3d865f7ea..32b5b859ae 100644 --- a/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt +++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt @@ -23,6 +23,7 @@ import com.android.launcher3.R import com.android.launcher3.dagger.LauncherAppComponent import com.android.launcher3.dagger.LauncherAppSingleton import com.android.launcher3.util.LauncherModelHelper +import com.android.quickstep.dagger.QuickStepModule import com.android.systemui.contextualeducation.GestureType import com.android.systemui.shared.system.InputConsumerController import dagger.BindsInstance @@ -105,7 +106,7 @@ class LauncherSwipeHandlerV2Test { } @LauncherAppSingleton -@Component +@Component(modules = [QuickStepModule::class]) interface TestComponent : LauncherAppComponent { @Component.Builder interface Builder : LauncherAppComponent.Builder { diff --git a/res/values/config.xml b/res/values/config.xml index a1ccb67a57..f6f3c9563f 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -76,7 +76,6 @@ - diff --git a/src/com/android/launcher3/contextualeducation/ContextualEduStatsManager.java b/src/com/android/launcher3/contextualeducation/ContextualEduStatsManager.java index da13546c78..5664174014 100644 --- a/src/com/android/launcher3/contextualeducation/ContextualEduStatsManager.java +++ b/src/com/android/launcher3/contextualeducation/ContextualEduStatsManager.java @@ -16,22 +16,25 @@ package com.android.launcher3.contextualeducation; -import static com.android.launcher3.util.MainThreadInitializedObject.forOverride; - -import com.android.launcher3.R; -import com.android.launcher3.util.MainThreadInitializedObject; -import com.android.launcher3.util.ResourceBasedOverride; -import com.android.launcher3.util.SafeCloseable; +import com.android.launcher3.dagger.LauncherAppSingleton; +import com.android.launcher3.dagger.LauncherBaseAppComponent; +import com.android.launcher3.util.DaggerSingletonObject; import com.android.systemui.contextualeducation.GestureType; +import javax.inject.Inject; + /** * A class to update contextual education data. It is a no-op implementation and could be - * overridden by changing the resource value [R.string.contextual_edu_manager_class] to provide - * a real implementation. + * overridden through dagger modules to provide a real implementation. */ -public class ContextualEduStatsManager implements ResourceBasedOverride, SafeCloseable { - public static final MainThreadInitializedObject INSTANCE = - forOverride(ContextualEduStatsManager.class, R.string.contextual_edu_manager_class); +@LauncherAppSingleton +public class ContextualEduStatsManager { + public static final DaggerSingletonObject INSTANCE = + new DaggerSingletonObject<>(LauncherBaseAppComponent::getContextualEduStatsManager); + + @Inject + public ContextualEduStatsManager() { } + /** * Updates contextual education stats when a gesture is triggered @@ -40,8 +43,4 @@ public class ContextualEduStatsManager implements ResourceBasedOverride, SafeClo */ public void updateEduStats(boolean isTrackpadGesture, GestureType gestureType) { } - - @Override - public void close() { - } } diff --git a/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java b/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java index e89671e090..8fe0409646 100644 --- a/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java +++ b/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java @@ -18,6 +18,7 @@ package com.android.launcher3.dagger; import android.content.Context; +import com.android.launcher3.contextualeducation.ContextualEduStatsManager; import com.android.launcher3.graphics.IconShape; import com.android.launcher3.pm.InstallSessionHelper; import com.android.launcher3.util.ApiWrapper; @@ -43,6 +44,7 @@ import dagger.BindsInstance; public interface LauncherBaseAppComponent { DaggerSingletonTracker getDaggerSingletonTracker(); ApiWrapper getApiWrapper(); + ContextualEduStatsManager getContextualEduStatsManager(); CustomWidgetManager getCustomWidgetManager(); IconShape getIconShape(); InstallSessionHelper getInstallSessionHelper(); From 49f7df04442bf425afbb074aa3fcda1e67a8f1f9 Mon Sep 17 00:00:00 2001 From: fbaron Date: Tue, 5 Nov 2024 16:15:19 -0800 Subject: [PATCH 10/15] Fix flag guarding for oneGridRotationHandling Bug: 364711064 Flag: com.android.launcher3.one_grid_rotation_handling Test: n/a Change-Id: Ic0027bf82912bf56470a8abc29880599820b3352 --- res/values/attrs.xml | 3 +++ .../android/launcher3/InvariantDeviceProfile.java | 15 ++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/res/values/attrs.xml b/res/values/attrs.xml index 16ea0cd11e..4dddb9a506 100644 --- a/res/values/attrs.xml +++ b/res/values/attrs.xml @@ -268,6 +268,9 @@ defaults to @dimen/taskbar_button_margin_default --> + + + diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java index 7acba753ff..3a29727785 100644 --- a/src/com/android/launcher3/InvariantDeviceProfile.java +++ b/src/com/android/launcher3/InvariantDeviceProfile.java @@ -540,7 +540,7 @@ public class InvariantDeviceProfile implements SafeCloseable { } } - private List getPredefinedDeviceProfiles(Context context, + private static List getPredefinedDeviceProfiles(Context context, String gridName, @DeviceType int deviceType, boolean allowDisabledGrid) { ArrayList profiles = new ArrayList<>(); @@ -554,7 +554,7 @@ public class InvariantDeviceProfile implements SafeCloseable { GridOption gridOption = new GridOption(context, Xml.asAttributeSet(parser)); if ((gridOption.isEnabled(deviceType) || allowDisabledGrid) - && (Flags.oneGridSpecs() == gridOption.isNewGridOption())) { + && gridOption.filterByFlag(deviceType)) { final int displayDepth = parser.getDepth(); while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > displayDepth) @@ -710,7 +710,7 @@ public class InvariantDeviceProfile implements SafeCloseable { return parseAllDefinedGridOptions(context) .stream() .filter(go -> go.isEnabled(deviceType)) - .filter(go -> (Flags.oneGridSpecs() == go.isNewGridOption())) + .filter(go -> go.filterByFlag(deviceType)) .collect(Collectors.toList()); } @@ -967,6 +967,7 @@ public class InvariantDeviceProfile implements SafeCloseable { private final int demoModeLayoutId; private final boolean isScalable; + private final boolean mIsDualGrid; private final int devicePaddingId; private final int mWorkspaceSpecsId; private final int mWorkspaceSpecsTwoPanelId; @@ -991,6 +992,7 @@ public class InvariantDeviceProfile implements SafeCloseable { DEVICE_CATEGORY_ALL); mRowCountSpecsId = a.getResourceId( R.styleable.GridDisplayOption_rowCountSpecsId, INVALID_RESOURCE_HANDLE); + mIsDualGrid = a.getBoolean(R.styleable.GridDisplayOption_isDualGrid, false); if (mRowCountSpecsId != INVALID_RESOURCE_HANDLE) { ResourceHelper resourceHelper = new ResourceHelper(context, mRowCountSpecsId); NumRows numR = getRowCount(resourceHelper, context, deviceCategory); @@ -1154,6 +1156,13 @@ public class InvariantDeviceProfile implements SafeCloseable { public boolean isNewGridOption() { return mRowCountSpecsId != INVALID_RESOURCE_HANDLE; } + + public boolean filterByFlag(int deviceType) { + if (deviceType == TYPE_TABLET) { + return Flags.oneGridRotationHandling() == mIsDualGrid; + } + return Flags.oneGridSpecs() == isNewGridOption(); + } } public static final class NumRows { From f030458a10f4ebb96fed9d22314033389cdb716b Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Tue, 5 Nov 2024 12:41:57 +0800 Subject: [PATCH 11/15] Notify finish on the same thread when entering recents above home The expected order to finish recents is first "setWillFinishToHome" and then "finish" via RecentsAnimationControllerCompat. Because RecentsAnimationController uses UI_HELPER_EXECUTOR to invoke setWillFinishToHome, if "finish" is called on UI thread directly, there may be a race that WillFinishToHome is not set yet (only when animation is disabled), then the shell's RecentsTransitionHandler will handle it as "return to app" rather than entering recents. By using the regular finishRunningRecentsAnimation (forceFinish is false), RecentsAnimationController#finishController will also post to UI_HELPER_EXECUTOR, so the order between setWillFinishToHome can be consistent. Bug: 375667878 Flag: EXEMPT bugfix Test: atest com.android.quickstep.FallbackRecentsTest#testOverview Test: Set 3rd party home as default. Disable animation (Settings's "Remove animations"). Press recents key on home. It should enter recents. Change-Id: Ia449f77b317db812360092c2aaf9e3657b92cf7b --- quickstep/src/com/android/quickstep/TaskAnimationManager.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java index 56c978a318..f0683d2021 100644 --- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java +++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java @@ -201,8 +201,7 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn // Only finish if the end target is RECENTS. Otherwise, if the target is // NEW_TASK, startActivityFromRecents will be skipped. if (mLastGestureState.getEndTarget() == RECENTS) { - finishRunningRecentsAnimation(false /* toHome */, - true /* forceFinish */, null /* forceFinishCb */); + finishRunningRecentsAnimation(false /* toHome */); } }); } From f048c99de4e3bc73cf535b5d7c05b80361d0ec0c Mon Sep 17 00:00:00 2001 From: Jordan Silva Date: Tue, 5 Nov 2024 17:00:46 +0000 Subject: [PATCH 12/15] Add OverviewDesktop test to verify carousel behavior on swipe up This CL updates a test to verify the behaviour while swiping up from a fullscreen app to Overview and checking if that TaskView is between DesktopTasks (right side) and Grid Tasks (left side). The test adds the following validations: - Launches adjacent task while DesktopTask is at the center of the screen - Swipe up from a fullscreen app to Overview to validate whether the task is between other tasks and desktop tasks. - Fling back to DesktopTask to dismiss the adjacent focused task Fix: 353948167 Flag: com.android.launcher3.enable_large_desktop_windowing_tile Test: TaplTestsOverviewDesktop Change-Id: Iaa15d4061c3b6ba8fc0d03416b4721cdf3f047c3 --- .../quickstep/TaplTestsOverviewDesktop.kt | 32 ++++++++++++------- .../android/launcher3/tapl/Background.java | 30 ++++++++++++++--- .../android/launcher3/tapl/OverviewTask.java | 12 ++++--- 3 files changed, 53 insertions(+), 21 deletions(-) diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsOverviewDesktop.kt b/quickstep/tests/src/com/android/quickstep/TaplTestsOverviewDesktop.kt index 2a8afbf682..120a89b0f8 100644 --- a/quickstep/tests/src/com/android/quickstep/TaplTestsOverviewDesktop.kt +++ b/quickstep/tests/src/com/android/quickstep/TaplTestsOverviewDesktop.kt @@ -104,28 +104,36 @@ class TaplTestsOverviewDesktop : AbstractLauncherUiTest() { @Test @PortraitLandscape - fun dismissFocusedTask_thenDesktopTask_thenFocusedTaskIsCentered() { + fun dismissTasks_whenDesktopTask_IsInTheCenter() { // Create extra activity to be DesktopTaskView startTestActivity(TEST_ACTIVITY_EXTRA) mLauncher.goHome().switchToOverview() + val desktop = moveTaskToDesktop(TEST_ACTIVITY_EXTRA) + var overview = desktop.switchToOverview() - val overview = desktop.switchToOverview() + // Open focused task and go back to Overview to validate whether it has adjacent tasks in + // its both sides (grid task on left and desktop tasks at its right side) + val focusedTaskOpened = overview.getTestActivityTask(TEST_ACTIVITY_2).open() - // Dismiss focused task - val focusedTask1 = overview.getTestActivityTask(TEST_ACTIVITY_2) - assertTaskContentDescription(focusedTask1, TEST_ACTIVITY_2) - focusedTask1.dismiss() - - // Dismiss DesktopTaskView + // Fling to desktop task and dismiss the focused task to check repositioning of + // grid tasks. + overview = focusedTaskOpened.switchToOverview().apply { flingBackward() } val desktopTask = overview.currentTask assertWithMessage("The current task is not a Desktop.").that(desktopTask.isDesktop).isTrue() + + // Get focused task (previously opened task) then dismiss this task + val focusedTaskInOverview = overview.getTestActivityTask(TEST_ACTIVITY_2) + assertTaskContentDescription(focusedTaskInOverview, TEST_ACTIVITY_2) + focusedTaskInOverview.dismiss() + + // Dismiss DesktopTask to validate whether the new focused task will take its position desktopTask.dismiss() - // Dismiss focused task - val focusedTask2 = overview.currentTask - assertTaskContentDescription(focusedTask2, TEST_ACTIVITY_1) - focusedTask2.dismiss() + // Dismiss last focused task + val lastFocusedTask = overview.currentTask + assertTaskContentDescription(lastFocusedTask, TEST_ACTIVITY_1) + lastFocusedTask.dismiss() assertWithMessage("Still have tasks after dismissing all the tasks") .that(mLauncher.workspace.switchToOverview().hasTasks()) diff --git a/tests/tapl/com/android/launcher3/tapl/Background.java b/tests/tapl/com/android/launcher3/tapl/Background.java index e1bd686f65..512db394ac 100644 --- a/tests/tapl/com/android/launcher3/tapl/Background.java +++ b/tests/tapl/com/android/launcher3/tapl/Background.java @@ -29,6 +29,7 @@ import androidx.test.uiautomator.UiObject2; import com.android.launcher3.tapl.LauncherInstrumentation.NavigationModel; import com.android.launcher3.tapl.LauncherInstrumentation.TrackpadGestureType; +import com.android.launcher3.tapl.OverviewTask.TaskViewType; import com.android.launcher3.testing.shared.TestProtocol; import java.util.List; @@ -121,12 +122,31 @@ public abstract class Background extends LauncherInstrumentation.VisibleContaine if (mLauncher.isTablet()) { List tasks = mLauncher.getDevice().findObjects( TASK_SELECTOR); + final int centerX = mLauncher.getDevice().getDisplayWidth() / 2; - mLauncher.assertTrue( - "Task(s) found to the right of the swiped task", - tasks.stream().allMatch(t -> - t.getVisibleBounds().right < centerX - || t.getVisibleBounds().centerX() == centerX)); + UiObject2 centerTask = tasks.stream() + .filter(t -> t.getVisibleCenter().x == centerX) + .findFirst() + .orElse(null); + + if (centerTask != null) { + mLauncher.assertTrue( + "Task(s) found to the right of the swiped task", + tasks.stream() + .filter(t -> t != centerTask + && OverviewTask.getType(t) + != TaskViewType.DESKTOP) + .allMatch(t -> t.getVisibleBounds().right + < centerTask.getVisibleBounds().left)); + mLauncher.assertTrue( + "DesktopTask(s) found to the left of the swiped task", + tasks.stream() + .filter(t -> t != centerTask + && OverviewTask.getType(t) + == TaskViewType.DESKTOP) + .allMatch(t -> t.getVisibleBounds().left + > centerTask.getVisibleBounds().right)); + } } } diff --git a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java index 5fd4dac084..8512d73193 100644 --- a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java +++ b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java @@ -57,7 +57,7 @@ public final class OverviewTask { mLauncher.assertNotNull("task must not be null", task); mTask = task; mOverview = overview; - mType = getType(); + mType = getType(task); verifyActiveContainer(); } @@ -304,8 +304,12 @@ public final class OverviewTask { return containsContentDescription(expected, DEFAULT); } - private TaskViewType getType() { - String resourceName = mTask.getResourceName(); + /** + * Returns the TaskView type of the task. It will return whether the task is a single TaskView, + * a GroupedTaskView or a DesktopTaskView. + */ + static TaskViewType getType(UiObject2 task) { + String resourceName = task.getResourceName(); if (resourceName.endsWith("task_view_grouped")) { return TaskViewType.GROUPED; } else if (resourceName.endsWith("task_view_desktop")) { @@ -345,7 +349,7 @@ public final class OverviewTask { } } - private enum TaskViewType { + enum TaskViewType { SINGLE, GROUPED, DESKTOP From 1f6a7b46be7cdce82e8928b2ed7f2125d842d521 Mon Sep 17 00:00:00 2001 From: Andy Wickham Date: Tue, 22 Oct 2024 18:46:27 -0700 Subject: [PATCH 13/15] Adds all_apps_sheet_for_handheld flag. This flag causes All Apps to render on a background panel in handheld mode similarly to how it does on tablets. Demo: https://drive.google.com/file/d/11K8yueTb9Xr8oRJCM3TxcFH8V3rRFJrJ/view?usp=sharing&resourcekey=0-hMNEGzMQ5KC9D7may2Gb-g Bug: 374186088 Bug: 372618421 Test: Manual Flag: com.android.launcher3.all_apps_sheet_for_handheld Change-Id: Ie0b1e784d4330fd71f7f36f39e5dd85e8ee14933 --- aconfig/launcher.aconfig | 7 +++ .../uioverrides/states/AllAppsState.java | 12 ++--- src/com/android/launcher3/DeviceProfile.java | 7 ++- src/com/android/launcher3/LauncherState.java | 10 +++- .../allapps/ActivityAllAppsContainerView.java | 49 +++---------------- .../allapps/AllAppsTransitionController.java | 21 +++----- .../states/StateAnimationConfig.java | 4 +- .../touch/AllAppsSwipeController.java | 4 +- 8 files changed, 44 insertions(+), 70 deletions(-) diff --git a/aconfig/launcher.aconfig b/aconfig/launcher.aconfig index 5101851d78..ee7e975de1 100644 --- a/aconfig/launcher.aconfig +++ b/aconfig/launcher.aconfig @@ -310,6 +310,13 @@ flag { bug: "346408388" } +flag { + name: "all_apps_sheet_for_handheld" + namespace: "launcher" + description: "All Apps will be presented on a bottom sheet in handheld mode" + bug: "374186088" +} + flag { name: "multiline_search_bar" namespace: "launcher" diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java index 030a7acb48..d387794c20 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java +++ b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java @@ -118,7 +118,7 @@ public class AllAppsState extends LauncherState { @Override public ScaleAndTranslation getHotseatScaleAndTranslation(Launcher launcher) { - if (launcher.getDeviceProfile().isTablet) { + if (launcher.getDeviceProfile().shouldShowAllAppsOnSheet()) { return getWorkspaceScaleAndTranslation(launcher); } else { ScaleAndTranslation overviewScaleAndTranslation = LauncherState.OVERVIEW @@ -133,7 +133,7 @@ public class AllAppsState extends LauncherState { @Override protected float getDepthUnchecked(DEVICE_PROFILE_CONTEXT context) { - if (context.getDeviceProfile().isTablet) { + if (context.getDeviceProfile().shouldShowAllAppsOnSheet()) { return context.getDeviceProfile().bottomSheetDepth; } else { // The scrim fades in at approximately 50% of the swipe gesture. @@ -154,7 +154,7 @@ public class AllAppsState extends LauncherState { return new PageAlphaProvider(DECELERATE_2) { @Override public float getPageAlpha(int pageIndex) { - return launcher.getDeviceProfile().isTablet + return launcher.getDeviceProfile().shouldShowAllAppsOnSheet() ? superPageAlphaProvider.getPageAlpha(pageIndex) : 0; } @@ -164,8 +164,8 @@ public class AllAppsState extends LauncherState { @Override public int getVisibleElements(Launcher launcher) { int elements = ALL_APPS_CONTENT | FLOATING_SEARCH_BAR; - // Only add HOTSEAT_ICONS for tablets in ALL_APPS state. - if (launcher.getDeviceProfile().isTablet) { + // When All Apps is presented on a bottom sheet, HOTSEAT_ICONS are visible. + if (launcher.getDeviceProfile().shouldShowAllAppsOnSheet()) { elements |= HOTSEAT_ICONS; } return elements; @@ -202,7 +202,7 @@ public class AllAppsState extends LauncherState { @Override public int getWorkspaceScrimColor(Launcher launcher) { - return launcher.getDeviceProfile().isTablet + return launcher.getDeviceProfile().shouldShowAllAppsOnSheet() ? launcher.getResources().getColor(R.color.widgets_picker_scrim) : Themes.getAttrColor(launcher, R.attr.allAppsScrimColor); } diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index 4305703fba..c25e8fb1a5 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -827,7 +827,7 @@ public class DeviceProfile { hotseatBorderSpace = cellLayoutBorderSpacePx.y; } - if (isTablet) { + if (shouldShowAllAppsOnSheet()) { allAppsPadding.top = mInsets.top; allAppsShiftRange = heightPx; } else { @@ -1516,6 +1516,11 @@ public class DeviceProfile { } } + /** Whether All Apps should be presented on a bottom sheet. */ + public boolean shouldShowAllAppsOnSheet() { + return isTablet || Flags.allAppsSheetForHandheld(); + } + private void setupAllAppsStyle(Context context) { TypedArray allAppsStyle = context.obtainStyledAttributes( inv.allAppsStyle != INVALID_RESOURCE_HANDLE ? inv.allAppsStyle diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java index 102189b530..7d5e481432 100644 --- a/src/com/android/launcher3/LauncherState.java +++ b/src/com/android/launcher3/LauncherState.java @@ -375,8 +375,14 @@ public abstract class LauncherState implements BaseState { } public PageAlphaProvider getWorkspacePageAlphaProvider(Launcher launcher) { - if ((this != NORMAL && this != HINT_STATE) - || !launcher.getDeviceProfile().shouldFadeAdjacentWorkspaceScreens()) { + DeviceProfile dp = launcher.getDeviceProfile(); + boolean shouldFadeAdjacentScreens = (this == NORMAL || this == HINT_STATE) + && dp.shouldFadeAdjacentWorkspaceScreens(); + // Avoid showing adjacent screens behind handheld All Apps sheet. + if (Flags.allAppsSheetForHandheld() && dp.isPhone && this == ALL_APPS) { + shouldFadeAdjacentScreens = true; + } + if (!shouldFadeAdjacentScreens) { return DEFAULT_ALPHA_PROVIDER; } final int centerPage = launcher.getWorkspace().getNextPage(); diff --git a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java index 0dd2791f5b..4504b8e10b 100644 --- a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java @@ -47,7 +47,6 @@ import android.os.Parcelable; import android.os.Process; import android.os.UserManager; import android.util.AttributeSet; -import android.util.FloatProperty; import android.util.Log; import android.util.SparseArray; import android.view.KeyEvent; @@ -115,19 +114,6 @@ public class ActivityAllAppsContainerView ScrimView.ScrimDrawingController { - public static final FloatProperty> BOTTOM_SHEET_ALPHA = - new FloatProperty<>("bottomSheetAlpha") { - @Override - public Float get(ActivityAllAppsContainerView containerView) { - return containerView.mBottomSheetAlpha; - } - - @Override - public void setValue(ActivityAllAppsContainerView containerView, float v) { - containerView.setBottomSheetAlpha(v); - } - }; - public static final float PULL_MULTIPLIER = .02f; public static final float FLING_VELOCITY_MULTIPLIER = 1200f; protected static final String BUNDLE_KEY_CURRENT_PAGE = "launcher.allapps.current_page"; @@ -191,8 +177,6 @@ public class ActivityAllAppsContainerView private ScrimView mScrimView; private int mHeaderColor; private int mBottomSheetBackgroundColor; - private float mBottomSheetAlpha = 1f; - private boolean mForceBottomSheetVisible; private int mTabsProtectionAlpha; @Nullable private AllAppsTransitionController mAllAppsTransitionController; @@ -351,20 +335,6 @@ public class ActivityAllAppsContainerView return mSearchUiManager; } - public View getBottomSheetBackground() { - return mBottomSheetBackground; - } - - /** - * Temporarily force the bottom sheet to be visible on non-tablets. - * - * @param force {@code true} means bottom sheet will be visible on phones until {@code reset()}. - */ - public void forceBottomSheetVisible(boolean force) { - mForceBottomSheetVisible = force; - updateBackgroundVisibility(mActivityContext.getDeviceProfile()); - } - public View getSearchView() { return mSearchContainer; } @@ -496,7 +466,7 @@ public class ActivityAllAppsContainerView if (mHeader != null && mHeader.getVisibility() == VISIBLE) { mHeader.reset(animate); } - forceBottomSheetVisible(false); + updateBackgroundVisibility(mActivityContext.getDeviceProfile()); // Reset the base recycler view after transitioning home. updateHeaderScroll(0); if (exitSearch) { @@ -1002,18 +972,13 @@ public class ActivityAllAppsContainerView } protected void updateBackgroundVisibility(DeviceProfile deviceProfile) { - boolean visible = deviceProfile.isTablet || mForceBottomSheetVisible; - mBottomSheetBackground.setVisibility(visible ? View.VISIBLE : View.GONE); - // Note: For tablets, the opaque background and header protection are added in drawOnScrim. + mBottomSheetBackground.setVisibility( + deviceProfile.shouldShowAllAppsOnSheet() ? View.VISIBLE : View.GONE); + // Note: The opaque sheet background and header protection are added in drawOnScrim. // For the taskbar entrypoint, the scrim is drawn by its abstract slide in view container, // so its header protection is derived from this scrim instead. } - private void setBottomSheetAlpha(float alpha) { - // Bottom sheet alpha is always 1 for tablets. - mBottomSheetAlpha = mActivityContext.getDeviceProfile().isTablet ? 1f : alpha; - } - @VisibleForTesting public void onAppsUpdated() { mHasWorkApps = Stream.of(mAllAppsStore.getApps()) @@ -1151,8 +1116,8 @@ public class ActivityAllAppsContainerView applyAdapterSideAndBottomPaddings(grid); MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams(); - // Ignore left/right insets on tablet because we are already centered in-screen. - if (grid.isTablet) { + // Ignore left/right insets on bottom sheet because we are already centered in-screen. + if (grid.shouldShowAllAppsOnSheet()) { mlp.leftMargin = mlp.rightMargin = 0; } else { mlp.leftMargin = insets.left; @@ -1398,7 +1363,7 @@ public class ActivityAllAppsContainerView // Draw full background panel for tablets. if (hasBottomSheet) { mHeaderPaint.setColor(mBottomSheetBackgroundColor); - mHeaderPaint.setAlpha((int) (255 * mBottomSheetAlpha)); + mHeaderPaint.setAlpha(255); mTmpRectF.set( leftWithScale, diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java index c6852e015c..bd604eb08b 100644 --- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java +++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java @@ -16,7 +16,6 @@ package com.android.launcher3.allapps; import static com.android.app.animation.Interpolators.DECELERATE_1_7; -import static com.android.app.animation.Interpolators.INSTANT; import static com.android.app.animation.Interpolators.LINEAR; import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY; import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y; @@ -28,7 +27,6 @@ import static com.android.launcher3.UtilitiesKt.CLIP_CHILDREN_FALSE_MODIFIER; import static com.android.launcher3.UtilitiesKt.modifyAttributesOnViewTree; import static com.android.launcher3.UtilitiesKt.restoreAttributesOnViewTree; import static com.android.launcher3.anim.PropertySetter.NO_ANIM_PROPERTY_SETTER; -import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_BOTTOM_SHEET_FADE; import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE; import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS; import static com.android.launcher3.util.SystemUiController.FLAG_DARK_NAV; @@ -106,7 +104,7 @@ public class AllAppsTransitionController @Override public Float get(AllAppsTransitionController controller) { - if (controller.mIsTablet) { + if (controller.mShouldShowAllAppsOnSheet) { return controller.mAppsView.getActiveRecyclerView().getTranslationY(); } else { return controller.getAppsViewPullbackTranslationY().getValue(); @@ -115,7 +113,7 @@ public class AllAppsTransitionController @Override public void setValue(AllAppsTransitionController controller, float translation) { - if (controller.mIsTablet) { + if (controller.mShouldShowAllAppsOnSheet) { controller.mAppsView.getActiveRecyclerView().setTranslationY(translation); controller.getAppsViewPullbackTranslationY().setValue( ALL_APPS_PULL_BACK_TRANSLATION_DEFAULT); @@ -134,7 +132,7 @@ public class AllAppsTransitionController @Override public Float get(AllAppsTransitionController controller) { - if (controller.mIsTablet) { + if (controller.mShouldShowAllAppsOnSheet) { return controller.mAppsView.getActiveRecyclerView().getAlpha(); } else { return controller.getAppsViewPullbackAlpha().getValue(); @@ -143,7 +141,7 @@ public class AllAppsTransitionController @Override public void setValue(AllAppsTransitionController controller, float alpha) { - if (controller.mIsTablet) { + if (controller.mShouldShowAllAppsOnSheet) { controller.mAppsView.getActiveRecyclerView().setAlpha(alpha); controller.getAppsViewPullbackAlpha().setValue( ALL_APPS_PULL_BACK_ALPHA_DEFAULT); @@ -168,6 +166,7 @@ public class AllAppsTransitionController @Nullable private Animator.AnimatorListener mAllAppsSearchBackAnimationListener; private boolean mIsVerticalLayout; + private boolean mShouldShowAllAppsOnSheet; // Animation in this class is controlled by a single variable {@link mProgress}. // Visually, it represents top y coordinate of the all apps container if multiplied with @@ -183,8 +182,6 @@ public class AllAppsTransitionController private MultiValueAlpha mAppsViewAlpha; private MultiPropertyFactory mAppsViewTranslationY; - private boolean mIsTablet; - private boolean mHasScaleEffect; private final VibratorWrapper mVibratorWrapper; @@ -193,7 +190,7 @@ public class AllAppsTransitionController DeviceProfile dp = mLauncher.getDeviceProfile(); mProgress = 1f; mIsVerticalLayout = dp.isVerticalBarLayout(); - mIsTablet = dp.isTablet; + mShouldShowAllAppsOnSheet = dp.shouldShowAllAppsOnSheet(); mNavScrimFlag = Themes.getAttrBoolean(l, R.attr.isMainColorDark) ? FLAG_DARK_NAV : FLAG_LIGHT_NAV; @@ -217,7 +214,7 @@ public class AllAppsTransitionController mLauncher.getWorkspace().getPageIndicator().setTranslationY(0); } - mIsTablet = dp.isTablet; + mShouldShowAllAppsOnSheet = dp.shouldShowAllAppsOnSheet(); } /** @@ -395,10 +392,6 @@ public class AllAppsTransitionController setter.setFloat(getAppsViewPullbackAlpha(), MultiPropertyFactory.MULTI_PROPERTY_VALUE, hasAllAppsContent ? 1 : 0, allAppsFade); - setter.setFloat(mLauncher.getAppsView(), - ActivityAllAppsContainerView.BOTTOM_SHEET_ALPHA, hasAllAppsContent ? 1 : 0, - config.getInterpolator(ANIM_ALL_APPS_BOTTOM_SHEET_FADE, INSTANT)); - boolean shouldProtectHeader = !config.hasAnimationFlag(StateAnimationConfig.SKIP_SCRIM) && (ALL_APPS == state || mLauncher.getStateManager().getState() == ALL_APPS); mScrimView.setDrawingController(shouldProtectHeader ? mAppsView : null); diff --git a/src/com/android/launcher3/states/StateAnimationConfig.java b/src/com/android/launcher3/states/StateAnimationConfig.java index 0ca5afd1e8..2ffbbf400a 100644 --- a/src/com/android/launcher3/states/StateAnimationConfig.java +++ b/src/com/android/launcher3/states/StateAnimationConfig.java @@ -77,7 +77,6 @@ public class StateAnimationConfig { ANIM_WORKSPACE_PAGE_TRANSLATE_X, ANIM_OVERVIEW_SPLIT_SELECT_FLOATING_TASK_TRANSLATE_OFFSCREEN, ANIM_OVERVIEW_SPLIT_SELECT_INSTRUCTIONS_FADE, - ANIM_ALL_APPS_BOTTOM_SHEET_FADE, ANIM_ALL_APPS_KEYBOARD_FADE }) @Retention(RetentionPolicy.SOURCE) @@ -101,8 +100,7 @@ public class StateAnimationConfig { public static final int ANIM_WORKSPACE_PAGE_TRANSLATE_X = 15; public static final int ANIM_OVERVIEW_SPLIT_SELECT_FLOATING_TASK_TRANSLATE_OFFSCREEN = 17; public static final int ANIM_OVERVIEW_SPLIT_SELECT_INSTRUCTIONS_FADE = 18; - public static final int ANIM_ALL_APPS_BOTTOM_SHEET_FADE = 19; - public static final int ANIM_ALL_APPS_KEYBOARD_FADE = 20; + public static final int ANIM_ALL_APPS_KEYBOARD_FADE = 19; private static final int ANIM_TYPES_COUNT = 21; diff --git a/src/com/android/launcher3/touch/AllAppsSwipeController.java b/src/com/android/launcher3/touch/AllAppsSwipeController.java index 9dcdf22852..107bcc1226 100644 --- a/src/com/android/launcher3/touch/AllAppsSwipeController.java +++ b/src/com/android/launcher3/touch/AllAppsSwipeController.java @@ -198,7 +198,7 @@ public class AllAppsSwipeController extends AbstractStateChangeTouchController { * Applies Animation config values for transition from all apps to home. */ public static void applyAllAppsToNormalConfig(Launcher launcher, StateAnimationConfig config) { - if (launcher.getDeviceProfile().isTablet) { + if (launcher.getDeviceProfile().shouldShowAllAppsOnSheet()) { config.setInterpolator(ANIM_SCRIM_FADE, Interpolators.reverse(ALL_APPS_SCRIM_RESPONDER)); config.setInterpolator(ANIM_ALL_APPS_FADE, FINAL_FRAME); @@ -240,7 +240,7 @@ public class AllAppsSwipeController extends AbstractStateChangeTouchController { */ public static void applyNormalToAllAppsAnimConfig( Launcher launcher, StateAnimationConfig config) { - if (launcher.getDeviceProfile().isTablet) { + if (launcher.getDeviceProfile().shouldShowAllAppsOnSheet()) { config.setInterpolator(ANIM_ALL_APPS_FADE, INSTANT); config.setInterpolator(ANIM_SCRIM_FADE, ALL_APPS_SCRIM_RESPONDER); if (!config.isUserControlled()) { From bfd02bb36a679c8a46d503616b0972cd6ae0708c Mon Sep 17 00:00:00 2001 From: Brandon Dayauon Date: Fri, 20 Sep 2024 14:50:55 -0700 Subject: [PATCH 14/15] Implement the work scheduler view and update colors of FAB Update colors of the FAB to spec: https://www.figma.com/design/uMzPkNMZpb7EyfHDo8usIa/V-%E2%80%A2-Toast-Butter?node-id=3784-112229&node-type=instance&m=dev Exported the brief case icon from figma since it is not available on go/icons. Color of the brief case icon is onPrimary. Have place holder string in launcher but implement the actual string in NL. bug:361589193 Test - manual: video: https://drive.google.com/file/d/1CIs8qdtV1jUvbq57CcgAXDBPPHHX5CKJ/view?usp=sharing Flag: com.android.launcher3.work_scheduler_in_work_profile Change-Id: Ia98e9c4394f6ddfa7009653034929f9afbfeac8c --- quickstep/res/values-night/colors.xml | 2 - quickstep/res/values/colors.xml | 2 - res/drawable/ic_corp_off.xml | 10 +- res/drawable/ic_schedule.xml | 25 ++++ res/drawable/work_mode_fab_background.xml | 2 +- res/drawable/work_scheduler_background.xml | 26 ++++ res/layout/work_mode_fab.xml | 9 +- res/layout/work_mode_utility_view.xml | 32 ++++ res/values-night-v31/colors.xml | 5 - res/values-v31/colors.xml | 5 - res/values/colors.xml | 2 - res/values/dimens.xml | 3 + res/values/strings.xml | 4 + .../allapps/ActivityAllAppsContainerView.java | 10 +- .../launcher3/allapps/WorkProfileManager.java | 58 ++++---- ...rkModeSwitch.java => WorkUtilityView.java} | 139 ++++++++++++++---- .../launcher3/ui/TaplWorkProfileTest.java | 6 +- 17 files changed, 246 insertions(+), 94 deletions(-) create mode 100644 res/drawable/ic_schedule.xml create mode 100644 res/drawable/work_scheduler_background.xml create mode 100644 res/layout/work_mode_utility_view.xml rename src/com/android/launcher3/allapps/{WorkModeSwitch.java => WorkUtilityView.java} (65%) diff --git a/quickstep/res/values-night/colors.xml b/quickstep/res/values-night/colors.xml index 98e4871da2..a1e9c70f69 100644 --- a/quickstep/res/values-night/colors.xml +++ b/quickstep/res/values-night/colors.xml @@ -26,6 +26,4 @@ ?attr/materialColorPrimary - ?attr/materialColorPrimaryFixedDim - ?attr/materialColorOnPrimaryFixed \ No newline at end of file diff --git a/quickstep/res/values/colors.xml b/quickstep/res/values/colors.xml index 62873d6d64..668bce764c 100644 --- a/quickstep/res/values/colors.xml +++ b/quickstep/res/values/colors.xml @@ -94,6 +94,4 @@ ?attr/materialColorPrimary - ?attr/materialColorPrimaryFixedDim - ?attr/materialColorOnPrimaryFixed \ No newline at end of file diff --git a/res/drawable/ic_corp_off.xml b/res/drawable/ic_corp_off.xml index 117258e3bd..d4bb2f31a9 100644 --- a/res/drawable/ic_corp_off.xml +++ b/res/drawable/ic_corp_off.xml @@ -16,9 +16,9 @@ android:width="24dp" android:height="24dp" android:viewportWidth="24" - android:viewportHeight="24" - android:tint="?android:attr/textColorHint"> + android:viewportHeight="24"> - \ No newline at end of file + android:pathData="M16,6H20C21.11,6 22,6.89 22,8V18.99C22,19.021 21.994,19.05 21.989,19.077C21.984,19.102 21.98,19.126 21.98,19.15L20,17.17V8H10.83L8,5.17V4C8,2.89 8.89,2 10,2H14C15.11,2 16,2.89 16,4V6ZM10,6H14V4H10V6ZM19,19L8,8L6,6L2.81,2.81L1.39,4.22L3.3,6.13C2.54,6.41 2.01,7.14 2.01,8L2,19C2,20.11 2.89,21 4,21H18.17L19.78,22.61L21.19,21.2L20.82,20.83L19,19ZM4,8V19H16.17L5.17,8H4Z" + android:fillColor="?attr/materialColorOnPrimary" + android:fillType="evenOdd"/> + diff --git a/res/drawable/ic_schedule.xml b/res/drawable/ic_schedule.xml new file mode 100644 index 0000000000..3eeb6a2c2e --- /dev/null +++ b/res/drawable/ic_schedule.xml @@ -0,0 +1,25 @@ + + + + diff --git a/res/drawable/work_mode_fab_background.xml b/res/drawable/work_mode_fab_background.xml index fd948d1445..5bad965401 100644 --- a/res/drawable/work_mode_fab_background.xml +++ b/res/drawable/work_mode_fab_background.xml @@ -18,7 +18,7 @@ - + diff --git a/res/drawable/work_scheduler_background.xml b/res/drawable/work_scheduler_background.xml new file mode 100644 index 0000000000..6bbf029fc4 --- /dev/null +++ b/res/drawable/work_scheduler_background.xml @@ -0,0 +1,26 @@ + + + + + + + + + + \ No newline at end of file diff --git a/res/layout/work_mode_fab.xml b/res/layout/work_mode_fab.xml index fc59e568d3..46f2d8aa42 100644 --- a/res/layout/work_mode_fab.xml +++ b/res/layout/work_mode_fab.xml @@ -12,11 +12,9 @@ See the License for the specific language governing permissions and limitations under the License. --> - - + diff --git a/res/layout/work_mode_utility_view.xml b/res/layout/work_mode_utility_view.xml new file mode 100644 index 0000000000..fc112ce849 --- /dev/null +++ b/res/layout/work_mode_utility_view.xml @@ -0,0 +1,32 @@ + + + + + diff --git a/res/values-night-v31/colors.xml b/res/values-night-v31/colors.xml index 0f630e5860..d9f9769f94 100644 --- a/res/values-night-v31/colors.xml +++ b/res/values-night-v31/colors.xml @@ -53,10 +53,5 @@ @android:color/system_accent1_800 - - @android:color/system_accent1_200 - - @android:color/system_accent1_900 - @android:color/system_neutral1_100 \ No newline at end of file diff --git a/res/values-v31/colors.xml b/res/values-v31/colors.xml index a5cdfc7a1d..d74e3087c2 100644 --- a/res/values-v31/colors.xml +++ b/res/values-v31/colors.xml @@ -104,11 +104,6 @@ @android:color/system_accent1_0 - - @android:color/system_accent1_200 - - @android:color/system_accent1_900 - @android:color/system_neutral1_1000 @android:color/system_neutral1_900 diff --git a/res/values/colors.xml b/res/values/colors.xml index 1eca88d009..fa1626ea80 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -98,8 +98,6 @@ #40484D ?android:attr/colorAccent - #A8C7FA - #041E49 #EFEDED #FAF9F8 diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 037687dec1..d4773c3c9f 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -166,6 +166,9 @@ 16dp 20dp 16dp + 16dp + 8dp + 56dp 20dp 16dp 16dp diff --git a/res/values/strings.xml b/res/values/strings.xml index 9d0602169c..af57c869aa 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -465,6 +465,8 @@ Got it \u24D8 + + Work apps are paused @@ -483,6 +485,8 @@ Pause work apps Unpause + + Work apps schedule Filter diff --git a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java index 0dd2791f5b..2456980100 100644 --- a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java @@ -726,7 +726,7 @@ public class ActivityAllAppsContainerView post(() -> mAH.get(AdapterHolder.WORK).applyPadding()); } else { - mWorkManager.detachWorkModeSwitch(); + mWorkManager.detachWorkUtilityViews(); mViewPager = null; } @@ -1257,8 +1257,8 @@ public class ActivityAllAppsContainerView /** Called in Launcher#bindStringCache() to update the UI when cache is updated. */ public void updateWorkUI() { setDeviceManagementResources(); - if (mWorkManager.getWorkModeSwitch() != null) { - mWorkManager.getWorkModeSwitch().updateStringFromCache(); + if (mWorkManager.getWorkUtilityView() != null) { + mWorkManager.getWorkUtilityView().updateStringFromCache(); } inflateWorkCardsIfNeeded(); } @@ -1581,8 +1581,8 @@ public class ActivityAllAppsContainerView void applyPadding() { if (mRecyclerView != null) { int bottomOffset = 0; - if (isWork() && mWorkManager.getWorkModeSwitch() != null) { - bottomOffset = mInsets.bottom + mWorkManager.getWorkModeSwitch().getHeight(); + if (isWork() && mWorkManager.getWorkUtilityView() != null) { + bottomOffset = mInsets.bottom + mWorkManager.getWorkUtilityView().getHeight(); } else if (isMain() && mPrivateProfileManager != null) { Optional privateSpaceHeaderItem = mAppsList.getAdapterItems() .stream() diff --git a/src/com/android/launcher3/allapps/WorkProfileManager.java b/src/com/android/launcher3/allapps/WorkProfileManager.java index 96998a3e38..3d0c1d063d 100644 --- a/src/com/android/launcher3/allapps/WorkProfileManager.java +++ b/src/com/android/launcher3/allapps/WorkProfileManager.java @@ -58,7 +58,7 @@ public class WorkProfileManager extends UserProfileManager implements PersonalWorkSlidingTabStrip.OnActivePageChangedListener { private static final String TAG = "WorkProfileManager"; private final ActivityAllAppsContainerView mAllApps; - private WorkModeSwitch mWorkModeSwitch; + private WorkUtilityView mWorkUtilityView; private final Predicate mWorkProfileMatcher; public WorkProfileManager( @@ -79,15 +79,15 @@ public class WorkProfileManager extends UserProfileManager @Override public void onActivePageChanged(int page) { - updateWorkFAB(page); + updateWorkUtilityViews(page); } - private void updateWorkFAB(int page) { - if (mWorkModeSwitch != null) { + private void updateWorkUtilityViews(int page) { + if (mWorkUtilityView != null) { if (page == MAIN || page == SEARCH) { - mWorkModeSwitch.animateVisibility(false); + mWorkUtilityView.animateVisibility(false); } else if (page == WORK && getCurrentState() == STATE_ENABLED) { - mWorkModeSwitch.animateVisibility(true); + mWorkUtilityView.animateVisibility(true); } } } @@ -104,10 +104,10 @@ public class WorkProfileManager extends UserProfileManager } boolean isEnabled = !mAllApps.getAppsStore().hasModelFlag(quietModeFlag); updateCurrentState(isEnabled ? STATE_ENABLED : STATE_DISABLED); - if (mWorkModeSwitch != null) { + if (mWorkUtilityView != null) { // reset the position of the button and clear IME insets. - mWorkModeSwitch.getImeInsets().setEmpty(); - mWorkModeSwitch.updateTranslationY(); + mWorkUtilityView.getImeInsets().setEmpty(); + mWorkUtilityView.updateTranslationY(); } } @@ -116,54 +116,54 @@ public class WorkProfileManager extends UserProfileManager if (getAH() != null) { getAH().mAppsList.updateAdapterItems(); } - if (mWorkModeSwitch != null) { - updateWorkFAB(mAllApps.getCurrentPage()); + if (mWorkUtilityView != null) { + updateWorkUtilityViews(mAllApps.getCurrentPage()); } if (getCurrentState() == STATE_ENABLED) { - attachWorkModeSwitch(); + attachWorkUtilityViews(); } else if (getCurrentState() == STATE_DISABLED) { - detachWorkModeSwitch(); + detachWorkUtilityViews(); } } /** * Creates and attaches for profile toggle button to {@link ActivityAllAppsContainerView} */ - public boolean attachWorkModeSwitch() { + public boolean attachWorkUtilityViews() { if (!mAllApps.getAppsStore().hasModelFlag( FLAG_HAS_SHORTCUT_PERMISSION | FLAG_QUIET_MODE_CHANGE_PERMISSION)) { Log.e(TAG, "unable to attach work mode switch; Missing required permissions"); return false; } - if (mWorkModeSwitch == null) { - mWorkModeSwitch = (WorkModeSwitch) mAllApps.getLayoutInflater().inflate( - R.layout.work_mode_fab, mAllApps, false); + if (mWorkUtilityView == null) { + mWorkUtilityView = (WorkUtilityView) mAllApps.getLayoutInflater().inflate( + R.layout.work_mode_utility_view, mAllApps, false); } - if (mWorkModeSwitch.getParent() == null) { - mAllApps.addView(mWorkModeSwitch); + if (mWorkUtilityView.getParent() == null) { + mAllApps.addView(mWorkUtilityView); } if (mAllApps.getCurrentPage() != WORK) { - mWorkModeSwitch.animateVisibility(false); + mWorkUtilityView.animateVisibility(false); } if (getAH() != null) { getAH().applyPadding(); } - mWorkModeSwitch.setOnClickListener(this::onWorkFabClicked); + mWorkUtilityView.setOnClickListener(this::onWorkFabClicked); return true; } /** * Removes work profile toggle button from {@link ActivityAllAppsContainerView} */ - public void detachWorkModeSwitch() { - if (mWorkModeSwitch != null && mWorkModeSwitch.getParent() == mAllApps) { - mAllApps.removeView(mWorkModeSwitch); + public void detachWorkUtilityViews() { + if (mWorkUtilityView != null && mWorkUtilityView.getParent() == mAllApps) { + mAllApps.removeView(mWorkUtilityView); } - mWorkModeSwitch = null; + mWorkUtilityView = null; } @Nullable - public WorkModeSwitch getWorkModeSwitch() { - return mWorkModeSwitch; + public WorkUtilityView getWorkUtilityView() { + return mWorkUtilityView; } private ActivityAllAppsContainerView.AdapterHolder getAH() { @@ -199,7 +199,7 @@ public class WorkProfileManager extends UserProfileManager } private void onWorkFabClicked(View view) { - if (getCurrentState() == STATE_ENABLED && mWorkModeSwitch.isEnabled()) { + if (getCurrentState() == STATE_ENABLED && mWorkUtilityView.isEnabled()) { logEvents(LAUNCHER_TURN_OFF_WORK_APPS_TAP); setWorkProfileEnabled(false); } @@ -216,7 +216,7 @@ public class WorkProfileManager extends UserProfileManager } @Override public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { - WorkModeSwitch fab = getWorkModeSwitch(); + WorkUtilityView fab = getWorkUtilityView(); if (fab == null){ return; } diff --git a/src/com/android/launcher3/allapps/WorkModeSwitch.java b/src/com/android/launcher3/allapps/WorkUtilityView.java similarity index 65% rename from src/com/android/launcher3/allapps/WorkModeSwitch.java rename to src/com/android/launcher3/allapps/WorkUtilityView.java index f1f72b267b..ad347d9697 100644 --- a/src/com/android/launcher3/allapps/WorkModeSwitch.java +++ b/src/com/android/launcher3/allapps/WorkUtilityView.java @@ -21,11 +21,13 @@ import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.content.Context; +import android.content.Intent; import android.graphics.Rect; import android.text.TextUtils; import android.util.AttributeSet; import android.view.ViewGroup; import android.view.WindowInsets; +import android.widget.ImageButton; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; @@ -36,6 +38,7 @@ import androidx.core.view.WindowInsetsCompat; import com.android.app.animation.Interpolators; import com.android.launcher3.DeviceProfile; +import com.android.launcher3.Flags; import com.android.launcher3.Insettable; import com.android.launcher3.R; import com.android.launcher3.Utilities; @@ -43,10 +46,13 @@ import com.android.launcher3.anim.AnimatedPropertySetter; import com.android.launcher3.anim.KeyboardInsetAnimationCallback; import com.android.launcher3.model.StringCache; import com.android.launcher3.views.ActivityContext; + +import java.util.ArrayList; + /** - * Work profile toggle switch shown at the bottom of AllApps work tab + * Work profile utility ViewGroup that is shown at the bottom of AllApps work tab */ -public class WorkModeSwitch extends LinearLayout implements Insettable, +public class WorkUtilityView extends LinearLayout implements Insettable, KeyboardInsetAnimationCallback.KeyboardInsetListener { private static final int TEXT_EXPAND_OPACITY_DURATION = 300; @@ -54,10 +60,14 @@ public class WorkModeSwitch extends LinearLayout implements Insettable, private static final int EXPAND_COLLAPSE_DURATION = 300; private static final int TEXT_ALPHA_EXPAND_DELAY = 80; private static final int TEXT_ALPHA_COLLAPSE_DELAY = 0; + private static final int WORK_SCHEDULER_OPACITY_DURATION = + (int) (EXPAND_COLLAPSE_DURATION * 0.75f); private static final int FLAG_FADE_ONGOING = 1 << 1; private static final int FLAG_TRANSLATION_ONGOING = 1 << 2; private static final int FLAG_IS_EXPAND = 1 << 3; private static final int SCROLL_THRESHOLD_DP = 10; + private static final float WORK_SCHEDULER_SCALE_MIN = 0.25f; + private static final float WORK_SCHEDULER_SCALE_MAX = 1f; private final Rect mInsets = new Rect(); private final Rect mImeInsets = new Rect(); @@ -67,22 +77,25 @@ public class WorkModeSwitch extends LinearLayout implements Insettable, private final int mTextMarginStart; private final int mTextMarginEnd; private final int mIconMarginStart; + private final String mWorkSchedulerIntentAction; // Threshold when user scrolls up/down to determine when should button extend/collapse private final int mScrollThreshold; - private TextView mTextView; - private ImageView mIcon; private ValueAnimator mPauseFABAnim; + private TextView mPauseText; + private ImageView mWorkIcon; + private ImageButton mSchedulerButton; - public WorkModeSwitch(@NonNull Context context) { + public WorkUtilityView(@NonNull Context context) { this(context, null, 0); } - public WorkModeSwitch(@NonNull Context context, @NonNull AttributeSet attrs) { + public WorkUtilityView(@NonNull Context context, @NonNull AttributeSet attrs) { this(context, attrs, 0); } - public WorkModeSwitch(@NonNull Context context, @NonNull AttributeSet attrs, int defStyleAttr) { + public WorkUtilityView(@NonNull Context context, @NonNull AttributeSet attrs, + int defStyleAttr) { super(context, attrs, defStyleAttr); mContext = context; mScrollThreshold = Utilities.dpToPx(SCROLL_THRESHOLD_DP); @@ -93,14 +106,17 @@ public class WorkModeSwitch extends LinearLayout implements Insettable, R.dimen.work_fab_text_end_margin); mIconMarginStart = mContext.getResources().getDimensionPixelSize( R.dimen.work_fab_icon_start_margin_expanded); + mWorkSchedulerIntentAction = mContext.getResources().getString( + R.string.work_profile_scheduler_intent); } @Override protected void onFinishInflate() { super.onFinishInflate(); - mTextView = findViewById(R.id.pause_text); - mIcon = findViewById(R.id.work_icon); + mPauseText = findViewById(R.id.pause_text); + mWorkIcon = findViewById(R.id.work_icon); + mSchedulerButton = findViewById(R.id.work_scheduler); setSelected(true); KeyboardInsetAnimationCallback keyboardInsetAnimationCallback = new KeyboardInsetAnimationCallback(this); @@ -109,6 +125,12 @@ public class WorkModeSwitch extends LinearLayout implements Insettable, addFlag(FLAG_IS_EXPAND); setInsets(mActivityContext.getDeviceProfile().getInsets()); updateStringFromCache(); + mSchedulerButton.setVisibility(GONE); + if (shouldUseScheduler()) { + mSchedulerButton.setVisibility(VISIBLE); + mSchedulerButton.setOnClickListener(view -> + mContext.startActivity(new Intent(mWorkSchedulerIntentAction))); + } } @Override @@ -183,15 +205,63 @@ public class WorkModeSwitch extends LinearLayout implements Insettable, super.setTranslationY(Math.min(translationY, -mInsets.bottom)); } + private ValueAnimator animateSchedulerScale(boolean isExpanding) { + float scaleFrom = isExpanding ? WORK_SCHEDULER_SCALE_MIN : WORK_SCHEDULER_SCALE_MAX; + float scaleTo = isExpanding ? WORK_SCHEDULER_SCALE_MAX : WORK_SCHEDULER_SCALE_MIN; + ValueAnimator schedulerScaleAnim = ObjectAnimator.ofFloat(scaleFrom, scaleTo); + schedulerScaleAnim.setDuration(EXPAND_COLLAPSE_DURATION); + schedulerScaleAnim.setInterpolator(Interpolators.STANDARD); + schedulerScaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator valueAnimator) { + float scale = (float) valueAnimator.getAnimatedValue(); + mSchedulerButton.setScaleX(scale); + mSchedulerButton.setScaleY(scale); + } + }); + schedulerScaleAnim.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationStart(Animator animation) { + if (isExpanding) { + mSchedulerButton.setVisibility(VISIBLE); + } + } - private void animatePillTransition(boolean isExpanding) { + @Override + public void onAnimationEnd(Animator animation) { + if (!isExpanding) { + mSchedulerButton.setVisibility(GONE); + } + } + }); + return schedulerScaleAnim; + } + + private ValueAnimator animateSchedulerAlpha(boolean isExpanding) { + float alphaFrom = isExpanding ? 0 : 1; + float alphaTo = isExpanding ? 1 : 0; + ValueAnimator schedulerAlphaAnim = ObjectAnimator.ofFloat(alphaFrom, alphaTo); + schedulerAlphaAnim.setDuration(WORK_SCHEDULER_OPACITY_DURATION); + schedulerAlphaAnim.setStartDelay(isExpanding ? 0 : + EXPAND_COLLAPSE_DURATION - WORK_SCHEDULER_OPACITY_DURATION); + schedulerAlphaAnim.setInterpolator(Interpolators.STANDARD); + schedulerAlphaAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator valueAnimator) { + mSchedulerButton.setAlpha((float) valueAnimator.getAnimatedValue()); + } + }); + return schedulerAlphaAnim; + } + + private void animateWorkUtilityViews(boolean isExpanding) { if (!shouldAnimate(isExpanding)) { return; } AnimatorSet animatorSet = new AnimatedPropertySetter().buildAnim(); - mTextView.measure(0,0); - int currentWidth = mTextView.getWidth(); - int fullWidth = mTextView.getMeasuredWidth(); + mPauseText.measure(0,0); + int currentWidth = mPauseText.getWidth(); + int fullWidth = mPauseText.getMeasuredWidth(); float from = isExpanding ? 0 : currentWidth; float to = isExpanding ? fullWidth : 0; mPauseFABAnim = ObjectAnimator.ofFloat(from, to); @@ -203,15 +273,15 @@ public class WorkModeSwitch extends LinearLayout implements Insettable, float translation = (float) valueAnimator.getAnimatedValue(); float translationFraction = translation / fullWidth; ViewGroup.MarginLayoutParams textViewLayoutParams = - (ViewGroup.MarginLayoutParams) mTextView.getLayoutParams(); + (ViewGroup.MarginLayoutParams) mPauseText.getLayoutParams(); textViewLayoutParams.width = (int) translation; textViewLayoutParams.setMarginStart((int) (mTextMarginStart * translationFraction)); textViewLayoutParams.setMarginEnd((int) (mTextMarginEnd * translationFraction)); - mTextView.setLayoutParams(textViewLayoutParams); + mPauseText.setLayoutParams(textViewLayoutParams); ViewGroup.MarginLayoutParams iconLayoutParams = - (ViewGroup.MarginLayoutParams) mIcon.getLayoutParams(); + (ViewGroup.MarginLayoutParams) mWorkIcon.getLayoutParams(); iconLayoutParams.setMarginStart((int) (mIconMarginStart * translationFraction)); - mIcon.setLayoutParams(iconLayoutParams); + mWorkIcon.setLayoutParams(iconLayoutParams); } }); mPauseFABAnim.addListener(new AnimatorListenerAdapter() { @@ -220,21 +290,28 @@ public class WorkModeSwitch extends LinearLayout implements Insettable, if (isExpanding) { addFlag(FLAG_IS_EXPAND); } else { - mTextView.setVisibility(GONE); + mPauseText.setVisibility(GONE); removeFlag(FLAG_IS_EXPAND); } - mTextView.setHorizontallyScrolling(false); - mTextView.setEllipsize(TextUtils.TruncateAt.END); + mPauseText.setHorizontallyScrolling(false); + mPauseText.setEllipsize(TextUtils.TruncateAt.END); } @Override public void onAnimationStart(Animator animator) { - mTextView.setHorizontallyScrolling(true); - mTextView.setVisibility(VISIBLE); - mTextView.setEllipsize(null); + mPauseText.setHorizontallyScrolling(true); + mPauseText.setVisibility(VISIBLE); + mPauseText.setEllipsize(null); } }); - animatorSet.playTogether(mPauseFABAnim, updatePauseTextAlpha(isExpanding)); + ArrayList animatorList = new ArrayList<>(); + animatorList.add(mPauseFABAnim); + animatorList.add(updatePauseTextAlpha(isExpanding)); + if (shouldUseScheduler()) { + animatorList.add(animateSchedulerScale(isExpanding)); + animatorList.add(animateSchedulerAlpha(isExpanding)); + } + animatorSet.playTogether(animatorList); animatorSet.start(); } @@ -250,7 +327,7 @@ public class WorkModeSwitch extends LinearLayout implements Insettable, alphaAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { - mTextView.setAlpha((float) valueAnimator.getAnimatedValue()); + mPauseText.setAlpha((float) valueAnimator.getAnimatedValue()); } }); return alphaAnim; @@ -287,11 +364,11 @@ public class WorkModeSwitch extends LinearLayout implements Insettable, } public void extend() { - animatePillTransition(true); + animateWorkUtilityViews(true); } - public void shrink(){ - animatePillTransition(false); + public void shrink() { + animateWorkUtilityViews(false); } /** @@ -310,7 +387,11 @@ public class WorkModeSwitch extends LinearLayout implements Insettable, public void updateStringFromCache(){ StringCache cache = mActivityContext.getStringCache(); if (cache != null) { - mTextView.setText(cache.workProfilePauseButton); + mPauseText.setText(cache.workProfilePauseButton); } } + + private boolean shouldUseScheduler() { + return Flags.workSchedulerInWorkProfile() && !mWorkSchedulerIntentAction.isEmpty(); + } } diff --git a/tests/src/com/android/launcher3/ui/TaplWorkProfileTest.java b/tests/src/com/android/launcher3/ui/TaplWorkProfileTest.java index a45e3bbb84..33ffd1dd40 100644 --- a/tests/src/com/android/launcher3/ui/TaplWorkProfileTest.java +++ b/tests/src/com/android/launcher3/ui/TaplWorkProfileTest.java @@ -158,16 +158,16 @@ public class TaplWorkProfileTest extends AbstractLauncherUiTest { waitForLauncherCondition("work profile initial state check failed", launcher -> - manager.getWorkModeSwitch() != null + manager.getWorkUtilityView() != null && manager.getCurrentState() == WorkProfileManager.STATE_ENABLED - && manager.getWorkModeSwitch().isEnabled(), + && manager.getWorkUtilityView().isEnabled(), LauncherInstrumentation.WAIT_TIME_MS); //start work profile toggle OFF test executeOnLauncher(l -> { // Ensure updates are not deferred so notification happens when apps pause. l.getAppsView().getAppsStore().disableDeferUpdates(DEFER_UPDATES_TEST); - l.getAppsView().getWorkManager().getWorkModeSwitch().performClick(); + l.getAppsView().getWorkManager().getWorkUtilityView().performClick(); }); waitForLauncherCondition("Work profile toggle OFF failed", launcher -> { From 1fa2840e82be1ca35c723d5863ea7ef256292b5d Mon Sep 17 00:00:00 2001 From: Brandon Dayauon Date: Fri, 1 Nov 2024 13:27:48 -0700 Subject: [PATCH 15/15] Make sure work button is collapsed when keyboard is up upon going to app drawer Call shrink so that work button is collapsed when keyboard is up. bug:361589193 Test - manual: video before:https://drive.google.com/file/d/1OChJkEJEWrsuUtEaac2jtc15uGkOeGAm/view?usp=sharing after: https://drive.google.com/file/d/1DXGia25u4JzWRLTiwqlKQu8TYjyL9SEI/view?usp=sharing Flag: com.android.launcher3.work_scheduler_in_work_profile Change-Id: Ifafb76b61f0d2a5e9c6b60519adc300c911b20dc --- src/com/android/launcher3/allapps/WorkUtilityView.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/com/android/launcher3/allapps/WorkUtilityView.java b/src/com/android/launcher3/allapps/WorkUtilityView.java index ad347d9697..4b58ab06dc 100644 --- a/src/com/android/launcher3/allapps/WorkUtilityView.java +++ b/src/com/android/launcher3/allapps/WorkUtilityView.java @@ -188,8 +188,10 @@ public class WorkUtilityView extends LinearLayout implements Insettable, WindowInsetsCompat.toWindowInsetsCompat(insets, this); if (windowInsetsCompat.isVisible(WindowInsetsCompat.Type.ime())) { setInsets(mImeInsets, windowInsetsCompat.getInsets(WindowInsetsCompat.Type.ime())); + shrink(); } else { mImeInsets.setEmpty(); + extend(); } updateTranslationY(); return super.onApplyWindowInsets(insets);