diff --git a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java index 85daefff40..5777fb9a7f 100644 --- a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java +++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java @@ -274,7 +274,7 @@ public class DepthController implements StateHandler, public void onOverlayScrollChanged(float progress) { // Round out the progress to dedupe frequent, non-perceptable updates int progressI = (int) (progress * 256); - float progressF = progressI / 256f; + float progressF = Utilities.boundToRange(progressI / 256f, 0f, 1f); if (Float.compare(mOverlayScrollProgress, progressF) == 0) { return; } diff --git a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginInitializerImpl.java b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginInitializerImpl.java index d14e8efdd6..0e12e30ce7 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginInitializerImpl.java +++ b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginInitializerImpl.java @@ -14,34 +14,17 @@ package com.android.launcher3.uioverrides.plugins; -import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; - import android.content.Context; -import android.os.Looper; import com.android.launcher3.Utilities; import com.android.systemui.shared.plugins.PluginInitializer; public class PluginInitializerImpl implements PluginInitializer { @Override - public Looper getBgLooper() { - return MODEL_EXECUTOR.getLooper(); - } - - @Override - public void onPluginManagerInit() { - } - - @Override - public String[] getWhitelistedPlugins(Context context) { + public String[] getPrivilegedPlugins(Context context) { return new String[0]; } - @Override - public PluginEnablerImpl getPluginEnabler(Context context) { - return new PluginEnablerImpl(context); - } - @Override public void handleWtfs() { } diff --git a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java index 2e422b77f6..15f89adff0 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java +++ b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java @@ -16,6 +16,8 @@ package com.android.launcher3.uioverrides.plugins; import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS; +import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; + import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -24,6 +26,7 @@ import android.content.pm.ResolveInfo; import com.android.launcher3.util.MainThreadInitializedObject; import com.android.systemui.plugins.Plugin; import com.android.systemui.plugins.PluginListener; +import com.android.systemui.shared.plugins.PluginInstanceManager; import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.shared.plugins.PluginManagerImpl; import com.android.systemui.shared.plugins.PluginPrefs; @@ -31,6 +34,7 @@ import com.android.systemui.shared.plugins.PluginPrefs; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.Set; public class PluginManagerWrapper { @@ -47,8 +51,14 @@ public class PluginManagerWrapper { private PluginManagerWrapper(Context c) { mContext = c; PluginInitializerImpl pluginInitializer = new PluginInitializerImpl(); - mPluginManager = new PluginManagerImpl(c, pluginInitializer); - mPluginEnabler = pluginInitializer.getPluginEnabler(c); + mPluginEnabler = new PluginEnablerImpl(c); + PluginInstanceManager.Factory instanceManagerFactory = new PluginInstanceManager.Factory( + c, c.getPackageManager(), MODEL_EXECUTOR.getLooper(), pluginInitializer); + + mPluginManager = new PluginManagerImpl(c, instanceManagerFactory, + pluginInitializer.isDebuggable(), + Optional.ofNullable(Thread.getDefaultUncaughtExceptionHandler()), mPluginEnabler, + new PluginPrefs(c), pluginInitializer.getPrivilegedPlugins(c)); } public PluginEnablerImpl getPluginEnabler() { diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java index e4f5a19c75..45e7e695a4 100644 --- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java +++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java @@ -59,7 +59,6 @@ import com.android.launcher3.testcomponent.TestCommandReceiver; import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.util.Wait; import com.android.launcher3.util.rule.FailureWatcher; -import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord; import com.android.quickstep.views.RecentsView; import org.junit.After; @@ -215,7 +214,6 @@ public class FallbackRecentsTest { // b/143488140 //@NavigationModeSwitch @Test - @ScreenRecord // b/187080582 public void testOverview() { startAppFast(getAppPackageName()); startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR)); diff --git a/res/values/attrs.xml b/res/values/attrs.xml index d05b69e73f..2c01163730 100644 --- a/res/values/attrs.xml +++ b/res/values/attrs.xml @@ -152,6 +152,12 @@ + + + + + + diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java index b93bfd6ef8..1fc895822f 100644 --- a/src/com/android/launcher3/InvariantDeviceProfile.java +++ b/src/com/android/launcher3/InvariantDeviceProfile.java @@ -35,6 +35,7 @@ import android.graphics.Rect; import android.text.TextUtils; import android.util.AttributeSet; import android.util.DisplayMetrics; +import android.util.Log; import android.util.SparseArray; import android.util.TypedValue; import android.util.Xml; @@ -68,6 +69,8 @@ public class InvariantDeviceProfile { private static final int DEFAULT_TRUE = -1; private static final int DEFAULT_SPLIT_DISPLAY = 2; + private static final int GRID_ENABLED_ALL_DISPLAYS = 0; + private static final int GRID_ENABLED_SINGLE_DISPLAY = 1; private static final String KEY_IDP_GRID_NAME = "idp_grid_name"; @@ -104,6 +107,7 @@ public class InvariantDeviceProfile { public float iconTextSize; public float allAppsIconSize; public float allAppsIconTextSize; + public boolean isSplitDisplay; public float minCellHeight; public float minCellWidth; @@ -280,6 +284,7 @@ public class InvariantDeviceProfile { numFolderColumns = closestProfile.numFolderColumns; isScalable = closestProfile.isScalable; devicePaddingId = closestProfile.devicePaddingId; + this.isSplitDisplay = isSplitDisplay; mExtraAttrs = closestProfile.extraAttrs; @@ -390,16 +395,19 @@ public class InvariantDeviceProfile { if ((type == XmlPullParser.START_TAG) && GridOption.TAG_NAME.equals(parser.getName())) { - GridOption gridOption = new GridOption(context, Xml.asAttributeSet(parser)); - final int displayDepth = parser.getDepth(); - while (((type = parser.next()) != XmlPullParser.END_TAG || - parser.getDepth() > displayDepth) - && type != XmlPullParser.END_DOCUMENT) { - if ((type == XmlPullParser.START_TAG) && "display-option".equals( - parser.getName())) { - profiles.add(new DisplayOption(gridOption, context, - Xml.asAttributeSet(parser), - isSplitDisplay ? DEFAULT_SPLIT_DISPLAY : DEFAULT_TRUE)); + GridOption gridOption = + new GridOption(context, Xml.asAttributeSet(parser), isSplitDisplay); + if (gridOption.isEnabled) { + final int displayDepth = parser.getDepth(); + while (((type = parser.next()) != XmlPullParser.END_TAG + || parser.getDepth() > displayDepth) + && type != XmlPullParser.END_DOCUMENT) { + if ((type == XmlPullParser.START_TAG) && "display-option".equals( + parser.getName())) { + profiles.add(new DisplayOption(gridOption, context, + Xml.asAttributeSet(parser), + isSplitDisplay ? DEFAULT_SPLIT_DISPLAY : DEFAULT_TRUE)); + } } } } @@ -411,7 +419,7 @@ public class InvariantDeviceProfile { ArrayList filteredProfiles = new ArrayList<>(); if (!TextUtils.isEmpty(gridName)) { for (DisplayOption option : profiles) { - if (gridName.equals(option.grid.name)) { + if (gridName.equals(option.grid.name) && option.grid.isEnabled) { filteredProfiles.add(option); } } @@ -430,6 +438,32 @@ public class InvariantDeviceProfile { return filteredProfiles; } + /** + * @return all the grid options that can be shown on the device + */ + public List parseAllGridOptions(Context context) { + List result = new ArrayList<>(); + try (XmlResourceParser parser = context.getResources().getXml(R.xml.device_profiles)) { + final int depth = parser.getDepth(); + int type; + while (((type = parser.next()) != XmlPullParser.END_TAG + || parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) { + if ((type == XmlPullParser.START_TAG) + && GridOption.TAG_NAME.equals(parser.getName())) { + GridOption option = + new GridOption(context, Xml.asAttributeSet(parser), isSplitDisplay); + if (option.isEnabled) { + result.add(option); + } + } + } + } catch (IOException | XmlPullParserException e) { + Log.e(TAG, "Error parsing device profile", e); + return Collections.emptyList(); + } + return result; + } + private int getLauncherIconDensity(int requiredSize) { // Densities typically defined by an app. int[] densityBuckets = new int[] { @@ -591,6 +625,7 @@ public class InvariantDeviceProfile { public final String name; public final int numRows; public final int numColumns; + public final boolean isEnabled; private final int numFolderRows; private final int numFolderColumns; @@ -610,7 +645,7 @@ public class InvariantDeviceProfile { private final SparseArray extraAttrs; - public GridOption(Context context, AttributeSet attrs) { + public GridOption(Context context, AttributeSet attrs, boolean isSplitDisplay) { TypedArray a = context.obtainStyledAttributes( attrs, R.styleable.GridDisplayOption); name = a.getString(R.styleable.GridDisplayOption_name); @@ -643,6 +678,12 @@ public class InvariantDeviceProfile { devicePaddingId = a.getResourceId( R.styleable.GridDisplayOption_devicePaddingId, 0); + final int enabledInt = + a.getInteger(R.styleable.GridDisplayOption_gridEnabled, + GRID_ENABLED_ALL_DISPLAYS); + isEnabled = enabledInt == GRID_ENABLED_ALL_DISPLAYS + || enabledInt == GRID_ENABLED_SINGLE_DISPLAY && !isSplitDisplay; + a.recycle(); extraAttrs = Themes.createValueMap(context, attrs, IntArray.wrap(R.styleable.GridDisplayOption)); diff --git a/src/com/android/launcher3/graphics/GridCustomizationsProvider.java b/src/com/android/launcher3/graphics/GridCustomizationsProvider.java index e4f5539dbd..fc8d855801 100644 --- a/src/com/android/launcher3/graphics/GridCustomizationsProvider.java +++ b/src/com/android/launcher3/graphics/GridCustomizationsProvider.java @@ -9,7 +9,6 @@ import android.annotation.TargetApi; import android.content.ContentProvider; import android.content.ContentValues; import android.content.pm.PackageManager; -import android.content.res.XmlResourceParser; import android.database.Cursor; import android.database.MatrixCursor; import android.net.Uri; @@ -23,23 +22,13 @@ import android.os.Message; import android.os.Messenger; import android.util.ArrayMap; import android.util.Log; -import android.util.Xml; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.InvariantDeviceProfile.GridOption; -import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.util.Executors; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - /** * Exposes various launcher grid options and allows the caller to change them. * APIs: @@ -94,7 +83,7 @@ public class GridCustomizationsProvider extends ContentProvider { MatrixCursor cursor = new MatrixCursor(new String[] { KEY_NAME, KEY_ROWS, KEY_COLS, KEY_PREVIEW_COUNT, KEY_IS_DEFAULT}); InvariantDeviceProfile idp = InvariantDeviceProfile.INSTANCE.get(getContext()); - for (GridOption gridOption : parseAllGridOptions()) { + for (GridOption gridOption : idp.parseAllGridOptions(getContext())) { cursor.newRow() .add(KEY_NAME, gridOption.name) .add(KEY_ROWS, gridOption.numRows) @@ -116,25 +105,6 @@ public class GridCustomizationsProvider extends ContentProvider { } } - private List parseAllGridOptions() { - List result = new ArrayList<>(); - try (XmlResourceParser parser = getContext().getResources().getXml(R.xml.device_profiles)) { - final int depth = parser.getDepth(); - int type; - while (((type = parser.next()) != XmlPullParser.END_TAG || - parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) { - if ((type == XmlPullParser.START_TAG) - && GridOption.TAG_NAME.equals(parser.getName())) { - result.add(new GridOption(getContext(), Xml.asAttributeSet(parser))); - } - } - } catch (IOException | XmlPullParserException e) { - Log.e(TAG, "Error parsing device profile", e); - return Collections.emptyList(); - } - return result; - } - @Override public String getType(Uri uri) { return "vnd.android.cursor.dir/launcher_grid"; @@ -155,9 +125,10 @@ public class GridCustomizationsProvider extends ContentProvider { switch (uri.getPath()) { case KEY_DEFAULT_GRID: { String gridName = values.getAsString(KEY_NAME); + InvariantDeviceProfile idp = InvariantDeviceProfile.INSTANCE.get(getContext()); // Verify that this is a valid grid option GridOption match = null; - for (GridOption option : parseAllGridOptions()) { + for (GridOption option : idp.parseAllGridOptions(getContext())) { if (option.name.equals(gridName)) { match = option; break; @@ -167,8 +138,7 @@ public class GridCustomizationsProvider extends ContentProvider { return 0; } - InvariantDeviceProfile.INSTANCE.get(getContext()) - .setCurrentGrid(getContext(), gridName); + idp.setCurrentGrid(getContext(), gridName); return 1; } case ICON_THEMED: diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java index bb726f8951..55995f2f66 100644 --- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java +++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java @@ -270,13 +270,13 @@ public class LauncherPreviewRenderer extends ContextWrapper CellLayout leftPanel = mRootView.findViewById(R.id.workspace_left); leftPanel.setPadding(mDp.workspacePadding.left + mDp.cellLayoutPaddingLeftRightPx, mDp.workspacePadding.top, - mDp.workspacePadding.right + mDp.cellLayoutPaddingLeftRightPx, + mDp.workspacePadding.right, mDp.workspacePadding.bottom); mWorkspaceScreens.put(LEFT_PANEL_ID, leftPanel); } CellLayout firstScreen = mRootView.findViewById(R.id.workspace); - firstScreen.setPadding(mDp.workspacePadding.left + mDp.cellLayoutPaddingLeftRightPx, + firstScreen.setPadding(mDp.workspacePadding.left, mDp.workspacePadding.top, mDp.workspacePadding.right + mDp.cellLayoutPaddingLeftRightPx, mDp.workspacePadding.bottom); diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java index 4beb617dd9..881f50cafb 100644 --- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java +++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java @@ -36,7 +36,6 @@ import com.android.launcher3.tapl.AppIconMenu; import com.android.launcher3.tapl.AppIconMenuItem; import com.android.launcher3.tapl.Widgets; import com.android.launcher3.tapl.Workspace; -import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord; import com.android.launcher3.views.OptionsPopupView; import com.android.launcher3.widget.picker.WidgetsFullSheet; import com.android.launcher3.widget.picker.WidgetsRecyclerView; @@ -97,7 +96,6 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest { } @Test - @ScreenRecord //b/187080582 public void testDevicePressMenu() throws Exception { mDevice.pressMenu(); mDevice.waitForIdle(); diff --git a/tests/src/com/android/launcher3/util/rule/ShellCommandRule.java b/tests/src/com/android/launcher3/util/rule/ShellCommandRule.java index 2b2fef4ae6..08953fc4c8 100644 --- a/tests/src/com/android/launcher3/util/rule/ShellCommandRule.java +++ b/tests/src/com/android/launcher3/util/rule/ShellCommandRule.java @@ -21,7 +21,6 @@ import static com.android.launcher3.tapl.TestHelpers.getLauncherInMyProcess; import android.content.ComponentName; import android.content.pm.ActivityInfo; -import android.util.Log; import androidx.annotation.Nullable; import androidx.test.InstrumentationRegistry; @@ -103,8 +102,6 @@ public class ShellCommandRule implements TestRule { */ public static ShellCommandRule setDefaultLauncher() { final ActivityInfo launcher = getLauncherInMyProcess(); - Log.d("b/187080582", "Launcher: " + new ComponentName(launcher.packageName, launcher.name) - .flattenToString()); return new ShellCommandRule(getLauncherCommand(launcher), null, true, () -> Assert.assertEquals("Setting default launcher failed", new ComponentName(launcher.packageName, launcher.name) diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 065af003ab..6cdfd5ba25 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -66,6 +66,7 @@ import androidx.test.uiautomator.Until; import com.android.launcher3.ResourceUtils; import com.android.launcher3.testing.TestProtocol; +import com.android.systemui.shared.system.ContextUtils; import com.android.systemui.shared.system.QuickStepContract; import org.junit.Assert; @@ -245,12 +246,16 @@ public final class LauncherInstrumentation { ComponentName cn = new ComponentName(pi.packageName, pi.name); if (pm.getComponentEnabledSetting(cn) != COMPONENT_ENABLED_STATE_ENABLED) { - mInstrumentation.getUiAutomation().adoptShellPermissionIdentity( - android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); - try { + if (TestHelpers.isInLauncherProcess()) { pm.setComponentEnabledSetting(cn, COMPONENT_ENABLED_STATE_ENABLED, DONT_KILL_APP); - } finally { - mInstrumentation.getUiAutomation().dropShellPermissionIdentity(); + } else { + try { + final int userId = ContextUtils.getUserId(getContext()); + mDevice.executeShellCommand( + "pm enable --user " + userId + " " + cn.flattenToString()); + } catch (IOException e) { + fail(e.toString()); + } } } } @@ -300,7 +305,7 @@ public final class LauncherInstrumentation { public boolean isTwoPanels() { return getTestInfo(TestProtocol.REQUEST_IS_TWO_PANELS) - .getBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD); + .getBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD); } private void setForcePauseTimeout(long timeout) { @@ -763,9 +768,6 @@ public final class LauncherInstrumentation { try (LauncherInstrumentation.Closable c1 = addContextLayer( "Swiped up from context menu to home")) { waitUntilLauncherObjectGone(CONTEXT_MENU_RES_ID); - // Swiping up can temporarily bring Nexus Launcher if the current - // Launcher is a Launcher3 one. Wait for the current launcher to reappear. - SystemClock.sleep(5000); // b/187080582 waitForLauncherObject(getAnyObjectSelector()); } }