From ef85d880a54065455ebae49e5752415ffcd20f3d Mon Sep 17 00:00:00 2001 From: Jaekyun Seok Date: Sat, 29 Apr 2017 09:36:46 +0900 Subject: [PATCH] Do not show static overlays as a theme Static overlays aren't changeable by a user. So we shouldn't list them as a theme. This CL fixed b/36812704 as well to run unit tests. Test: building succeeded and tested on sailfish. make RunSettingsRoboTests adb shell am instrument -w -e class \ com.android.settings.display.ThemePreferenceControllerTest \ com.android.settings.tests.unit/android.support.test.runner.AndroidJUnitRunner Bug: 37480890 Bug: 36812704 Change-Id: I8c13b6956083095dceaab3da6642bef1647d6a30 --- .../display/ThemePreferenceController.java | 22 +++++-- .../ThemePreferenceControllerTest.java | 64 +++++++++++++++---- 2 files changed, 71 insertions(+), 15 deletions(-) diff --git a/src/com/android/settings/display/ThemePreferenceController.java b/src/com/android/settings/display/ThemePreferenceController.java index a8d47d62542..b53599378d2 100644 --- a/src/com/android/settings/display/ThemePreferenceController.java +++ b/src/com/android/settings/display/ThemePreferenceController.java @@ -18,6 +18,7 @@ import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION import android.content.Context; import android.content.om.IOverlayManager; import android.content.om.OverlayInfo; +import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.os.RemoteException; @@ -35,6 +36,7 @@ import com.android.settings.overlay.FeatureFactory; import libcore.util.Objects; +import java.util.ArrayList; import java.util.List; public class ThemePreferenceController extends PreferenceController implements @@ -109,12 +111,22 @@ public class ThemePreferenceController extends PreferenceController implements return true; } + private boolean isChangeableOverlay(String packageName) { + try { + PackageInfo pi = mPackageManager.getPackageInfo(packageName, 0); + return pi != null && !pi.isStaticOverlay; + } catch (PackageManager.NameNotFoundException e) { + return false; + } + } + private String getTheme() { try { List infos = mOverlayService.getOverlayInfosForTarget("android", UserHandle.myUserId()); for (int i = 0, size = infos.size(); i < size; i++) { - if (infos.get(i).isEnabled()) { + if (infos.get(i).isEnabled() && + isChangeableOverlay(infos.get(i).packageName)) { return infos.get(i).packageName; } } @@ -141,11 +153,13 @@ public class ThemePreferenceController extends PreferenceController implements try { List infos = mOverlayService.getOverlayInfosForTarget("android", UserHandle.myUserId()); - String[] pkgs = new String[infos.size()]; + List pkgs = new ArrayList(infos.size()); for (int i = 0, size = infos.size(); i < size; i++) { - pkgs[i] = infos.get(i).packageName; + if (isChangeableOverlay(infos.get(i).packageName)) { + pkgs.add(infos.get(i).packageName); + } } - return pkgs; + return pkgs.toArray(new String[pkgs.size()]); } catch (RemoteException e) { } return new String[0]; diff --git a/tests/unit/src/com/android/settings/display/ThemePreferenceControllerTest.java b/tests/unit/src/com/android/settings/display/ThemePreferenceControllerTest.java index 3137d59da65..69c8c54c672 100644 --- a/tests/unit/src/com/android/settings/display/ThemePreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/display/ThemePreferenceControllerTest.java @@ -16,11 +16,10 @@ package com.android.settings.display; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -29,6 +28,7 @@ import static org.mockito.Mockito.when; import android.content.ContextWrapper; import android.content.om.OverlayInfo; import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; @@ -58,7 +58,7 @@ public class ThemePreferenceControllerTest { public void setup() { mMockOverlayManager = mock(OverlayManager.class); mMockPackageManager = mock(PackageManager.class); - mContext = new ContextWrapper(InstrumentationRegistry.getContext()) { + mContext = new ContextWrapper(InstrumentationRegistry.getTargetContext()) { @Override public PackageManager getPackageManager() { return mMockPackageManager; @@ -82,6 +82,8 @@ public class ThemePreferenceControllerTest { } return info; }); + when(mMockPackageManager.getPackageInfo(anyString(), anyInt())).thenReturn( + new PackageInfo()); when(mMockOverlayManager.getOverlayInfosForTarget(any(), anyInt())).thenReturn( list(info1, info2)); ListPreference pref = mock(ListPreference.class); @@ -91,31 +93,71 @@ public class ThemePreferenceControllerTest { CharSequence[] entries = arg.getValue(); - assertEquals(2, entries.length); - assertEquals("Theme1", entries[0]); - assertEquals("Theme2", entries[1]); + assertThat(entries).asList().containsExactly("Theme1", "Theme2"); verify(pref).setEntryValues(arg.capture()); CharSequence[] entryValues = arg.getValue(); - assertEquals("com.android.Theme1", entryValues[0]); - assertEquals("com.android.Theme2", entryValues[1]); + assertThat(entryValues).asList().containsExactly( + "com.android.Theme1", "com.android.Theme2"); verify(pref).setValue(eq("com.android.Theme1")); } + @Test + public void testUpdateState_withStaticOverlay() throws Exception { + OverlayInfo info1 = new OverlayInfo("com.android.Theme1", "android", + "", OverlayInfo.STATE_ENABLED, 0); + OverlayInfo info2 = new OverlayInfo("com.android.Theme2", "android", + "", OverlayInfo.STATE_ENABLED, 0); + when(mMockPackageManager.getApplicationInfo(any(), anyInt())).thenAnswer(inv -> { + ApplicationInfo info = mock(ApplicationInfo.class); + if ("com.android.Theme1".equals(inv.getArguments()[0])) { + when(info.loadLabel(any())).thenReturn("Theme1"); + } else { + when(info.loadLabel(any())).thenReturn("Theme2"); + } + return info; + }); + PackageInfo pi = new PackageInfo(); + pi.isStaticOverlay = true; + when(mMockPackageManager.getPackageInfo(eq("com.android.Theme1"), anyInt())).thenReturn(pi); + when(mMockPackageManager.getPackageInfo(eq("com.android.Theme2"), anyInt())).thenReturn( + new PackageInfo()); + when(mMockOverlayManager.getOverlayInfosForTarget(any(), anyInt())).thenReturn( + list(info1, info2)); + ListPreference pref = mock(ListPreference.class); + mPreferenceController.updateState(pref); + ArgumentCaptor arg = ArgumentCaptor.forClass(String[].class); + verify(pref).setEntries(arg.capture()); + + + CharSequence[] entries = arg.getValue(); + assertThat(entries).asList().containsExactly("Theme2"); + + verify(pref).setEntryValues(arg.capture()); + CharSequence[] entryValues = arg.getValue(); + assertThat(entryValues).asList().containsExactly("com.android.Theme2"); + + verify(pref).setValue(eq("com.android.Theme2")); + } + @Test public void testAvailable_false() throws Exception { + when(mMockPackageManager.getPackageInfo(anyString(), anyInt())).thenReturn( + new PackageInfo()); when(mMockOverlayManager.getOverlayInfosForTarget(any(), anyInt())) .thenReturn(list(new OverlayInfo("", "", "", 0, 0))); - assertFalse(mPreferenceController.isAvailable()); + assertThat(mPreferenceController.isAvailable()).isFalse(); } @Test public void testAvailable_true() throws Exception { + when(mMockPackageManager.getPackageInfo(anyString(), anyInt())).thenReturn( + new PackageInfo()); when(mMockOverlayManager.getOverlayInfosForTarget(any(), anyInt())) .thenReturn(list(new OverlayInfo("", "", "", 0, 0), new OverlayInfo("", "", "", 0, 0))); - assertTrue(mPreferenceController.isAvailable()); + assertThat(mPreferenceController.isAvailable()).isTrue(); } private ArrayList list(OverlayInfo... infos) {