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

Commit 031b9313 authored by Anton Potapov's avatar Anton Potapov
Browse files

Move CustomTile specific stuff behind the interface in TileServices

We need an abstraction in TileServices to allow flagging between old tiles and the new ones.

Test: passes current tests
Test: manually launch a devices with a custom tile and toggle it
Bug: 301055700
Change-Id: I696de56786b44ed5a1d3c3051b298d00f41ab4c4
parent d8d280f6
Loading
Loading
Loading
Loading
+14 −3
Original line number Diff line number Diff line
@@ -72,7 +72,8 @@ import dagger.assisted.Assisted;
import dagger.assisted.AssistedFactory;
import dagger.assisted.AssistedInject;

public class CustomTile extends QSTileImpl<State> implements TileChangeListener {
public class CustomTile extends QSTileImpl<State> implements TileChangeListener,
        CustomTileInterface {
    public static final String PREFIX = "custom(";

    private static final long CUSTOM_STALE_TIMEOUT = DateUtils.HOUR_IN_MILLIS;
@@ -181,7 +182,8 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener
    private void updateDefaultTileAndIcon() {
        try {
            PackageManager pm = mUserContext.getPackageManager();
            int flags = PackageManager.MATCH_DIRECT_BOOT_UNAWARE | PackageManager.MATCH_DIRECT_BOOT_AWARE;
            int flags = PackageManager.MATCH_DIRECT_BOOT_UNAWARE
                    | PackageManager.MATCH_DIRECT_BOOT_AWARE;
            if (isSystemApp(pm)) {
                flags |= PackageManager.MATCH_DISABLED_COMPONENTS;
            }
@@ -252,10 +254,12 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener
        }
    }

    @Override
    public int getUser() {
        return mUser;
    }

    @Override
    public ComponentName getComponent() {
        return mComponent;
    }
@@ -265,6 +269,7 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener
        return super.populate(logMaker).setComponentName(mComponent);
    }

    @Override
    public Tile getQsTile() {
        // TODO(b/191145007) Move to background thread safely
        updateDefaultTileAndIcon();
@@ -276,6 +281,7 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener
     *
     * @param tile tile populated with state to apply
     */
    @Override
    public void updateTileState(Tile tile, int appUid) {
        mServiceUid = appUid;
        // This comes from a binder call IQSService.updateQsTile
@@ -310,10 +316,12 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener
        mTile.setState(tile.getState());
    }

    @Override
    public void onDialogShown() {
        mIsShowingDialog = true;
    }

    @Override
    public void onDialogHidden() {
        mIsShowingDialog = false;
        try {
@@ -507,6 +515,7 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener
        return mComponent.getPackageName();
    }

    @Override
    public void startUnlockAndRun() {
        mActivityStarter.postQSRunnableDismissingKeyguard(() -> {
            try {
@@ -518,8 +527,10 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener

    /**
     * Starts an {@link android.app.Activity}
     *
     * @param pendingIntent A PendingIntent for an Activity to be launched immediately.
     */
    @Override
    public void startActivityAndCollapse(PendingIntent pendingIntent) {
        if (!pendingIntent.isActivity()) {
            Log.i(TAG, "Intent not for activity.");
+40 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.systemui.qs.external

import android.app.PendingIntent
import android.content.ComponentName
import android.service.quicksettings.Tile

interface CustomTileInterface {

    val user: Int
    val qsTile: Tile
    val component: ComponentName

    fun getTileSpec(): String

    fun refreshState()
    fun updateTileState(tile: Tile, uid: Int)

    fun onDialogShown()
    fun onDialogHidden()

    fun startActivityAndCollapse(pendingIntent: PendingIntent)

    fun startUnlockAndRun()
}
+20 −24
Original line number Diff line number Diff line
@@ -67,9 +67,10 @@ public class TileServices extends IQSService.Stub {
    static final int REDUCED_MAX_BOUND = 1;
    private static final String TAG = "TileServices";

    private final ArrayMap<CustomTile, TileServiceManager> mServices = new ArrayMap<>();
    private final SparseArrayMap<ComponentName, CustomTile> mTiles = new SparseArrayMap<>();
    private final ArrayMap<IBinder, CustomTile> mTokenMap = new ArrayMap<>();
    private final ArrayMap<CustomTileInterface, TileServiceManager> mServices = new ArrayMap<>();
    private final SparseArrayMap<ComponentName, CustomTileInterface> mTiles =
            new SparseArrayMap<>();
    private final ArrayMap<IBinder, CustomTileInterface> mTokenMap = new ArrayMap<>();
    private final Context mContext;
    private final Handler mMainHandler;
    private final Provider<Handler> mHandlerProvider;
@@ -120,7 +121,7 @@ public class TileServices extends IQSService.Stub {
        return mHost;
    }

    public TileServiceManager getTileWrapper(CustomTile tile) {
    public TileServiceManager getTileWrapper(CustomTileInterface tile) {
        ComponentName component = tile.getComponent();
        int userId = tile.getUser();
        TileServiceManager service = onCreateTileService(component, mBroadcastDispatcher);
@@ -140,7 +141,7 @@ public class TileServices extends IQSService.Stub {
                broadcastDispatcher, mUserTracker, mCustomTileAddedRepository, mBackgroundExecutor);
    }

    public void freeService(CustomTile tile, TileServiceManager service) {
    public void freeService(CustomTileInterface tile, TileServiceManager service) {
        synchronized (mServices) {
            service.setBindAllowed(false);
            service.handleDestroy();
@@ -184,7 +185,7 @@ public class TileServices extends IQSService.Stub {
        }
    }

    private int verifyCaller(CustomTile tile) {
    private int verifyCaller(CustomTileInterface tile) {
        try {
            String packageName = tile.getComponent().getPackageName();
            int uid = mContext.getPackageManager().getPackageUidAsUser(packageName,
@@ -201,7 +202,7 @@ public class TileServices extends IQSService.Stub {
    private void requestListening(ComponentName component) {
        synchronized (mServices) {
            int userId = mUserTracker.getUserId();
            CustomTile customTile = getTileForUserAndComponent(userId, component);
            CustomTileInterface customTile = getTileForUserAndComponent(userId, component);
            if (customTile == null) {
                Log.d(TAG, "Couldn't find tile for " + component + "(" + userId + ")");
                return;
@@ -227,7 +228,7 @@ public class TileServices extends IQSService.Stub {

    @Override
    public void updateQsTile(Tile tile, IBinder token) {
        CustomTile customTile = getTileForToken(token);
        CustomTileInterface customTile = getTileForToken(token);
        if (customTile != null) {
            int uid = verifyCaller(customTile);
            synchronized (mServices) {
@@ -247,7 +248,7 @@ public class TileServices extends IQSService.Stub {

    @Override
    public void onStartSuccessful(IBinder token) {
        CustomTile customTile = getTileForToken(token);
        CustomTileInterface customTile = getTileForToken(token);
        if (customTile != null) {
            verifyCaller(customTile);
            synchronized (mServices) {
@@ -267,7 +268,7 @@ public class TileServices extends IQSService.Stub {

    @Override
    public void onShowDialog(IBinder token) {
        CustomTile customTile = getTileForToken(token);
        CustomTileInterface customTile = getTileForToken(token);
        if (customTile != null) {
            verifyCaller(customTile);
            customTile.onDialogShown();
@@ -278,7 +279,7 @@ public class TileServices extends IQSService.Stub {

    @Override
    public void onDialogHidden(IBinder token) {
        CustomTile customTile = getTileForToken(token);
        CustomTileInterface customTile = getTileForToken(token);
        if (customTile != null) {
            verifyCaller(customTile);
            Objects.requireNonNull(mServices.get(customTile)).setShowingDialog(false);
@@ -288,7 +289,7 @@ public class TileServices extends IQSService.Stub {

    @Override
    public void onStartActivity(IBinder token) {
        CustomTile customTile = getTileForToken(token);
        CustomTileInterface customTile = getTileForToken(token);
        if (customTile != null) {
            verifyCaller(customTile);
            mPanelInteractor.forceCollapsePanels();
@@ -301,7 +302,7 @@ public class TileServices extends IQSService.Stub {
    }

    @VisibleForTesting
    protected void startActivity(CustomTile customTile, PendingIntent pendingIntent) {
    protected void startActivity(CustomTileInterface customTile, PendingIntent pendingIntent) {
        if (customTile != null) {
            verifyCaller(customTile);
            customTile.startActivityAndCollapse(pendingIntent);
@@ -310,7 +311,7 @@ public class TileServices extends IQSService.Stub {

    @Override
    public void updateStatusIcon(IBinder token, Icon icon, String contentDescription) {
        CustomTile customTile = getTileForToken(token);
        CustomTileInterface customTile = getTileForToken(token);
        if (customTile != null) {
            verifyCaller(customTile);
            try {
@@ -340,7 +341,7 @@ public class TileServices extends IQSService.Stub {
    @Nullable
    @Override
    public Tile getTile(IBinder token) {
        CustomTile customTile = getTileForToken(token);
        CustomTileInterface customTile = getTileForToken(token);
        if (customTile != null) {
            verifyCaller(customTile);
            return customTile.getQsTile();
@@ -367,7 +368,7 @@ public class TileServices extends IQSService.Stub {

    @Override
    public void startUnlockAndRun(IBinder token) {
        CustomTile customTile = getTileForToken(token);
        CustomTileInterface customTile = getTileForToken(token);
        if (customTile != null) {
            verifyCaller(customTile);
            customTile.startUnlockAndRun();
@@ -385,14 +386,14 @@ public class TileServices extends IQSService.Stub {
    }

    @Nullable
    public CustomTile getTileForToken(IBinder token) {
    public CustomTileInterface getTileForToken(IBinder token) {
        synchronized (mServices) {
            return mTokenMap.get(token);
        }
    }

    @Nullable
    private CustomTile getTileForUserAndComponent(int userId, ComponentName component) {
    private CustomTileInterface getTileForUserAndComponent(int userId, ComponentName component) {
        synchronized (mServices) {
            return mTiles.get(userId, component);
        }
@@ -419,11 +420,6 @@ public class TileServices extends IQSService.Stub {
    };

    private static final Comparator<TileServiceManager> SERVICE_SORT =
            new Comparator<TileServiceManager>() {
        @Override
        public int compare(TileServiceManager left, TileServiceManager right) {
            return -Integer.compare(left.getBindPriority(), right.getBindPriority());
        }
    };
            (left, right) -> -Integer.compare(left.getBindPriority(), right.getBindPriority());

}