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

Commit 82b28764 authored by Fabian Kozynski's avatar Fabian Kozynski Committed by Android (Google) Code Review
Browse files

Merge changes from topics "172251878", "presubmit-am-7890421506ee474b9057d3c5d333e341" into tm-dev

* changes:
  CompatChange to use hidden API in TileService
  Fix loopers in TileServices
parents 0859177c af6c54c1
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -843,6 +843,24 @@ public class StatusBarManager {
        }
    }

    /**
     * Sets an active {@link android.service.quicksettings.TileService} to listening state
     *
     * The {@code componentName}'s package must match the calling package.
     *
     * @param componentName the tile to set into listening state
     * @see android.service.quicksettings.TileService#requestListeningState
     * @hide
     */
    public void requestTileServiceListeningState(@NonNull ComponentName componentName) {
        Objects.requireNonNull(componentName);
        try {
            getService().requestTileServiceListeningState(componentName, mContext.getUserId());
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
    }

    /**
     * Request to the user to add a {@link android.service.quicksettings.TileService}
     * to the set of current QS tiles.
+19 −15
Original line number Diff line number Diff line
@@ -15,18 +15,19 @@
 */
package android.service.quicksettings;

import android.Manifest;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.app.Dialog;
import android.app.Service;
import android.app.StatusBarManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.drawable.Icon;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -146,13 +147,6 @@ public class TileService extends Service {
    public static final String META_DATA_TOGGLEABLE_TILE =
            "android.service.quicksettings.TOGGLEABLE_TILE";

    /**
     * Used to notify SysUI that Listening has be requested.
     * @hide
     */
    public static final String ACTION_REQUEST_LISTENING =
            "android.service.quicksettings.action.REQUEST_LISTENING";

    /**
     * @hide
     */
@@ -482,14 +476,24 @@ public class TileService extends Service {
     *
     * This method is only applicable to tiles that have {@link #META_DATA_ACTIVE_TILE} defined
     * as true on their TileService Manifest declaration, and will do nothing otherwise.
     *
     * For apps targeting {@link Build.VERSION_CODES#TIRAMISU} or later, this call may throw
     * the following exceptions if the request is not valid:
     * <ul>
     *     <li> {@link NullPointerException} if {@code component} is {@code null}.</li>
     *     <li> {@link SecurityException} if the package of {@code component} does not match
     *     the calling package or if the calling user cannot act on behalf of the user from the
     *     {@code context}.</li>
     *     <li> {@link IllegalArgumentException} if the user of the {@code context} is not the
     *     current user.</li>
     * </ul>
     */
    public static final void requestListeningState(Context context, ComponentName component) {
        final ComponentName sysuiComponent = ComponentName.unflattenFromString(
                context.getResources().getString(
                        com.android.internal.R.string.config_systemUIServiceComponent));
        Intent intent = new Intent(ACTION_REQUEST_LISTENING);
        intent.putExtra(Intent.EXTRA_COMPONENT_NAME, component);
        intent.setPackage(sysuiComponent.getPackageName());
        context.sendBroadcast(intent, Manifest.permission.BIND_QUICK_SETTINGS_TILE);
        StatusBarManager sbm = context.getSystemService(StatusBarManager.class);
        if (sbm == null) {
            Log.e(TAG, "No StatusBarManager service found");
            return;
        }
        sbm.requestTileServiceListeningState(component);
    }
}
+5 −0
Original line number Diff line number Diff line
@@ -297,6 +297,11 @@ oneway interface IStatusBar
     */
    void runGcForTest();

    /**
     * Send a request to SystemUI to put a given active tile in listening state
     */
    void requestTileServiceListeningState(in ComponentName componentName);

    void requestAddTile(in ComponentName componentName, in CharSequence appName, in CharSequence label, in Icon icon, in IAddTileResultCallback callback);
    void cancelRequestAddTile(in String packageName);

+5 −0
Original line number Diff line number Diff line
@@ -171,6 +171,11 @@ interface IStatusBarService
     */
    void suppressAmbientDisplay(boolean suppress);

    /**
     * Send a request to SystemUI to put a given active tile in listening state
     */
    void requestTileServiceListeningState(in ComponentName componentName, int userId);

    void requestAddTile(in ComponentName componentName, in CharSequence label, in Icon icon, int userId, in IAddTileResultCallback callback);
    void cancelRequestAddTile(in String packageName);

+17 −28
Original line number Diff line number Diff line
@@ -15,26 +15,22 @@
 */
package com.android.systemui.qs.external;

import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Icon;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.os.UserHandle;
import android.service.quicksettings.IQSService;
import android.service.quicksettings.Tile;
import android.service.quicksettings.TileService;
import android.util.ArrayMap;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.internal.statusbar.StatusBarIcon;
@@ -42,6 +38,7 @@ import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.qs.QSTileHost;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.policy.KeyguardStateController;

@@ -51,6 +48,7 @@ import java.util.Comparator;
import java.util.Objects;

import javax.inject.Inject;
import javax.inject.Provider;

/**
 * Runs the day-to-day operations of which tiles should be bound and when.
@@ -64,11 +62,12 @@ public class TileServices extends IQSService.Stub {
    private final ArrayMap<ComponentName, CustomTile> mTiles = new ArrayMap<>();
    private final ArrayMap<IBinder, CustomTile> mTokenMap = new ArrayMap<>();
    private final Context mContext;
    private final Handler mHandler;
    private final Handler mMainHandler;
    private final Provider<Handler> mHandlerProvider;
    private final QSTileHost mHost;
    private final KeyguardStateController mKeyguardStateController;
    private final BroadcastDispatcher mBroadcastDispatcher;
    private final CommandQueue mCommandQueue;
    private final UserTracker mUserTracker;

    private int mMaxBound = DEFAULT_MAX_BOUND;
@@ -76,23 +75,20 @@ public class TileServices extends IQSService.Stub {
    @Inject
    public TileServices(
            QSTileHost host,
            @Main Looper looper,
            @Main Provider<Handler> handlerProvider,
            BroadcastDispatcher broadcastDispatcher,
            UserTracker userTracker,
            KeyguardStateController keyguardStateController) {
            KeyguardStateController keyguardStateController,
            CommandQueue commandQueue) {
        mHost = host;
        mKeyguardStateController = keyguardStateController;
        mContext = mHost.getContext();
        mBroadcastDispatcher = broadcastDispatcher;
        mHandler = new Handler(looper);
        mMainHandler = new Handler(Looper.getMainLooper());
        mHandlerProvider = handlerProvider;
        mMainHandler = mHandlerProvider.get();
        mUserTracker = userTracker;
        mBroadcastDispatcher.registerReceiver(
                mRequestListeningReceiver,
                new IntentFilter(TileService.ACTION_REQUEST_LISTENING),
                null, // Use the default Executor
                UserHandle.ALL
        );
        mCommandQueue = commandQueue;
        mCommandQueue.addCallback(mRequestListeningCallback);
    }

    public Context getContext() {
@@ -118,7 +114,7 @@ public class TileServices extends IQSService.Stub {

    protected TileServiceManager onCreateTileService(ComponentName component,
            BroadcastDispatcher broadcastDispatcher) {
        return new TileServiceManager(this, mHandler, component,
        return new TileServiceManager(this, mHandlerProvider.get(), component,
                broadcastDispatcher, mUserTracker);
    }

@@ -354,21 +350,14 @@ public class TileServices extends IQSService.Stub {
    public void destroy() {
        synchronized (mServices) {
            mServices.values().forEach(service -> service.handleDestroy());
            mBroadcastDispatcher.unregisterReceiver(mRequestListeningReceiver);
        }
        mCommandQueue.removeCallback(mRequestListeningCallback);
    }

    private final BroadcastReceiver mRequestListeningReceiver = new BroadcastReceiver() {
    private final CommandQueue.Callbacks mRequestListeningCallback = new CommandQueue.Callbacks() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (TileService.ACTION_REQUEST_LISTENING.equals(intent.getAction())) {
                try {
                    ComponentName c = intent.getParcelableExtra(Intent.EXTRA_COMPONENT_NAME);
                    requestListening(c);
                } catch (ClassCastException ex) {
                    Log.e(TAG, "Bad component name", ex);
                }
            }
        public void requestTileServiceListeningState(@NonNull ComponentName componentName) {
            mMainHandler.post(() -> requestListening(componentName));
        }
    };

Loading