Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a09d1a73 authored by Automerger Merge Worker's avatar Automerger Merge Worker
Browse files

Merge "Fix policy for platform compat UI" am: 3208f994 am: e184ff60 am: b85d1971

Change-Id: I1b8f54ab614ec7ad3649d24e6fff661038817557
parents fb5bf791 b85d1971
Loading
Loading
Loading
Loading
+38 −15
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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;
@@ -64,6 +71,8 @@ public class PlatformCompatDashboard extends DashboardFragment {

    private CompatibilityChangeInfo[] mChanges;

    private AndroidBuildClassifier mAndroidBuildClassifier = new AndroidBuildClassifier();

    @VisibleForTesting
    String mSelectedApp;

@@ -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();
@@ -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);
        }
    }
@@ -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()));
@@ -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);
        }
    }

    /**
@@ -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 "
@@ -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);
    }

+46 −3
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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;
@@ -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;
@@ -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
@@ -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");
    }
@@ -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
@@ -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