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

Commit 6e2db2c3 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "DO NOT MERGE: Cherry-pick misc fixes to AOSP"

parents 56cc4986 bc7b20b4
Loading
Loading
Loading
Loading
+29 −17
Original line number Diff line number Diff line
@@ -19,18 +19,21 @@ package com.android.settings.development;
import static android.os.UserHandle.USER_SYSTEM;

import android.content.Context;
import android.content.om.IOverlayManager;
import android.content.om.OverlayInfo;
import android.content.pm.PackageManager;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.text.TextUtils;
import android.view.DisplayCutout;

import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.ListPreference;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import android.text.TextUtils;
import android.view.DisplayCutout;

import com.android.settings.R;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.wrapper.OverlayManagerWrapper;
import com.android.settings.wrapper.OverlayManagerWrapper.OverlayInfo;
import com.android.settingslib.development.DeveloperOptionsPreferenceController;

import java.util.List;
@@ -41,7 +44,7 @@ public class EmulateDisplayCutoutPreferenceController extends

    private static final String KEY = "display_cutout_emulation";

    private final OverlayManagerWrapper mOverlayManager;
    private final IOverlayManager mOverlayManager;
    private final boolean mAvailable;

    private ListPreference mPreference;
@@ -49,7 +52,7 @@ public class EmulateDisplayCutoutPreferenceController extends

    @VisibleForTesting
    EmulateDisplayCutoutPreferenceController(Context context, PackageManager packageManager,
            OverlayManagerWrapper overlayManager) {
            IOverlayManager overlayManager) {
        super(context);
        mOverlayManager = overlayManager;
        mPackageManager = packageManager;
@@ -57,7 +60,8 @@ public class EmulateDisplayCutoutPreferenceController extends
    }

    public EmulateDisplayCutoutPreferenceController(Context context) {
        this(context, context.getPackageManager(), new OverlayManagerWrapper());
        this(context, context.getPackageManager(), IOverlayManager.Stub
                .asInterface(ServiceManager.getService(Context.OVERLAY_SERVICE)));
    }

    @Override
@@ -102,11 +106,15 @@ public class EmulateDisplayCutoutPreferenceController extends
        }

        final boolean result;
        try {
            if (TextUtils.isEmpty(packageName)) {
                result = mOverlayManager.setEnabled(currentPackageName, false, USER_SYSTEM);
            } else {
                result = mOverlayManager.setEnabledExclusiveInCategory(packageName, USER_SYSTEM);
            }
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
        updateState(mPreference);
        return result;
    }
@@ -145,14 +153,18 @@ public class EmulateDisplayCutoutPreferenceController extends
    }

    private OverlayInfo[] getOverlayInfos() {
        @SuppressWarnings("unchecked") List<OverlayInfo> overlayInfos =
                mOverlayManager.getOverlayInfosForTarget("android", USER_SYSTEM);
        List<OverlayInfo> overlayInfos;
        try {
            overlayInfos = mOverlayManager.getOverlayInfosForTarget("android", USER_SYSTEM);
            for (int i = overlayInfos.size() - 1; i >= 0; i--) {
                if (!DisplayCutout.EMULATION_OVERLAY_CATEGORY.equals(
                        overlayInfos.get(i).category)) {
                    overlayInfos.remove(i);
                }
            }
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
        return overlayInfos.toArray(new OverlayInfo[overlayInfos.size()]);
    }

+40 −31
Original line number Diff line number Diff line
@@ -13,7 +13,11 @@
 */
package com.android.settings.display;

import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_THEME;

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;
@@ -23,13 +27,12 @@ import android.os.UserHandle;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.ListPreference;
import android.support.v7.preference.Preference;

import android.text.TextUtils;

import com.android.settings.R;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.wrapper.OverlayManagerWrapper;
import com.android.settings.wrapper.OverlayManagerWrapper.OverlayInfo;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;

@@ -37,24 +40,22 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_THEME;

public class ThemePreferenceController extends AbstractPreferenceController implements
        PreferenceControllerMixin, Preference.OnPreferenceChangeListener {

    private static final String KEY_THEME = "theme";

    private final MetricsFeatureProvider mMetricsFeatureProvider;
    private final OverlayManagerWrapper mOverlayService;
    private final IOverlayManager mOverlayService;
    private final PackageManager mPackageManager;

    public ThemePreferenceController(Context context) {
        this(context, ServiceManager.getService(Context.OVERLAY_SERVICE) != null
                ? new OverlayManagerWrapper() : null);
        this(context, IOverlayManager.Stub
                .asInterface(ServiceManager.getService(Context.OVERLAY_SERVICE)));
    }

    @VisibleForTesting
    ThemePreferenceController(Context context, OverlayManagerWrapper overlayManager) {
    ThemePreferenceController(Context context, IOverlayManager overlayManager) {
        super(context);
        mOverlayService = overlayManager;
        mPackageManager = context.getPackageManager();
@@ -77,7 +78,7 @@ public class ThemePreferenceController extends AbstractPreferenceController impl
    @Override
    public void updateState(Preference preference) {
        ListPreference pref = (ListPreference) preference;
        String[] pkgs = getAvailableThemes();
        String[] pkgs = getAvailableThemes(false /* currentThemeOnly */);
        CharSequence[] labels = new CharSequence[pkgs.length];
        for (int i = 0; i < pkgs.length; i++) {
            try {
@@ -109,11 +110,15 @@ public class ThemePreferenceController extends AbstractPreferenceController impl

    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
        String current = getTheme();
        String current = getCurrentTheme();
        if (Objects.equals(newValue, current)) {
            return true;
        }
        try {
            mOverlayService.setEnabledExclusiveInCategory((String) newValue, UserHandle.myUserId());
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
        return true;
    }

@@ -129,40 +134,44 @@ public class ThemePreferenceController extends AbstractPreferenceController impl
        }
    }

    private String getTheme() {
        List<OverlayInfo> infos = mOverlayService.getOverlayInfosForTarget("android",
                UserHandle.myUserId());
        for (int i = 0, size = infos.size(); i < size; i++) {
            if (infos.get(i).isEnabled() && isTheme(infos.get(i))) {
                return infos.get(i).packageName;
            }
        }
        return null;
    }

    @Override
    public boolean isAvailable() {
        if (mOverlayService == null) return false;
        String[] themes = getAvailableThemes();
        String[] themes = getAvailableThemes(false /* currentThemeOnly */);
        return themes != null && themes.length > 1;
    }


    @VisibleForTesting
    String getCurrentTheme() {
        return getTheme();
        String[] themePackages = getAvailableThemes(true /* currentThemeOnly */);
        return themePackages.length < 1 ? null : themePackages[0];
    }

    @VisibleForTesting
    String[] getAvailableThemes() {
        List<OverlayInfo> infos = mOverlayService.getOverlayInfosForTarget("android",
                UserHandle.myUserId());
        List<String> pkgs = new ArrayList<>(infos.size());
    String[] getAvailableThemes(boolean currentThemeOnly) {
        List<OverlayInfo> infos;
        List<String> pkgs;
        try {
            infos = mOverlayService.getOverlayInfosForTarget("android", UserHandle.myUserId());
            pkgs = new ArrayList<>(infos.size());
            for (int i = 0, size = infos.size(); i < size; i++) {
                if (isTheme(infos.get(i))) {
                    if (infos.get(i).isEnabled() && currentThemeOnly) {
                        return new String[] {infos.get(i).packageName};
                    } else {
                        pkgs.add(infos.get(i).packageName);
                    }
                }
            }
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }

        // Current enabled theme is not found.
        if (currentThemeOnly) {
            return new String[0];
        }
        return pkgs.toArray(new String[pkgs.size()]);
    }
}
+0 −102
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.settings.wrapper;

import android.content.Context;
import android.content.om.IOverlayManager;
import android.content.om.OverlayInfo;
import android.os.RemoteException;
import android.os.ServiceManager;

import java.util.ArrayList;
import java.util.List;

public class OverlayManagerWrapper {

    private final IOverlayManager mOverlayManager;

    public OverlayManagerWrapper(IOverlayManager overlayManager) {
        mOverlayManager = overlayManager;
    }

    public OverlayManagerWrapper() {
        this(IOverlayManager.Stub.asInterface(ServiceManager.getService(Context.OVERLAY_SERVICE)));
    }

    public List<OverlayInfo> getOverlayInfosForTarget(String overlay, int userId) {
        if (mOverlayManager == null) {
            return new ArrayList<>();
        }
        try {
            List<android.content.om.OverlayInfo> infos
                    = mOverlayManager.getOverlayInfosForTarget(overlay, userId);
            ArrayList<OverlayInfo> result = new ArrayList<>(infos.size());
            for (int i = 0; i < infos.size(); i++) {
                result.add(new OverlayInfo(infos.get(i)));
            }
            return result;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    public boolean setEnabled(String overlay, boolean enabled, int userId) {
        if (mOverlayManager == null) {
            return false;
        }
        try {
            return mOverlayManager.setEnabled(overlay, enabled, userId);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    public boolean setEnabledExclusiveInCategory(String overlay, int userId) {
        if (mOverlayManager == null) {
            return false;
        }
        try {
            return mOverlayManager.setEnabledExclusiveInCategory(overlay, userId);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    public static class OverlayInfo {

        public static final String CATEGORY_THEME = android.content.om.OverlayInfo.CATEGORY_THEME;
        public final String packageName;
        public final String category;
        private final boolean mEnabled;

        public OverlayInfo(String packageName, String category, boolean enabled) {
            this.packageName = packageName;
            this.category = category;
            mEnabled = enabled;
        }

        public OverlayInfo(android.content.om.OverlayInfo info) {
            mEnabled = info.isEnabled();
            category = info.category;
            packageName = info.packageName;
        }

        public boolean isEnabled() {
            return mEnabled;
        }
    }
}
+22 −6
Original line number Diff line number Diff line
@@ -26,14 +26,15 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.content.Context;
import android.content.om.IOverlayManager;
import android.content.om.OverlayInfo;
import android.content.pm.PackageManager;
import android.support.v7.preference.ListPreference;
import android.support.v7.preference.PreferenceScreen;
import android.os.RemoteException;
import android.view.DisplayCutout;

import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.wrapper.OverlayManagerWrapper;
import com.android.settings.wrapper.OverlayManagerWrapper.OverlayInfo;

import org.junit.Before;
import org.junit.Test;
@@ -41,6 +42,7 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.ArrayList;
import java.util.Arrays;

@RunWith(SettingsRobolectricTestRunner.class)
@@ -54,7 +56,7 @@ public class EmulateDisplayCutoutPreferenceControllerTest {
    @Mock
    private Context mContext;
    @Mock
    private OverlayManagerWrapper mOverlayManager;
    private IOverlayManager mOverlayManager;
    @Mock
    private PackageManager mPackageManager;
    @Mock
@@ -64,6 +66,7 @@ public class EmulateDisplayCutoutPreferenceControllerTest {
    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        when(mContext.getSystemService(Context.OVERLAY_SERVICE)).thenReturn(mOverlayManager);
        mockCurrentOverlays();
        when(mPackageManager.getApplicationInfo(any(), anyInt()))
            .thenThrow(PackageManager.NameNotFoundException.class);
@@ -72,8 +75,12 @@ public class EmulateDisplayCutoutPreferenceControllerTest {
    }

    Object mockCurrentOverlays(OverlayInfo... overlays) {
        try {
            return when(mOverlayManager.getOverlayInfosForTarget(eq("android"), anyInt()))
                .thenReturn(Arrays.asList(overlays));
        } catch (RemoteException re) {
            return new ArrayList<OverlayInfo>();
        }
    }

    @Test
@@ -146,6 +153,15 @@ public class EmulateDisplayCutoutPreferenceControllerTest {
    }

    private static OverlayInfo createFakeOverlay(String pkg, boolean enabled) {
        return new OverlayInfo(pkg, DisplayCutout.EMULATION_OVERLAY_CATEGORY, enabled);
        final int state = (enabled) ? OverlayInfo.STATE_ENABLED : OverlayInfo.STATE_DISABLED;

        return new OverlayInfo(pkg /* packageName */,
                pkg + ".target" /* targetPackageName */,
                DisplayCutout.EMULATION_OVERLAY_CATEGORY /* category */,
                pkg + ".baseCodePath" /* baseCodePath */,
                state /* state */,
                0 /* userId */,
                0 /* priority */,
                true /* isStatic */);
    }
}
 No newline at end of file
+61 −7
Original line number Diff line number Diff line
@@ -16,26 +16,28 @@

package com.android.settings.display;

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.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.content.Context;
import android.content.om.IOverlayManager;
import android.content.om.OverlayInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.support.v7.preference.ListPreference;


import com.android.settings.R;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.wrapper.OverlayManagerWrapper;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -44,6 +46,8 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;

import java.util.Arrays;

@RunWith(SettingsRobolectricTestRunner.class)
public class ThemePreferenceControllerTest {

@@ -55,6 +59,8 @@ public class ThemePreferenceControllerTest {
    private ApplicationInfo mApplicationInfo;
    @Mock
    private ListPreference mPreference;
    @Mock
    private IOverlayManager mOverlayManager;

    private ThemePreferenceController mController;

@@ -67,8 +73,28 @@ public class ThemePreferenceControllerTest {
        when(mContext.getString(R.string.default_theme))
                .thenReturn(RuntimeEnvironment.application.getString(R.string.default_theme));

        mController =
            spy(new ThemePreferenceController(mContext, mock(OverlayManagerWrapper.class)));
        when(mContext.getSystemService(Context.OVERLAY_SERVICE)).thenReturn(mOverlayManager);
        mController = spy(new ThemePreferenceController(mContext, mOverlayManager));
    }

    @Test
    public void testAvailable_false() throws Exception {
        when(mPackageManager.getPackageInfo(anyString(), anyInt())).thenReturn(
                new PackageInfo());
        when(mOverlayManager.getOverlayInfosForTarget(any(), anyInt()))
                .thenReturn(Arrays.asList(new OverlayInfo("", "", "", "", 0, 0, 0, false)));
        assertThat(mController.isAvailable()).isFalse();
    }

    @Test
    public void testAvailable_true() throws Exception {
        when(mPackageManager.getPackageInfo(anyString(), anyInt())).thenReturn(
                new PackageInfo());
        when(mOverlayManager.getOverlayInfosForTarget(any(), anyInt()))
                .thenReturn(Arrays.asList(
                        new OverlayInfo("", "", OverlayInfo.CATEGORY_THEME, "", 0, 0, 0, true),
                        new OverlayInfo("", "", OverlayInfo.CATEGORY_THEME, "", 0, 0, 0, true)));
        assertThat(mController.isAvailable()).isTrue();
    }

    @Test
@@ -79,7 +105,7 @@ public class ThemePreferenceControllerTest {
        final String themeLabel2 = "Theme2";
        final String[] themes = {pkg1, pkg2};
        doReturn("pkg1.theme1").when(mController).getCurrentTheme();
        doReturn(themes).when(mController).getAvailableThemes();
        doReturn(themes).when(mController).getAvailableThemes(false /* currentThemeOnly */);
        when(mPackageManager.getApplicationInfo(anyString(), anyInt()).loadLabel(mPackageManager))
                .thenReturn(themeLabel1)
                .thenReturn(themeLabel2);
@@ -98,7 +124,7 @@ public class ThemePreferenceControllerTest {
        final String themeLabel2 = "Theme2";
        final String[] themes = {pkg1, pkg2};
        doReturn(null).when(mController).getCurrentTheme();
        doReturn(themes).when(mController).getAvailableThemes();
        doReturn(themes).when(mController).getAvailableThemes(false /* currentThemeOnly */);
        when(mPackageManager.getApplicationInfo(anyString(), anyInt()).loadLabel(mPackageManager))
                .thenReturn(themeLabel1)
                .thenReturn(themeLabel2);
@@ -109,4 +135,32 @@ public class ThemePreferenceControllerTest {
                .setSummary(RuntimeEnvironment.application.getString(R.string.default_theme));
        verify(mPreference).setValue(null);
    }

    @Test
    public void getCurrentTheme_withEnabledState() throws Exception {
        OverlayInfo info1 = new OverlayInfo("com.android.Theme1", "android",
                OverlayInfo.CATEGORY_THEME, "", OverlayInfo.STATE_ENABLED, 0, 0, true);
        OverlayInfo info2 = new OverlayInfo("com.android.Theme2", "android",
                OverlayInfo.CATEGORY_THEME, "", 0, 0, 0, true);
        when(mOverlayManager.getOverlayInfosForTarget(any(), anyInt())).thenReturn(
                Arrays.asList(info1, info2));
        when(mPackageManager.getPackageInfo(anyString(), anyInt())).thenReturn(
                new PackageInfo());

        assertThat(mController.getCurrentTheme()).isEqualTo(info1.packageName);
    }

    @Test
    public void testGetCurrentTheme_withoutEnabledState() throws Exception {
        OverlayInfo info1 = new OverlayInfo("com.android.Theme1", "android",
                OverlayInfo.CATEGORY_THEME, "", OverlayInfo.STATE_DISABLED, 0, 0, true);
        OverlayInfo info2 = new OverlayInfo("com.android.Theme2", "android",
                OverlayInfo.CATEGORY_THEME, "", 0, 0, 0, true);
        when(mOverlayManager.getOverlayInfosForTarget(any(), anyInt())).thenReturn(
                Arrays.asList(info1, info2));
        when(mPackageManager.getPackageInfo(anyString(), anyInt())).thenReturn(
                new PackageInfo());

        assertThat(mController.getCurrentTheme()).isNull();
    }
}
Loading