From 96e60d7b5e6d638ca5f8ab7bfd1b31a09d639579 Mon Sep 17 00:00:00 2001 From: Amin Shaikh Date: Wed, 24 Apr 2019 13:47:57 -0400 Subject: [PATCH] Improve theme application transition. - Remove duplicate app info changed / activity relaunch messages caused by applying several overlay packages sequentially; this eliminated the double launcher activity restart - Asynchronously enable each overlay from SystemUI; this increases the speed of enabling overlays, thus decreasing the effect of the frozen activity transition Fixes: 130151718 Test: make; change themes many times Change-Id: Idcf04edc88cb9391b9920b9e1f9f873a5b62b311 --- core/java/android/app/ActivityThread.java | 2 ++ .../theme/ThemeOverlayController.java | 2 ++ .../systemui/theme/ThemeOverlayManager.java | 26 ++++++++++++------- .../theme/ThemeOverlayManagerTest.java | 17 +++--------- 4 files changed, 23 insertions(+), 24 deletions(-) diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 6552a779f3407..583103c19ab96 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -1064,6 +1064,7 @@ public final class ActivityThread extends ClientTransactionHandler { } public void scheduleApplicationInfoChanged(ApplicationInfo ai) { + mH.removeMessages(H.APPLICATION_INFO_CHANGED); sendMessage(H.APPLICATION_INFO_CHANGED, ai); } @@ -5126,6 +5127,7 @@ public final class ActivityThread extends ClientTransactionHandler { * handling current transaction item before relaunching the activity. */ void scheduleRelaunchActivity(IBinder token) { + mH.removeMessages(H.RELAUNCH_ACTIVITY, token); sendMessage(H.RELAUNCH_ACTIVITY, token); } diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java index f318f8f94e50a..8380b19f70090 100644 --- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java +++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java @@ -24,6 +24,7 @@ import android.content.om.OverlayManager; import android.content.pm.UserInfo; import android.database.ContentObserver; import android.net.Uri; +import android.os.AsyncTask; import android.os.Handler; import android.os.UserHandle; import android.os.UserManager; @@ -66,6 +67,7 @@ public class ThemeOverlayController extends SystemUI { mUserManager = mContext.getSystemService(UserManager.class); mThemeManager = new ThemeOverlayManager( mContext.getSystemService(OverlayManager.class), + AsyncTask.THREAD_POOL_EXECUTOR, mContext.getString(R.string.launcher_overlayable_package)); final Handler bgHandler = Dependency.get(Dependency.BG_HANDLER); final IntentFilter filter = new IntentFilter(); diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayManager.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayManager.java index 51ae70b84286e..27e3b2b438bf6 100644 --- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayManager.java +++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayManager.java @@ -31,6 +31,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.Executor; import java.util.stream.Collectors; class ThemeOverlayManager { @@ -91,10 +92,13 @@ class ThemeOverlayManager { /* Target package for each overlay category. */ private final Map mCategoryToTargetPackage = new ArrayMap<>(); private final OverlayManager mOverlayManager; + private final Executor mExecutor; private final String mLauncherPackage; - ThemeOverlayManager(OverlayManager overlayManager, String launcherPackage) { + ThemeOverlayManager(OverlayManager overlayManager, Executor executor, + String launcherPackage) { mOverlayManager = overlayManager; + mExecutor = executor; mLauncherPackage = launcherPackage; mTargetPackageToCategories.put(ANDROID_PACKAGE, Sets.newHashSet( OVERLAY_CATEGORY_COLOR, OVERLAY_CATEGORY_FONT, @@ -149,19 +153,21 @@ class ThemeOverlayManager { private void setEnabled( String packageName, String category, Set handles, boolean enabled) { for (UserHandle userHandle : handles) { - setEnabled(packageName, userHandle, enabled); + setEnabledAsync(packageName, userHandle, enabled); } if (!handles.contains(UserHandle.SYSTEM) && SYSTEM_USER_CATEGORIES.contains(category)) { - setEnabled(packageName, UserHandle.SYSTEM, enabled); + setEnabledAsync(packageName, UserHandle.SYSTEM, enabled); } } - private void setEnabled(String pkg, UserHandle userHandle, boolean enabled) { - if (DEBUG) Log.d(TAG, String.format("setEnabled: %s %s %b", pkg, userHandle, enabled)); - if (enabled) { - mOverlayManager.setEnabledExclusiveInCategory(pkg, userHandle); - } else { - mOverlayManager.setEnabled(pkg, false, userHandle); - } + private void setEnabledAsync(String pkg, UserHandle userHandle, boolean enabled) { + mExecutor.execute(() -> { + if (DEBUG) Log.d(TAG, String.format("setEnabled: %s %s %b", pkg, userHandle, enabled)); + if (enabled) { + mOverlayManager.setEnabledExclusiveInCategory(pkg, userHandle); + } else { + mOverlayManager.setEnabled(pkg, false, userHandle); + } + }); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayManagerTest.java index a904704e3ea64..4659afc8e1c24 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayManagerTest.java @@ -47,13 +47,12 @@ import com.android.systemui.SysuiTestCase; import com.google.android.collect.Maps; import com.google.common.collect.Lists; import com.google.common.collect.Sets; +import com.google.common.util.concurrent.MoreExecutors; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.InOrder; import org.mockito.Mock; -import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import java.util.HashMap; @@ -87,7 +86,8 @@ public class ThemeOverlayManagerTest extends SysuiTestCase { @Before public void setup() throws Exception { MockitoAnnotations.initMocks(this); - mManager = new ThemeOverlayManager(mOverlayManager, LAUNCHER_PACKAGE); + mManager = new ThemeOverlayManager(mOverlayManager, MoreExecutors.directExecutor(), + LAUNCHER_PACKAGE); when(mOverlayManager.getOverlayInfosForTarget(ANDROID_PACKAGE, UserHandle.SYSTEM)) .thenReturn(Lists.newArrayList( createOverlayInfo(TEST_DISABLED_PREFIX + OVERLAY_CATEGORY_COLOR, @@ -135,17 +135,6 @@ public class ThemeOverlayManagerTest extends SysuiTestCase { } } - @Test - public void allCategoriesSpecified_enabledInOrder() { - mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, TEST_USER_HANDLES); - - InOrder inOrder = Mockito.inOrder(mOverlayManager); - for (String category : THEME_CATEGORIES) { - inOrder.verify(mOverlayManager) - .setEnabledExclusiveInCategory(ALL_CATEGORIES_MAP.get(category), TEST_USER); - } - } - @Test public void allCategoriesSpecified_sysuiCategoriesAlsoAppliedToSysuiUser() { mManager.applyCurrentUserOverlays(ALL_CATEGORIES_MAP, TEST_USER_HANDLES);