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

Commit 23b011a9 authored by Nan Wu's avatar Nan Wu Committed by Android (Google) Code Review
Browse files

Merge "Allow tile services to start foreground service when tile is clicked" into main

parents 3ace69d8 c5ea08c6
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -427,6 +427,12 @@ public class PowerExemptionManager {
     */
    public static final int REASON_PACKAGE_UNARCHIVE = 328;

    /**
     * Tile onClick event
     * @hide
     */
    public static final int REASON_TILE_ONCLICK = 329;

    /** @hide The app requests out-out. */
    public static final int REASON_OPT_OUT_REQUESTED = 1000;

@@ -504,13 +510,15 @@ public class PowerExemptionManager {
            REASON_ROLE_EMERGENCY,
            REASON_SYSTEM_MODULE,
            REASON_CARRIER_PRIVILEGED_APP,
            REASON_OPT_OUT_REQUESTED,
            REASON_DPO_PROTECTED_APP,
            REASON_DISALLOW_APPS_CONTROL,
            REASON_ACTIVE_DEVICE_ADMIN,
            REASON_MEDIA_NOTIFICATION_TRANSFER,
            REASON_PACKAGE_INSTALLER,
            REASON_SYSTEM_EXEMPT_APP_OP,
            REASON_PACKAGE_UNARCHIVE,
            REASON_TILE_ONCLICK,
            REASON_OPT_OUT_REQUESTED,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface ReasonCode {}
+5 −0
Original line number Diff line number Diff line
@@ -310,6 +310,11 @@ public class PowerWhitelistManager {
     * @hide
     */
    public static final int REASON_SHELL = PowerExemptionManager.REASON_SHELL;
    /**
     * Tile onClick event
     * @hide
     */
    public static final int REASON_TILE_ONCLICK = PowerExemptionManager.REASON_TILE_ONCLICK;

    /**
     * The list of BG-FGS-Launch and temp-allowlist reason code.
+8 −0
Original line number Diff line number Diff line
@@ -76,6 +76,7 @@ import android.net.ConnectivityManager;
import android.net.NetworkScoreManager;
import android.net.wifi.WifiManager;
import android.os.BatteryStats;
import android.os.IDeviceIdleController;
import android.os.PowerExemptionManager;
import android.os.PowerManager;
import android.os.ServiceManager;
@@ -735,4 +736,11 @@ public class FrameworkServicesModule {
    static Optional<SatelliteManager> provideSatelliteManager(Context context) {
        return Optional.ofNullable(context.getSystemService(SatelliteManager.class));
    }

    @Provides
    @Singleton
    static IDeviceIdleController provideDeviceIdleController() {
        return IDeviceIdleController.Stub.asInterface(
                ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER));
    }
}
+43 −3
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
 */
package com.android.systemui.qs.external;

import static android.os.PowerWhitelistManager.REASON_TILE_ONCLICK;
import static android.provider.DeviceConfig.NAMESPACE_SYSTEMUI;
import static android.service.quicksettings.TileService.START_ACTIVITY_NEEDS_PENDING_INTENT;

import android.app.ActivityManager;
@@ -31,8 +33,10 @@ import android.net.Uri;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.IDeviceIdleController;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.service.quicksettings.IQSService;
import android.service.quicksettings.IQSTileService;
import android.service.quicksettings.TileService;
@@ -89,7 +93,9 @@ public class TileLifecycleManager extends BroadcastReceiver implements
    private static final int MAX_BIND_RETRIES = 5;
    private static final long DEFAULT_BIND_RETRY_DELAY = 5 * DateUtils.SECOND_IN_MILLIS;
    private static final long LOW_MEMORY_BIND_RETRY_DELAY = 20 * DateUtils.SECOND_IN_MILLIS;

    private static final long TILE_SERVICE_ONCLICK_ALLOW_LIST_DEFAULT_DURATION_MS = 15_000;
    private static final String PROPERTY_TILE_SERVICE_ONCLICK_ALLOW_LIST_DURATION =
            "property_tile_service_onclick_allow_list_duration";
    // Shared prefs that hold tile lifecycle info.
    private static final String TILES = "tiles_prefs";

@@ -102,6 +108,7 @@ public class TileLifecycleManager extends BroadcastReceiver implements
    private final PackageManagerAdapter mPackageManagerAdapter;
    private final BroadcastDispatcher mBroadcastDispatcher;
    private final ActivityManager mActivityManager;
    private final IDeviceIdleController mDeviceIdleController;

    private Set<Integer> mQueuedMessages = new ArraySet<>();
    @NonNull
@@ -120,12 +127,15 @@ public class TileLifecycleManager extends BroadcastReceiver implements
    private TileChangeListener mChangeListener;
    // Return value from bindServiceAsUser, determines whether safe to call unbind.
    private AtomicBoolean mIsBound = new AtomicBoolean(false);
    private long mTempAllowFgsLaunchDuration = TILE_SERVICE_ONCLICK_ALLOW_LIST_DEFAULT_DURATION_MS;
    private final DeviceConfig.OnPropertiesChangedListener mDeviceConfigChangedListener;
    private AtomicBoolean mDeviceConfigChangedListenerRegistered = new AtomicBoolean(false);

    @AssistedInject
    TileLifecycleManager(@Main Handler handler, Context context, IQSService service,
            PackageManagerAdapter packageManagerAdapter, BroadcastDispatcher broadcastDispatcher,
            @Assisted Intent intent, @Assisted UserHandle user, ActivityManager activityManager,
            @Background DelayableExecutor executor) {
            IDeviceIdleController deviceIdleController, @Background DelayableExecutor executor) {
        mContext = context;
        mHandler = handler;
        mIntent = intent;
@@ -136,6 +146,16 @@ public class TileLifecycleManager extends BroadcastReceiver implements
        mPackageManagerAdapter = packageManagerAdapter;
        mBroadcastDispatcher = broadcastDispatcher;
        mActivityManager = activityManager;
        mDeviceIdleController = deviceIdleController;
        mDeviceConfigChangedListener = properties -> {
            if (!DeviceConfig.NAMESPACE_SYSTEMUI.equals(properties.getNamespace())) {
                return;
            }
            mTempAllowFgsLaunchDuration = properties.getLong(
                    PROPERTY_TILE_SERVICE_ONCLICK_ALLOW_LIST_DURATION,
                    TILE_SERVICE_ONCLICK_ALLOW_LIST_DEFAULT_DURATION_MS);
        };

        if (mDebug) Log.d(TAG, "Creating " + mIntent + " " + mUser);
    }

@@ -211,6 +231,13 @@ public class TileLifecycleManager extends BroadcastReceiver implements
        }
        mBound.set(bind);
        if (bind) {
            if (mDeviceConfigChangedListenerRegistered.compareAndSet(false, true)) {
                DeviceConfig.addOnPropertiesChangedListener(NAMESPACE_SYSTEMUI, mExecutor,
                        mDeviceConfigChangedListener);
                mTempAllowFgsLaunchDuration = DeviceConfig.getLong(NAMESPACE_SYSTEMUI,
                        PROPERTY_TILE_SERVICE_ONCLICK_ALLOW_LIST_DURATION,
                        TILE_SERVICE_ONCLICK_ALLOW_LIST_DEFAULT_DURATION_MS);
            }
            if (mBindTryCount == MAX_BIND_RETRIES) {
                // Too many failures, give up on this tile until an update.
                startPackageListening();
@@ -363,6 +390,9 @@ public class TileLifecycleManager extends BroadcastReceiver implements
            stopPackageListening();
        }
        mChangeListener = null;
        if (mDeviceConfigChangedListener != null) {
            DeviceConfig.removeOnPropertiesChangedListener(mDeviceConfigChangedListener);
        }
    }

    /**
@@ -566,7 +596,17 @@ public class TileLifecycleManager extends BroadcastReceiver implements
    @Override
    public void onClick(IBinder iBinder) {
        if (mDebug) Log.d(TAG, "onClick " + iBinder + " " + getComponent() + " " + mUser);
        if (isNullOrFailedAction(mOptionalWrapper, (wrapper) -> wrapper.onClick(iBinder))) {
        if (isNullOrFailedAction(mOptionalWrapper, (wrapper) -> {
            final String packageName = mIntent.getComponent().getPackageName();
            try {
                mDeviceIdleController.addPowerSaveTempWhitelistApp(packageName,
                        mTempAllowFgsLaunchDuration, mUser.getIdentifier(), REASON_TILE_ONCLICK,
                        "tile onclick");
            } catch (RemoteException e) {
                Log.d(TAG, "Caught exception trying to add client package to temp allow list", e);
            }
            return wrapper.onClick(iBinder);
        })) {
            mClickBinder = iBinder;
            queueMessage(MSG_ON_CLICK);
            handleDeath();
+22 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */
package com.android.systemui.qs.external;

import static android.os.PowerExemptionManager.REASON_TILE_ONCLICK;
import static android.service.quicksettings.TileService.START_ACTIVITY_NEEDS_PENDING_INTENT;

import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -52,6 +53,7 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IDeviceIdleController;
import android.os.UserHandle;
import android.service.quicksettings.IQSService;
import android.service.quicksettings.IQSTileService;
@@ -83,6 +85,7 @@ public class TileLifecycleManagerTest extends SysuiTestCase {
            mock(BroadcastDispatcher.class);
    private final IQSTileService.Stub mMockTileService = mock(IQSTileService.Stub.class);
    private final ActivityManager mActivityManager = mock(ActivityManager.class);
    private final IDeviceIdleController mDeviceIdleController = mock(IDeviceIdleController.class);

    private ComponentName mTileServiceComponentName;
    private Intent mTileServiceIntent;
@@ -126,6 +129,7 @@ public class TileLifecycleManagerTest extends SysuiTestCase {
                mTileServiceIntent,
                mUser,
                mActivityManager,
                mDeviceIdleController,
                mExecutor);
    }

@@ -385,6 +389,20 @@ public class TileLifecycleManagerTest extends SysuiTestCase {
        assertTrue(mStateManager.isToggleableTile());
    }

    @Test
    public void testClickCallsDeviceIdleManager() throws Exception {
        mStateManager.onTileAdded();
        mStateManager.onStartListening();
        mStateManager.onClick(null);
        mStateManager.executeSetBindService(true);
        mExecutor.runAllReady();

        verify(mMockTileService).onClick(null);
        verify(mDeviceIdleController).addPowerSaveTempWhitelistApp(
                mTileServiceComponentName.getPackageName(), 15000,
                mUser.getIdentifier(), REASON_TILE_ONCLICK, "tile onclick");
    }

    @Test
    public void testFalseBindCallsUnbind() {
        Context falseContext = mock(Context.class);
@@ -396,6 +414,7 @@ public class TileLifecycleManagerTest extends SysuiTestCase {
                mTileServiceIntent,
                mUser,
                mActivityManager,
                mDeviceIdleController,
                mExecutor);

        manager.executeSetBindService(true);
@@ -418,6 +437,7 @@ public class TileLifecycleManagerTest extends SysuiTestCase {
                mTileServiceIntent,
                mUser,
                mActivityManager,
                mDeviceIdleController,
                mExecutor);

        manager.executeSetBindService(true);
@@ -440,6 +460,7 @@ public class TileLifecycleManagerTest extends SysuiTestCase {
                mTileServiceIntent,
                mUser,
                mActivityManager,
                mDeviceIdleController,
                mExecutor);

        manager.executeSetBindService(true);
@@ -464,6 +485,7 @@ public class TileLifecycleManagerTest extends SysuiTestCase {
                mTileServiceIntent,
                mUser,
                mActivityManager,
                mDeviceIdleController,
                mExecutor);

        manager.executeSetBindService(true);