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

Commit f1807d89 authored by Ats Jenk's avatar Ats Jenk Committed by Android (Google) Code Review
Browse files

Merge "Add support to hide developer tile based on a flag" into tm-qpr-dev

parents 9ef4f7bf 618876c6
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -4067,6 +4067,8 @@
            </intent-filter>
            <meta-data android:name="android.service.quicksettings.TOGGLEABLE_TILE"
                android:value="true"/>
            <meta-data android:name="com.android.settings.development.qstile.REQUIRES_SYSTEM_PROPERTY"
                       android:value="persist.wm.debug.desktop_mode" />
        </service>

        <activity
+16 −1
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
import android.service.quicksettings.TileService;
import android.util.Log;

@@ -61,9 +62,23 @@ public class DevelopmentTilePreferenceController extends BasePreferenceControlle
        final Intent intent = new Intent(TileService.ACTION_QS_TILE)
                .setPackage(context.getPackageName());
        final List<ResolveInfo> resolveInfos = mPackageManager.queryIntentServices(intent,
                PackageManager.MATCH_DISABLED_COMPONENTS);
                PackageManager.MATCH_DISABLED_COMPONENTS | PackageManager.GET_META_DATA);
        for (ResolveInfo info : resolveInfos) {
            ServiceInfo sInfo = info.serviceInfo;

            // Check if the tile requires a flag. If it does, hide tile if flag is off.
            if (sInfo.metaData != null) {
                String flag = sInfo.metaData.getString(
                        DevelopmentTiles.META_DATA_REQUIRES_SYSTEM_PROPERTY);
                if (flag != null) {
                    boolean enabled = SystemProperties.getBoolean(flag, false);
                    if (!enabled) {
                        // Flagged tile, flag is not enabled
                        continue;
                    }
                }
            }

            final int enabledSetting = mPackageManager.getComponentEnabledSetting(
                    new ComponentName(sInfo.packageName, sInfo.name));
            boolean checked = enabledSetting == PackageManager.COMPONENT_ENABLED_STATE_ENABLED
+16 −0
Original line number Diff line number Diff line
@@ -58,6 +58,22 @@ import com.android.settingslib.development.DevelopmentSettingsEnabler;
import com.android.settingslib.development.SystemPropPoker;

public abstract class DevelopmentTiles extends TileService {

    /**
     * Meta-data for a development tile to declare a sysprop flag that needs to be enabled for
     * the tile to be available.
     *
     * To define the flag, set this meta-data on the tile's manifest declaration.
     * <pre class="prettyprint">
     * {@literal
     * <meta-data android:name="com.android.settings.development.qstile.REQUIRES_SYSTEM_PROPERTY"
     *     android:value="persist.debug.flag_name_here" />
     * }
     * </pre>
     */
    public static final String META_DATA_REQUIRES_SYSTEM_PROPERTY =
            "com.android.settings.development.qstile.REQUIRES_SYSTEM_PROPERTY";

    private static final String TAG = "DevelopmentTiles";

    protected abstract boolean isEnabled();
+50 −5
Original line number Diff line number Diff line
@@ -19,7 +19,9 @@ package com.android.settings.development.qstile;
import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -30,6 +32,7 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.os.Bundle;
import android.os.RemoteException;
import android.service.quicksettings.TileService;

@@ -50,6 +53,7 @@ import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
import org.robolectric.shadows.ShadowPackageManager;
import org.robolectric.shadows.ShadowSystemProperties;
import org.robolectric.util.ReflectionHelpers;

import java.util.Arrays;
@@ -88,11 +92,7 @@ public class DevelopmentTilePreferenceControllerTest {
    public void display_hasTileService_shouldDisplay() {
        final Intent tileProbe = new Intent(TileService.ACTION_QS_TILE)
                .setPackage(mContext.getPackageName());
        final ResolveInfo info = new ResolveInfo();
        info.serviceInfo = new FakeServiceInfo();
        info.serviceInfo.name = "abc";
        info.serviceInfo.icon = R.drawable.ic_settings_24dp;
        info.serviceInfo.packageName = mContext.getPackageName();
        final ResolveInfo info = createFakeInfo("abc");
        mShadowPackageManager.setResolveInfosForIntent(tileProbe, Arrays.asList(info));

        mController.displayPreference(mScreen);
@@ -100,6 +100,36 @@ public class DevelopmentTilePreferenceControllerTest {
        verify(mScreen, atLeastOnce()).addPreference(any(Preference.class));
    }

    @Test
    public void display_flagDefinedAndOn_shouldDisplay() {
        ShadowSystemProperties.override("tile_flag", "1");

        final Intent tileProbe = new Intent(TileService.ACTION_QS_TILE)
                .setPackage(mContext.getPackageName());
        final ResolveInfo info = createFakeInfo("abc");
        info.serviceInfo.metaData = createFlagMetadata("tile_flag");
        mShadowPackageManager.setResolveInfosForIntent(tileProbe, Arrays.asList(info));

        mController.displayPreference(mScreen);

        verify(mScreen, atLeastOnce()).addPreference(argThat(pref -> pref.getKey().equals("abc")));
    }

    @Test
    public void display_flagDefinedAndOff_shouldHide() {
        ShadowSystemProperties.override("tile_flag" , "0");

        final Intent tileProbe = new Intent(TileService.ACTION_QS_TILE)
                .setPackage(mContext.getPackageName());
        final ResolveInfo info = createFakeInfo("abc");
        info.serviceInfo.metaData = createFlagMetadata("tile_flag");
        mShadowPackageManager.setResolveInfosForIntent(tileProbe, Arrays.asList(info));

        mController.displayPreference(mScreen);

        verify(mScreen, never()).addPreference(argThat(pref -> pref.getKey().equals("abc")));
    }

    @Test
    public void preferenceChecked_shouldAddTile() throws RemoteException {
        SwitchPreference preference = createPreference(/* defaultCheckedState = */ false);
@@ -132,6 +162,21 @@ public class DevelopmentTilePreferenceControllerTest {
        return preference;
    }

    private ResolveInfo createFakeInfo(String name) {
        final ResolveInfo info = new ResolveInfo();
        info.serviceInfo = new FakeServiceInfo();
        info.serviceInfo.name = name;
        info.serviceInfo.icon = R.drawable.ic_settings_24dp;
        info.serviceInfo.packageName = mContext.getPackageName();
        return info;
    }

    private Bundle createFlagMetadata(String flag) {
        Bundle metaData = new Bundle();
        metaData.putString(DevelopmentTiles.META_DATA_REQUIRES_SYSTEM_PROPERTY, flag);
        return metaData;
    }

    private static class FakeServiceInfo extends ServiceInfo {

        public String loadLabel(PackageManager mgr) {