Loading src/com/android/settings/development/compat/PlatformCompatDashboard.java +38 −15 Original line number Diff line number Diff line Loading @@ -16,7 +16,9 @@ package com.android.settings.development.compat; import static com.android.settings.development.AppPicker.EXTRA_DEBUGGABLE; import static com.android.settings.development.DevelopmentOptionsActivityRequestCodes.REQUEST_COMPAT_CHANGE_APP; import static com.android.internal.compat.OverrideAllowedState.ALLOWED; import android.app.Activity; import android.app.settings.SettingsEnums; Loading @@ -25,7 +27,9 @@ import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Bundle; import android.os.RemoteException; import android.os.ServiceManager; Loading @@ -37,9 +41,12 @@ import androidx.preference.Preference.OnPreferenceChangeListener; import androidx.preference.PreferenceCategory; import androidx.preference.SwitchPreference; import com.android.internal.compat.AndroidBuildClassifier; import com.android.internal.compat.CompatibilityChangeConfig; import com.android.internal.compat.CompatibilityChangeInfo; import com.android.internal.compat.IPlatformCompat; import com.android.internal.compat.IOverrideValidator; import com.android.internal.compat.OverrideAllowedState; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.development.AppPicker; Loading @@ -64,6 +71,8 @@ public class PlatformCompatDashboard extends DashboardFragment { private CompatibilityChangeInfo[] mChanges; private AndroidBuildClassifier mAndroidBuildClassifier = new AndroidBuildClassifier(); @VisibleForTesting String mSelectedApp; Loading Loading @@ -117,17 +126,21 @@ public class PlatformCompatDashboard extends DashboardFragment { if (requestCode == REQUEST_COMPAT_CHANGE_APP) { if (resultCode == Activity.RESULT_OK) { mSelectedApp = data.getAction(); addPreferences(); try { final ApplicationInfo applicationInfo = getApplicationInfo(); addPreferences(applicationInfo); } catch (PackageManager.NameNotFoundException e) { startAppPicker(); } } return; } super.onActivityResult(requestCode, resultCode, data); } private void addPreferences() { private void addPreferences(ApplicationInfo applicationInfo) { getPreferenceScreen().removeAll(); getPreferenceScreen().addPreference( createAppPreference(getApplicationInfo().loadIcon(getPackageManager()))); getPreferenceScreen().addPreference(createAppPreference(applicationInfo)); // Differentiate compatibility changes into default enabled, default disabled and enabled // after target sdk. final CompatibilityChangeConfig configMappings = getAppChangeMappings(); Loading Loading @@ -164,7 +177,7 @@ public class PlatformCompatDashboard extends DashboardFragment { try { final ApplicationInfo applicationInfo = getApplicationInfo(); return getPlatformCompat().getAppConfig(applicationInfo); } catch (RemoteException e) { } catch (RemoteException | PackageManager.NameNotFoundException e) { throw new RuntimeException("Could not get app config!", e); } } Loading @@ -183,7 +196,15 @@ public class PlatformCompatDashboard extends DashboardFragment { change.getName() != null ? change.getName() : "Change_" + change.getId(); item.setSummary(changeName); item.setKey(changeName); item.setEnabled(true); boolean shouldEnable = true; try { shouldEnable = getPlatformCompat().getOverrideValidator() .getOverrideAllowedState(change.getId(), mSelectedApp) .state == ALLOWED; } catch (RemoteException e) { throw new RuntimeException("Could not check if change can be overridden for app.", e); } item.setEnabled(shouldEnable); item.setChecked(currentValue); item.setOnPreferenceChangeListener( new CompatChangePreferenceChangeListener(change.getId())); Loading @@ -195,12 +216,8 @@ public class PlatformCompatDashboard extends DashboardFragment { * * @return an {@link ApplicationInfo} instance. */ ApplicationInfo getApplicationInfo() { try { ApplicationInfo getApplicationInfo() throws PackageManager.NameNotFoundException { return getPackageManager().getApplicationInfo(mSelectedApp, 0); } catch (PackageManager.NameNotFoundException e) { throw new RuntimeException("Could not get ApplicationInfo for selected app!", e); } } /** Loading @@ -209,9 +226,10 @@ public class PlatformCompatDashboard extends DashboardFragment { * <p>The {@link Preference} contains the icon, package name and target SDK for the selected * app. Selecting this preference will also re-trigger the app selection dialog.</p> */ Preference createAppPreference(Drawable icon) { final ApplicationInfo applicationInfo = getApplicationInfo(); final Preference appPreference = new Preference(getPreferenceScreen().getContext()); Preference createAppPreference(ApplicationInfo applicationInfo) { final Context context = getPreferenceScreen().getContext(); final Drawable icon = applicationInfo.loadIcon(context.getPackageManager()); final Preference appPreference = new Preference(context); appPreference.setIcon(icon); appPreference.setSummary(mSelectedApp + " SDK " Loading Loading @@ -246,6 +264,11 @@ public class PlatformCompatDashboard extends DashboardFragment { private void startAppPicker() { final Intent intent = new Intent(getContext(), AppPicker.class); // If build is neither userdebug nor eng, only include debuggable apps final boolean debuggableBuild = mAndroidBuildClassifier.isDebuggableBuild(); if (!debuggableBuild) { intent.putExtra(AppPicker.EXTRA_DEBUGGABLE, true /* value */); } startActivityForResult(intent, REQUEST_COMPAT_CHANGE_APP); } Loading tests/robotests/src/com/android/settings/development/compat/PlatformCompatDashboardTest.java +46 −3 Original line number Diff line number Diff line Loading @@ -16,16 +16,23 @@ package com.android.settings.development.compat; import static com.android.internal.compat.OverrideAllowedState.ALLOWED; import static com.android.internal.compat.OverrideAllowedState.DISABLED_NOT_DEBUGGABLE; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import android.compat.Compatibility.ChangeConfig; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.graphics.drawable.Drawable; import android.os.RemoteException; Loading @@ -38,7 +45,9 @@ import androidx.preference.SwitchPreference; import com.android.internal.compat.CompatibilityChangeConfig; import com.android.internal.compat.CompatibilityChangeInfo; import com.android.internal.compat.IOverrideValidator; import com.android.internal.compat.IPlatformCompat; import com.android.internal.compat.OverrideAllowedState; import com.android.settings.R; import org.junit.Before; Loading Loading @@ -66,6 +75,10 @@ public class PlatformCompatDashboardTest { private ApplicationInfo mApplicationInfo; @Mock private PreferenceManager mPreferenceManager; @Mock private IOverrideValidator mOverrideValidator; @Mock private PackageManager mPackageManager; private Context mContext; private CompatibilityChangeInfo[] mChanges; Loading @@ -81,7 +94,11 @@ public class PlatformCompatDashboardTest { mChanges[3] = new CompatibilityChangeInfo(4L, "Enabled_After_SDK_1_2", 1, false, ""); mChanges[4] = new CompatibilityChangeInfo(5L, "Enabled_After_SDK_2", 2, false, ""); when(mPlatformCompat.listAllChanges()).thenReturn(mChanges); mContext = RuntimeEnvironment.application; when(mPlatformCompat.getOverrideValidator()).thenReturn(mOverrideValidator); // By default, allow any change when(mOverrideValidator.getOverrideAllowedState(anyLong(),anyString())) .thenReturn(new OverrideAllowedState(ALLOWED, -1, -1)); mContext = spy(RuntimeEnvironment.application); mPreferenceManager = new PreferenceManager(mContext); mPreferenceScreen = mPreferenceManager.createPreferenceScreen(mContext); mApplicationInfo.packageName = APP_NAME; Loading @@ -91,6 +108,7 @@ public class PlatformCompatDashboardTest { doReturn(mPlatformCompat).when(mDashboard).getPlatformCompat(); doReturn(mPreferenceScreen).when(mDashboard).getPreferenceScreen(); doReturn(mPreferenceManager).when(mDashboard).getPreferenceManager(); doReturn(mPackageManager).when(mContext).getPackageManager(); } @Test Loading @@ -107,8 +125,10 @@ public class PlatformCompatDashboardTest { @Test public void createAppPreference_targetSdkEquals1_summaryReturnsAppNameAndTargetSdk() { mApplicationInfo.targetSdkVersion = 1; Drawable icon = mock(Drawable.class); when(mApplicationInfo.loadIcon(any(PackageManager.class))).thenReturn(icon); Preference appPreference = mDashboard.createAppPreference(any(Drawable.class)); Preference appPreference = mDashboard.createAppPreference(mApplicationInfo); assertThat(appPreference.getSummary()).isEqualTo(APP_NAME + " SDK 1"); } Loading @@ -128,6 +148,7 @@ public class PlatformCompatDashboardTest { assertThat(enabledPreference.getSummary()).isEqualTo(mChanges[0].getName()); assertThat(enabledPreference instanceof SwitchPreference).isTrue(); assertThat(enabledSwitchPreference.isChecked()).isTrue(); assertThat(enabledSwitchPreference.isEnabled()).isTrue(); } @Test Loading @@ -143,6 +164,28 @@ public class PlatformCompatDashboardTest { assertThat(disabledPreference.getSummary()).isEqualTo(mChanges[1].getName()); SwitchPreference disabledSwitchPreference = (SwitchPreference) disabledPreference; assertThat(disabledSwitchPreference.isChecked()).isFalse(); assertThat(disabledSwitchPreference.isEnabled()).isTrue(); } @Test public void createPreferenceForChange_cannotOverride_createDisabledEntry() throws RemoteException { CompatibilityChangeInfo enabledChange = mChanges[0]; CompatibilityChangeConfig config = new CompatibilityChangeConfig( new ChangeConfig(new HashSet<Long>(Arrays.asList(enabledChange.getId())), new HashSet<Long>())); when(mOverrideValidator.getOverrideAllowedState(anyLong(),anyString())) .thenReturn(new OverrideAllowedState(DISABLED_NOT_DEBUGGABLE, -1, -1)); Preference preference = mDashboard.createPreferenceForChange(mContext, enabledChange, config); SwitchPreference switchPreference = (SwitchPreference) preference; assertThat(preference.getSummary()).isEqualTo(mChanges[0].getName()); assertThat(preference instanceof SwitchPreference).isTrue(); assertThat(switchPreference.isChecked()).isTrue(); assertThat(switchPreference.isEnabled()).isFalse(); } @Test Loading Loading
src/com/android/settings/development/compat/PlatformCompatDashboard.java +38 −15 Original line number Diff line number Diff line Loading @@ -16,7 +16,9 @@ package com.android.settings.development.compat; import static com.android.settings.development.AppPicker.EXTRA_DEBUGGABLE; import static com.android.settings.development.DevelopmentOptionsActivityRequestCodes.REQUEST_COMPAT_CHANGE_APP; import static com.android.internal.compat.OverrideAllowedState.ALLOWED; import android.app.Activity; import android.app.settings.SettingsEnums; Loading @@ -25,7 +27,9 @@ import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Bundle; import android.os.RemoteException; import android.os.ServiceManager; Loading @@ -37,9 +41,12 @@ import androidx.preference.Preference.OnPreferenceChangeListener; import androidx.preference.PreferenceCategory; import androidx.preference.SwitchPreference; import com.android.internal.compat.AndroidBuildClassifier; import com.android.internal.compat.CompatibilityChangeConfig; import com.android.internal.compat.CompatibilityChangeInfo; import com.android.internal.compat.IPlatformCompat; import com.android.internal.compat.IOverrideValidator; import com.android.internal.compat.OverrideAllowedState; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.development.AppPicker; Loading @@ -64,6 +71,8 @@ public class PlatformCompatDashboard extends DashboardFragment { private CompatibilityChangeInfo[] mChanges; private AndroidBuildClassifier mAndroidBuildClassifier = new AndroidBuildClassifier(); @VisibleForTesting String mSelectedApp; Loading Loading @@ -117,17 +126,21 @@ public class PlatformCompatDashboard extends DashboardFragment { if (requestCode == REQUEST_COMPAT_CHANGE_APP) { if (resultCode == Activity.RESULT_OK) { mSelectedApp = data.getAction(); addPreferences(); try { final ApplicationInfo applicationInfo = getApplicationInfo(); addPreferences(applicationInfo); } catch (PackageManager.NameNotFoundException e) { startAppPicker(); } } return; } super.onActivityResult(requestCode, resultCode, data); } private void addPreferences() { private void addPreferences(ApplicationInfo applicationInfo) { getPreferenceScreen().removeAll(); getPreferenceScreen().addPreference( createAppPreference(getApplicationInfo().loadIcon(getPackageManager()))); getPreferenceScreen().addPreference(createAppPreference(applicationInfo)); // Differentiate compatibility changes into default enabled, default disabled and enabled // after target sdk. final CompatibilityChangeConfig configMappings = getAppChangeMappings(); Loading Loading @@ -164,7 +177,7 @@ public class PlatformCompatDashboard extends DashboardFragment { try { final ApplicationInfo applicationInfo = getApplicationInfo(); return getPlatformCompat().getAppConfig(applicationInfo); } catch (RemoteException e) { } catch (RemoteException | PackageManager.NameNotFoundException e) { throw new RuntimeException("Could not get app config!", e); } } Loading @@ -183,7 +196,15 @@ public class PlatformCompatDashboard extends DashboardFragment { change.getName() != null ? change.getName() : "Change_" + change.getId(); item.setSummary(changeName); item.setKey(changeName); item.setEnabled(true); boolean shouldEnable = true; try { shouldEnable = getPlatformCompat().getOverrideValidator() .getOverrideAllowedState(change.getId(), mSelectedApp) .state == ALLOWED; } catch (RemoteException e) { throw new RuntimeException("Could not check if change can be overridden for app.", e); } item.setEnabled(shouldEnable); item.setChecked(currentValue); item.setOnPreferenceChangeListener( new CompatChangePreferenceChangeListener(change.getId())); Loading @@ -195,12 +216,8 @@ public class PlatformCompatDashboard extends DashboardFragment { * * @return an {@link ApplicationInfo} instance. */ ApplicationInfo getApplicationInfo() { try { ApplicationInfo getApplicationInfo() throws PackageManager.NameNotFoundException { return getPackageManager().getApplicationInfo(mSelectedApp, 0); } catch (PackageManager.NameNotFoundException e) { throw new RuntimeException("Could not get ApplicationInfo for selected app!", e); } } /** Loading @@ -209,9 +226,10 @@ public class PlatformCompatDashboard extends DashboardFragment { * <p>The {@link Preference} contains the icon, package name and target SDK for the selected * app. Selecting this preference will also re-trigger the app selection dialog.</p> */ Preference createAppPreference(Drawable icon) { final ApplicationInfo applicationInfo = getApplicationInfo(); final Preference appPreference = new Preference(getPreferenceScreen().getContext()); Preference createAppPreference(ApplicationInfo applicationInfo) { final Context context = getPreferenceScreen().getContext(); final Drawable icon = applicationInfo.loadIcon(context.getPackageManager()); final Preference appPreference = new Preference(context); appPreference.setIcon(icon); appPreference.setSummary(mSelectedApp + " SDK " Loading Loading @@ -246,6 +264,11 @@ public class PlatformCompatDashboard extends DashboardFragment { private void startAppPicker() { final Intent intent = new Intent(getContext(), AppPicker.class); // If build is neither userdebug nor eng, only include debuggable apps final boolean debuggableBuild = mAndroidBuildClassifier.isDebuggableBuild(); if (!debuggableBuild) { intent.putExtra(AppPicker.EXTRA_DEBUGGABLE, true /* value */); } startActivityForResult(intent, REQUEST_COMPAT_CHANGE_APP); } Loading
tests/robotests/src/com/android/settings/development/compat/PlatformCompatDashboardTest.java +46 −3 Original line number Diff line number Diff line Loading @@ -16,16 +16,23 @@ package com.android.settings.development.compat; import static com.android.internal.compat.OverrideAllowedState.ALLOWED; import static com.android.internal.compat.OverrideAllowedState.DISABLED_NOT_DEBUGGABLE; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import android.compat.Compatibility.ChangeConfig; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.graphics.drawable.Drawable; import android.os.RemoteException; Loading @@ -38,7 +45,9 @@ import androidx.preference.SwitchPreference; import com.android.internal.compat.CompatibilityChangeConfig; import com.android.internal.compat.CompatibilityChangeInfo; import com.android.internal.compat.IOverrideValidator; import com.android.internal.compat.IPlatformCompat; import com.android.internal.compat.OverrideAllowedState; import com.android.settings.R; import org.junit.Before; Loading Loading @@ -66,6 +75,10 @@ public class PlatformCompatDashboardTest { private ApplicationInfo mApplicationInfo; @Mock private PreferenceManager mPreferenceManager; @Mock private IOverrideValidator mOverrideValidator; @Mock private PackageManager mPackageManager; private Context mContext; private CompatibilityChangeInfo[] mChanges; Loading @@ -81,7 +94,11 @@ public class PlatformCompatDashboardTest { mChanges[3] = new CompatibilityChangeInfo(4L, "Enabled_After_SDK_1_2", 1, false, ""); mChanges[4] = new CompatibilityChangeInfo(5L, "Enabled_After_SDK_2", 2, false, ""); when(mPlatformCompat.listAllChanges()).thenReturn(mChanges); mContext = RuntimeEnvironment.application; when(mPlatformCompat.getOverrideValidator()).thenReturn(mOverrideValidator); // By default, allow any change when(mOverrideValidator.getOverrideAllowedState(anyLong(),anyString())) .thenReturn(new OverrideAllowedState(ALLOWED, -1, -1)); mContext = spy(RuntimeEnvironment.application); mPreferenceManager = new PreferenceManager(mContext); mPreferenceScreen = mPreferenceManager.createPreferenceScreen(mContext); mApplicationInfo.packageName = APP_NAME; Loading @@ -91,6 +108,7 @@ public class PlatformCompatDashboardTest { doReturn(mPlatformCompat).when(mDashboard).getPlatformCompat(); doReturn(mPreferenceScreen).when(mDashboard).getPreferenceScreen(); doReturn(mPreferenceManager).when(mDashboard).getPreferenceManager(); doReturn(mPackageManager).when(mContext).getPackageManager(); } @Test Loading @@ -107,8 +125,10 @@ public class PlatformCompatDashboardTest { @Test public void createAppPreference_targetSdkEquals1_summaryReturnsAppNameAndTargetSdk() { mApplicationInfo.targetSdkVersion = 1; Drawable icon = mock(Drawable.class); when(mApplicationInfo.loadIcon(any(PackageManager.class))).thenReturn(icon); Preference appPreference = mDashboard.createAppPreference(any(Drawable.class)); Preference appPreference = mDashboard.createAppPreference(mApplicationInfo); assertThat(appPreference.getSummary()).isEqualTo(APP_NAME + " SDK 1"); } Loading @@ -128,6 +148,7 @@ public class PlatformCompatDashboardTest { assertThat(enabledPreference.getSummary()).isEqualTo(mChanges[0].getName()); assertThat(enabledPreference instanceof SwitchPreference).isTrue(); assertThat(enabledSwitchPreference.isChecked()).isTrue(); assertThat(enabledSwitchPreference.isEnabled()).isTrue(); } @Test Loading @@ -143,6 +164,28 @@ public class PlatformCompatDashboardTest { assertThat(disabledPreference.getSummary()).isEqualTo(mChanges[1].getName()); SwitchPreference disabledSwitchPreference = (SwitchPreference) disabledPreference; assertThat(disabledSwitchPreference.isChecked()).isFalse(); assertThat(disabledSwitchPreference.isEnabled()).isTrue(); } @Test public void createPreferenceForChange_cannotOverride_createDisabledEntry() throws RemoteException { CompatibilityChangeInfo enabledChange = mChanges[0]; CompatibilityChangeConfig config = new CompatibilityChangeConfig( new ChangeConfig(new HashSet<Long>(Arrays.asList(enabledChange.getId())), new HashSet<Long>())); when(mOverrideValidator.getOverrideAllowedState(anyLong(),anyString())) .thenReturn(new OverrideAllowedState(DISABLED_NOT_DEBUGGABLE, -1, -1)); Preference preference = mDashboard.createPreferenceForChange(mContext, enabledChange, config); SwitchPreference switchPreference = (SwitchPreference) preference; assertThat(preference.getSummary()).isEqualTo(mChanges[0].getName()); assertThat(preference instanceof SwitchPreference).isTrue(); assertThat(switchPreference.isChecked()).isTrue(); assertThat(switchPreference.isEnabled()).isFalse(); } @Test Loading