diff --git a/Android.bp b/Android.bp index 010ea45c3d..19d2a5893b 100644 --- a/Android.bp +++ b/Android.bp @@ -23,42 +23,66 @@ min_launcher3_sdk_version = "26" // All sources are split so they can be reused in many other libraries/apps in other folders filegroup { name: "launcher-src", - srcs: [ "src/**/*.java", "src/**/*.kt" ], + srcs: [ + "src/**/*.java", + "src/**/*.kt", + ], } filegroup { name: "launcher-quickstep-src", - srcs: [ "quickstep/src/**/*.java", "quickstep/src/**/*.kt" ], + srcs: [ + "quickstep/src/**/*.java", + "quickstep/src/**/*.kt", + ], } filegroup { name: "launcher-go-src", - srcs: [ "go/src/**/*.java", "go/src/**/*.kt" ], + srcs: [ + "go/src/**/*.java", + "go/src/**/*.kt", + ], } filegroup { name: "launcher-go-quickstep-src", - srcs: [ "go/quickstep/src/**/*.java", "go/quickstep/src/**/*.kt" ], + srcs: [ + "go/quickstep/src/**/*.java", + "go/quickstep/src/**/*.kt", + ], } filegroup { name: "launcher-src_shortcuts_overrides", - srcs: [ "src_shortcuts_overrides/**/*.java", "src_shortcuts_overrides/**/*.kt" ], + srcs: [ + "src_shortcuts_overrides/**/*.java", + "src_shortcuts_overrides/**/*.kt", + ], } filegroup { name: "launcher-src_ui_overrides", - srcs: [ "src_ui_overrides/**/*.java", "src_ui_overrides/**/*.kt" ], + srcs: [ + "src_ui_overrides/**/*.java", + "src_ui_overrides/**/*.kt", + ], } filegroup { name: "launcher-ext_tests", - srcs: [ "ext_tests/**/*.java", "ext_tests/**/*.kt" ], + srcs: [ + "ext_tests/**/*.java", + "ext_tests/**/*.kt", + ], } filegroup { name: "launcher-quickstep-ext_tests", - srcs: [ "quickstep/ext_tests/**/*.java", "quickstep/ext_tests/**/*.kt" ], + srcs: [ + "quickstep/ext_tests/**/*.java", + "quickstep/ext_tests/**/*.kt", + ], } // Proguard files for Launcher3 @@ -85,9 +109,12 @@ android_library { srcs: [ "tests/tapl/**/*.java", ], - resource_dirs: [ ], + resource_dirs: [], manifest: "tests/tapl/AndroidManifest.xml", platform_apis: true, + lint: { + baseline_filename: "lint-baseline.xml", + }, } java_library_static { @@ -99,12 +126,15 @@ java_library_static { sdk_version: "current", proto: { type: "lite", - local_include_dirs:[ + local_include_dirs: [ "protos", "protos_overrides", ], }, static_libs: ["libprotobuf-java-lite"], + lint: { + baseline_filename: "lint-baseline.xml", + }, } java_library_static { @@ -115,14 +145,17 @@ java_library_static { sdk_version: "current", proto: { type: "lite", - local_include_dirs:[ + local_include_dirs: [ "quickstep/protos_overrides", ], }, static_libs: [ - "libprotobuf-java-lite", - "launcher_log_protos_lite" - ], + "libprotobuf-java-lite", + "launcher_log_protos_lite", + ], + lint: { + baseline_filename: "lint-baseline.xml", + }, } java_library { @@ -134,12 +167,15 @@ java_library { sdk_version: "current", min_sdk_version: min_launcher3_sdk_version, + lint: { + baseline_filename: "lint-baseline.xml", + }, } // Library with all the dependencies for building Launcher3 android_library { name: "Launcher3ResLib", - srcs: [ ], + srcs: [], resource_dirs: ["res"], static_libs: [ "LauncherPluginLib", @@ -154,7 +190,7 @@ android_library { "com.google.android.material_material", "iconloader_base", "view_capture", - "animationlib" + "animationlib", ], manifest: "AndroidManifest-common.xml", sdk_version: "current", @@ -236,7 +272,7 @@ android_app { // Library with all the dependencies for building quickstep android_library { name: "QuickstepResLib", - srcs: [ ], + srcs: [], resource_dirs: [ "quickstep/res", ], @@ -253,9 +289,11 @@ android_library { ], manifest: "quickstep/AndroidManifest.xml", min_sdk_version: "current", + lint: { + baseline_filename: "lint-baseline.xml", + }, } - // Library with all the dependencies for building Launcher Go android_library { name: "LauncherGoResLib", @@ -360,7 +398,10 @@ android_app { manifest: "go/AndroidManifest.xml", jacoco: { include_filter: ["com.android.launcher3.*"], - } + }, + lint: { + baseline_filename: "lint-baseline.xml", + }, } @@ -396,7 +437,10 @@ android_app { manifest: "quickstep/AndroidManifest.xml", jacoco: { include_filter: ["com.android.launcher3.*"], - } + }, + lint: { + baseline_filename: "lint-baseline.xml", + }, } @@ -414,7 +458,7 @@ android_app { min_sdk_version: "current", target_sdk_version: "current", - srcs: [ ], + srcs: [], resource_dirs: [ "go/quickstep/res", @@ -446,7 +490,9 @@ android_app { manifest: "quickstep/AndroidManifest.xml", jacoco: { include_filter: ["com.android.launcher3.*"], - } + }, + lint: { + baseline_filename: "lint-baseline.xml", + }, } - diff --git a/quickstep/src/com/android/launcher3/WidgetPickerActivity.java b/quickstep/src/com/android/launcher3/WidgetPickerActivity.java index 477cd84444..575ad9ee6a 100644 --- a/quickstep/src/com/android/launcher3/WidgetPickerActivity.java +++ b/quickstep/src/com/android/launcher3/WidgetPickerActivity.java @@ -16,6 +16,7 @@ package com.android.launcher3; +import static android.content.ClipDescription.MIMETYPE_TEXT_INTENT; import static android.view.WindowInsets.Type.navigationBars; import static android.view.WindowInsets.Type.statusBars; @@ -23,6 +24,8 @@ import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; import android.appwidget.AppWidgetProviderInfo; +import android.content.ClipData; +import android.content.ClipDescription; import android.content.Intent; import android.os.Bundle; import android.view.View; @@ -43,6 +46,14 @@ import java.util.ArrayList; /** An Activity that can host Launcher's widget picker. */ public class WidgetPickerActivity extends BaseActivity { + /** + * Name of the extra that indicates that a widget being dragged. + * + *

When set to "true" in the result of startActivityForResult, the client that launched the + * picker knows that activity was closed due to pending drag. + */ + private static final String EXTRA_IS_PENDING_WIDGET_DRAG = "is_pending_widget_drag"; + private SimpleDragLayer mDragLayer; private WidgetsModel mModel; private final PopupDataProvider mPopupDataProvider = new PopupDataProvider(i -> {}); @@ -102,6 +113,46 @@ public class WidgetPickerActivity extends BaseActivity { }; } + @Override + public View.OnLongClickListener getAllAppsItemLongClickListener() { + return view -> { + if (!(view instanceof WidgetCell widgetCell)) return false; + + if (widgetCell.getWidgetView().getDrawable() == null + && widgetCell.getAppWidgetHostViewPreview() == null) { + // The widget preview hasn't been loaded; so, we abort the drag. + return false; + } + + final AppWidgetProviderInfo info = widgetCell.getWidgetItem().widgetInfo; + if (info == null || info.provider == null) { + return false; + } + + ClipData clipData = new ClipData( + new ClipDescription( + /* label= */ "", // not displayed anywhere; so, set to empty. + new String[]{MIMETYPE_TEXT_INTENT} + ), + new ClipData.Item(new Intent() + .putExtra(Intent.EXTRA_USER, info.getProfile()) + .putExtra(Intent.EXTRA_COMPONENT_NAME, info.provider)) + ); + + // Set result indicating activity was closed due a widget being dragged. + setResult(RESULT_OK, new Intent() + .putExtra(EXTRA_IS_PENDING_WIDGET_DRAG, true)); + + // DRAG_FLAG_GLOBAL permits dragging data beyond app window. + return view.startDragAndDrop( + clipData, + new View.DragShadowBuilder(view), + /* myLocalState= */ null, + View.DRAG_FLAG_GLOBAL + ); + }; + } + private void refreshAndBindWidgets() { MODEL_EXECUTOR.execute(() -> { LauncherAppState app = LauncherAppState.getInstance(this); diff --git a/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java index f9816102d4..535c8ecec6 100644 --- a/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java @@ -104,6 +104,13 @@ public class FallbackTaskbarUIController extends TaskbarUIController { } } + @Override + protected boolean isInOverview() { + TopTaskTracker.CachedTaskInfo topTask = TopTaskTracker.INSTANCE + .get(mControllers.taskbarActivityContext).getCachedTopTask(true); + return topTask.isRecentsTask(); + } + @Override public RecentsView getRecentsView() { return mRecentsActivity.getOverviewPanel(); diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index fb25ec12d7..eff6e27898 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -42,7 +42,9 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_V import android.animation.AnimatorSet; import android.animation.ValueAnimator; +import android.app.ActivityManager.RunningTaskInfo; import android.app.ActivityOptions; +import android.app.ActivityTaskManager; import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; @@ -130,10 +132,13 @@ import com.android.systemui.unfold.updates.RotationChangeProvider; import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider; import java.io.PrintWriter; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Optional; +import java.util.Set; import java.util.function.Consumer; +import java.util.stream.Collectors; /** * The {@link ActivityContext} with which we inflate Taskbar-related Views. This allows UI elements @@ -1147,15 +1152,25 @@ public class TaskbarActivityContext extends BaseTaskbarContext { @Nullable Task foundTask = foundTasks[0]; if (foundTask != null) { TaskView foundTaskView = recents.getTaskViewByTaskId(foundTask.key.id); - if (foundTaskView != null - && foundTaskView.isVisibleToUser()) { - TestLogging.recordEvent( - TestProtocol.SEQUENCE_MAIN, "start: taskbarAppIcon"); - foundTaskView.launchTasks(); - return; + if (foundTaskView != null) { + // The foundTaskView contains the 1-2 taskIds we are looking for. + // If we are already in-app and running the correct tasks, no need + // to do anything. + if (FeatureFlags.enableAppPairs() + && isAlreadyInApp(foundTaskView.getTaskIds())) { + return; + } + // If we are in Overview and the TaskView tile is visible, expand that + // tile. + if (foundTaskView.isVisibleToUser()) { + TestLogging.recordEvent( + TestProtocol.SEQUENCE_MAIN, "start: taskbarAppIcon"); + foundTaskView.launchTasks(); + return; + } } } - + // If none of the above cases apply, launch a new app or app pair. if (findExactPairMatch) { // We did not find the app pair we were looking for, so launch one. recents.getSplitSelectController().getAppPairsController().launchAppPair( @@ -1167,6 +1182,27 @@ public class TaskbarActivityContext extends BaseTaskbarContext { ); } + /** + * Checks if a given list of taskIds are all already running in-app. + */ + private boolean isAlreadyInApp(int[] ids) { + if (mControllers.uiController.isInOverview()) { + return false; + } + + RunningTaskInfo[] currentlyRunningTasks = ActivityManagerWrapper.getInstance() + .getRunningTasks(false /* filterOnlyVisibleRecents */); + Set currentlyRunningIds = Arrays.stream(currentlyRunningTasks) + .map(task -> task.taskId).collect(Collectors.toSet()); + + for (int id : ids) { + if (id != ActivityTaskManager.INVALID_TASK_ID && !currentlyRunningIds.contains(id)) { + return false; + } + } + return true; + } + private void startItemInfoActivity(ItemInfo info) { Intent intent = new Intent(info.getIntent()) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); diff --git a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java index 7c24ba8fe6..0f88aac4fc 100644 --- a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java +++ b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java @@ -287,7 +287,7 @@ public class LauncherBackAnimationController { mBackInProgress = true; RemoteAnimationTarget appTarget = backEvent.getDepartingAnimationTarget(); - if (appTarget == null) { + if (appTarget == null || appTarget.leash == null || !appTarget.leash.isValid()) { return; } @@ -456,6 +456,7 @@ public class LauncherBackAnimationController { mBackInProgress /* fromPredictiveBack */); startTransitionAnimations(pair.first, pair.second); mLauncher.clearForceInvisibleFlag(INVISIBLE_ALL); + customizeStatusBarAppearance(true); } private void finishAnimation() { diff --git a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java index 03037914af..9d942c5380 100644 --- a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java +++ b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java @@ -149,6 +149,11 @@ public class QuickstepTestInformationHandler extends TestInformationHandler { case TestProtocol.REQUEST_REFRESH_OVERVIEW_TARGET: runOnTISBinder(TouchInteractionService.TISBinder::refreshOverviewTarget); return response; + + case TestProtocol.REQUEST_RECREATE_TASKBAR: + // Allow null-pointer to catch illegal states. + runOnTISBinder(tisBinder -> tisBinder.getTaskbarManager().recreateTaskbar()); + return response; } return super.call(method, arg, extras); diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 62ce256c7e..d5efd54976 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -56,7 +56,7 @@ 13dp 24dp - 22dp + 23dp 24dp diff --git a/src/com/android/launcher3/model/GridSizeMigrationUtil.java b/src/com/android/launcher3/model/GridSizeMigrationUtil.java index efd5574519..af66431d47 100644 --- a/src/com/android/launcher3/model/GridSizeMigrationUtil.java +++ b/src/com/android/launcher3/model/GridSizeMigrationUtil.java @@ -262,7 +262,8 @@ public class GridSizeMigrationUtil { String srcTableName, String destTableName) { int id = copyEntryAndUpdate(helper, entry, srcTableName, destTableName); - if (entry.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) { + if (entry.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER + || entry.itemType == LauncherSettings.Favorites.ITEM_TYPE_APP_PAIR) { for (Set itemIds : entry.mFolderItems.values()) { for (int itemId : itemIds) { copyEntryAndUpdate(helper, itemId, id, srcTableName, destTableName);