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

Commit 1c0e33b1 authored by Fabian Kozynski's avatar Fabian Kozynski
Browse files

Add config for overlaying extra default QS tiles

The new config resource allows for an overlay to specify additional QS
Tiles. These tiles will be available on a fresh flash of the device, as
well as when the user resets the tiles in QSCustomizer.

If the tiles are custom tiles and the apk is not installedi or the
TileService is disabled, the tile will just be discarded.

Test: atest QSTileHostTest
Test: add the grayscale custom spec to the config value and check that
the tile appears on reset.
Bug: 147493661
Change-Id: Ifbb8cc8ac7ef16c4b67ebbc776703e9ac8208c43
parent d31226a0
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -3545,6 +3545,12 @@
    <!-- Whether the device supports quick settings and its associated APIs -->
    <bool name="config_quickSettingsSupported">true</bool>

    <!-- Comma separated list of extra quick settings tiles to be added to the default set as
         defined in SystemUi (com.android.systemui.R.string.quick_settings_tiles_default).
         Custom tiles (TileService) must be specified as "custom(pkg_name/class_in_package)"
         (without the quotes, both absolute and relative class works). -->
    <string name="config_defaultExtraQuickSettingsTiles" translatable="false"></string>

    <!-- The component name, flattened to a string, for the default autofill service
         to  enabled for an user. This service must be trusted, as it can be activated
         without explicit consent of the user. If no autofill service with the
+1 −0
Original line number Diff line number Diff line
@@ -3404,6 +3404,7 @@
  <java-symbol type="string" name="etws_primary_default_message_others" />

  <java-symbol type="bool" name="config_quickSettingsSupported" />
  <java-symbol type="string" name="config_defaultExtraQuickSettingsTiles" />

  <java-symbol type="style" name="Theme.DeviceDefault.QuickSettings" />

+24 −6
Original line number Diff line number Diff line
@@ -366,7 +366,7 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D

    protected static List<String> loadTileSpecs(Context context, String tileList) {
        final Resources res = context.getResources();
        final String defaultTileList = res.getString(R.string.quick_settings_tiles_default);

        if (TextUtils.isEmpty(tileList)) {
            tileList = res.getString(R.string.quick_settings_tiles);
            if (DEBUG) Log.d(TAG, "Loaded tile specs from config: " + tileList);
@@ -380,11 +380,7 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D
            if (tile.isEmpty()) continue;
            if (tile.equals("default")) {
                if (!addedDefault) {
                    tiles.addAll(Arrays.asList(defaultTileList.split(",")));
                    if (Build.IS_DEBUGGABLE
                            && GarbageMonitor.MemoryTile.ADD_TO_DEFAULT_ON_DEBUGGABLE_BUILDS) {
                        tiles.add(GarbageMonitor.MemoryTile.TILE_SPEC);
                    }
                    tiles.addAll(getDefaultSpecs(context));
                    addedDefault = true;
                }
            } else {
@@ -394,6 +390,28 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, D
        return tiles;
    }

    /**
     * Returns the default QS tiles for the context.
     * @param context the context to obtain the resources from
     * @return a list of specs of the default tiles
     */
    public static List<String> getDefaultSpecs(Context context) {
        final ArrayList<String> tiles = new ArrayList<String>();

        final Resources res = context.getResources();
        final String defaultTileList = res.getString(R.string.quick_settings_tiles_default);
        final String extraTileList = res.getString(
                com.android.internal.R.string.config_defaultExtraQuickSettingsTiles);

        tiles.addAll(Arrays.asList(defaultTileList.split(",")));
        tiles.addAll(Arrays.asList(extraTileList.split(",")));
        if (Build.IS_DEBUGGABLE
                && GarbageMonitor.MemoryTile.ADD_TO_DEFAULT_ON_DEBUGGABLE_BUILDS) {
            tiles.add(GarbageMonitor.MemoryTile.TILE_SPEC);
        }
        return tiles;
    }

    @Override
    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        pw.println("QSTileHost:");
+1 −6
Original line number Diff line number Diff line
@@ -266,12 +266,7 @@ public class QSCustomizer extends LinearLayout implements OnMenuItemClickListene
    }

    private void reset() {
        ArrayList<String> tiles = new ArrayList<>();
        String defTiles = mContext.getString(R.string.quick_settings_tiles_default);
        for (String tile : defTiles.split(",")) {
            tiles.add(tile);
        }
        mTileAdapter.resetTileSpecs(mHost, tiles);
        mTileAdapter.resetTileSpecs(mHost, QSTileHost.getDefaultSpecs(mContext));
    }

    private void setTileSpecs() {
+42 −3
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.plugins.qs.QSFactory;
import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.qs.external.CustomTile;
import com.android.systemui.qs.tileimpl.QSFactoryImpl;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.shared.plugins.PluginManager;
@@ -73,6 +74,7 @@ import javax.inject.Provider;
public class QSTileHostTest extends SysuiTestCase {

    private static String MOCK_STATE_STRING = "MockState";
    private static final String CUSTOM_TILE_SPEC = "custom(TEST_PKG/.TEST_CLS)";

    @Mock
    private StatusBarIconController mIconController;
@@ -92,6 +94,8 @@ public class QSTileHostTest extends SysuiTestCase {
    private QSTile.State mMockState;
    @Mock
    private StatusBar mStatusBar;
    @Mock
    private CustomTile mCustomTile;

    private Handler mHandler;
    private TestableLooper mLooper;
@@ -103,9 +107,8 @@ public class QSTileHostTest extends SysuiTestCase {
        mLooper = TestableLooper.get(this);
        mHandler = new Handler(mLooper.getLooper());
        mQSTileHost = new TestQSTileHost(mContext, mIconController, mDefaultFactory, mHandler,
                mLooper.getLooper(),
                mPluginManager, mTunerService, mAutoTiles, mDumpController, mBroadcastDispatcher,
                mStatusBar);
                mLooper.getLooper(), mPluginManager, mTunerService, mAutoTiles, mDumpController,
                mBroadcastDispatcher, mStatusBar);
        setUpTileFactory();
        Settings.Secure.putStringForUser(mContext.getContentResolver(), QSTileHost.TILES_SETTING,
                "", ActivityManager.getCurrentUser());
@@ -121,10 +124,13 @@ public class QSTileHostTest extends SysuiTestCase {
                            return new TestTile1(mQSTileHost);
                        case "spec2":
                            return new TestTile2(mQSTileHost);
                        case CUSTOM_TILE_SPEC:
                            return mCustomTile;
                        default:
                            return null;
                    }
                });
        when(mCustomTile.isAvailable()).thenReturn(true);
    }

    @Test
@@ -173,6 +179,39 @@ public class QSTileHostTest extends SysuiTestCase {
        assertEquals(output, w.getBuffer().toString());
    }

    @Test
    public void testDefault() {
        mContext.getOrCreateTestableResources()
                .addOverride(R.string.quick_settings_tiles_default, "spec1");
        mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "default");
        assertEquals(1, mQSTileHost.getTiles().size());
        QSTile element = CollectionUtils.firstOrNull(mQSTileHost.getTiles());
        assertTrue(element instanceof TestTile1);
    }

    @Test
    public void testDefaultAndExtra() {
        mContext.getOrCreateTestableResources()
                .addOverride(R.string.quick_settings_tiles_default, "spec1");
        mContext.getOrCreateTestableResources().addOverride(
                com.android.internal.R.string.config_defaultExtraQuickSettingsTiles, "spec2");
        mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "default");
        assertEquals(2, mQSTileHost.getTiles().size());
        QSTile[] elements = mQSTileHost.getTiles().toArray(new QSTile[0]);
        assertTrue(elements[0] instanceof TestTile1);
        assertTrue(elements[1] instanceof TestTile2);
    }

    @Test
    public void testExtraCustom() {
        mContext.getOrCreateTestableResources().addOverride(
                com.android.internal.R.string.config_defaultExtraQuickSettingsTiles,
                CUSTOM_TILE_SPEC);
        mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "default");
        assertEquals(1, mQSTileHost.getTiles().size());
        assertEquals(mCustomTile, CollectionUtils.firstOrNull(mQSTileHost.getTiles()));
    }

    private static class TestQSTileHost extends QSTileHost {
        TestQSTileHost(Context context, StatusBarIconController iconController,
                QSFactoryImpl defaultFactory, Handler mainHandler, Looper bgLooper,