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

Commit dc540c04 authored by Kenneth Ford's avatar Kenneth Ford Committed by Automerger Merge Worker
Browse files

Merge changes from topic "top-focused-DevStMan" into sc-v2-dev am: c810e5c6

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15474618

Change-Id: I353f3d5ff6c4ad4b3780cb729e62920d6eb2ce7f
parents 34d5b8b1 c810e5c6
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -1133,10 +1133,10 @@ package android.hardware.camera2 {
package android.hardware.devicestate {

  public final class DeviceStateManager {
    method @RequiresPermission(android.Manifest.permission.CONTROL_DEVICE_STATE) public void cancelRequest(@NonNull android.hardware.devicestate.DeviceStateRequest);
    method @RequiresPermission(value=android.Manifest.permission.CONTROL_DEVICE_STATE, conditional=true) public void cancelRequest(@NonNull android.hardware.devicestate.DeviceStateRequest);
    method @NonNull public int[] getSupportedStates();
    method public void registerCallback(@NonNull java.util.concurrent.Executor, @NonNull android.hardware.devicestate.DeviceStateManager.DeviceStateCallback);
    method @RequiresPermission(android.Manifest.permission.CONTROL_DEVICE_STATE) public void requestState(@NonNull android.hardware.devicestate.DeviceStateRequest, @Nullable java.util.concurrent.Executor, @Nullable android.hardware.devicestate.DeviceStateRequest.Callback);
    method @RequiresPermission(value=android.Manifest.permission.CONTROL_DEVICE_STATE, conditional=true) public void requestState(@NonNull android.hardware.devicestate.DeviceStateRequest, @Nullable java.util.concurrent.Executor, @Nullable android.hardware.devicestate.DeviceStateRequest.Callback);
    method public void unregisterCallback(@NonNull android.hardware.devicestate.DeviceStateManager.DeviceStateCallback);
    field public static final int MAXIMUM_DEVICE_STATE = 255; // 0xff
    field public static final int MINIMUM_DEVICE_STATE = 0; // 0x0
+8 −6
Original line number Diff line number Diff line
@@ -86,12 +86,13 @@ public final class DeviceStateManager {
     * However, this behavior can be changed by setting flags on the {@link DeviceStateRequest}.
     *
     * @throws IllegalArgumentException if the requested state is unsupported.
     * @throws SecurityException if the {@link android.Manifest.permission#CONTROL_DEVICE_STATE}
     * permission is not held.
     * @throws SecurityException if the caller is neither the current top-focused activity nor if
     * the {@link android.Manifest.permission#CONTROL_DEVICE_STATE} permission is held.
     *
     * @see DeviceStateRequest
     */
    @RequiresPermission(android.Manifest.permission.CONTROL_DEVICE_STATE)
    @RequiresPermission(value = android.Manifest.permission.CONTROL_DEVICE_STATE,
            conditional = true)
    public void requestState(@NonNull DeviceStateRequest request,
            @Nullable @CallbackExecutor Executor executor,
            @Nullable DeviceStateRequest.Callback callback) {
@@ -105,10 +106,11 @@ public final class DeviceStateManager {
     * This method is noop if the {@code request} has not been submitted with a call to
     * {@link #requestState(DeviceStateRequest, Executor, DeviceStateRequest.Callback)}.
     *
     * @throws SecurityException if the {@link android.Manifest.permission#CONTROL_DEVICE_STATE}
     * permission is not held.
     * @throws SecurityException if the caller is neither the current top-focused activity nor if
     * the {@link android.Manifest.permission#CONTROL_DEVICE_STATE} permission is held.
     */
    @RequiresPermission(android.Manifest.permission.CONTROL_DEVICE_STATE)
    @RequiresPermission(value = android.Manifest.permission.CONTROL_DEVICE_STATE,
            conditional = true)
    public void cancelRequest(@NonNull DeviceStateRequest request) {
        mGlobal.cancelRequest(request);
    }
+27 −6
Original line number Diff line number Diff line
@@ -48,9 +48,12 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.FrameworkStatsLog;
import com.android.server.LocalServices;
import com.android.server.ServiceThread;
import com.android.server.SystemService;
import com.android.server.policy.DeviceStatePolicyImpl;
import com.android.server.wm.ActivityTaskManagerInternal;
import com.android.server.wm.WindowProcessController;

import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -101,6 +104,9 @@ public final class DeviceStateManagerService extends SystemService {
    private final BinderService mBinderService;
    @NonNull
    private final OverrideRequestController mOverrideRequestController;
    @VisibleForTesting
    @NonNull
    public ActivityTaskManagerInternal mActivityTaskManagerInternal;

    // All supported device states keyed by identifier.
    @GuardedBy("mLock")
@@ -153,6 +159,7 @@ public final class DeviceStateManagerService extends SystemService {
        mDeviceStatePolicy = policy;
        mDeviceStatePolicy.getDeviceStateProvider().setListener(new DeviceStateProviderListener());
        mBinderService = new BinderService();
        mActivityTaskManagerInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
    }

    @Override
@@ -778,14 +785,21 @@ public final class DeviceStateManagerService extends SystemService {

        @Override // Binder call
        public void requestState(IBinder token, int state, int flags) {
            final int callingPid = Binder.getCallingPid();
            // Allow top processes to request a device state change
            // If the calling process ID is not the top app, then we check if this process
            // holds a permission to CONTROL_DEVICE_STATE
            final WindowProcessController topApp = mActivityTaskManagerInternal.getTopApp();
            if (topApp.getPid() != callingPid) {
                getContext().enforceCallingOrSelfPermission(CONTROL_DEVICE_STATE,
                    "Permission required to request device state.");
                        "Permission required to request device state, "
                                + "or the call must come from the top focused app.");
            }

            if (token == null) {
                throw new IllegalArgumentException("Request token must not be null.");
            }

            final int callingPid = Binder.getCallingPid();
            final long callingIdentity = Binder.clearCallingIdentity();
            try {
                requestStateInternal(state, flags, callingPid, token);
@@ -796,14 +810,21 @@ public final class DeviceStateManagerService extends SystemService {

        @Override // Binder call
        public void cancelRequest(IBinder token) {
            final int callingPid = Binder.getCallingPid();
            // Allow top processes to cancel a device state change
            // If the calling process ID is not the top app, then we check if this process
            // holds a permission to CONTROL_DEVICE_STATE
            final WindowProcessController topApp = mActivityTaskManagerInternal.getTopApp();
            if (topApp.getPid() != callingPid) {
                getContext().enforceCallingOrSelfPermission(CONTROL_DEVICE_STATE,
                    "Permission required to clear requested device state.");
                        "Permission required to cancel device state, "
                                + "or the call must come from the top focused app.");
            }

            if (token == null) {
                throw new IllegalArgumentException("Request token must not be null.");
            }

            final int callingPid = Binder.getCallingPid();
            final long callingIdentity = Binder.clearCallingIdentity();
            try {
                cancelRequestInternal(callingPid, token);
+16 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.devicestate;

import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE;

import static org.mockito.Mockito.when;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
@@ -35,6 +36,11 @@ import android.platform.test.annotations.Presubmit;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;

import static org.mockito.Mockito.mock;

import com.android.server.wm.ActivityTaskManagerInternal;
import com.android.server.wm.WindowProcessController;

import junit.framework.Assert;

import org.junit.Before;
@@ -63,6 +69,8 @@ public final class DeviceStateManagerServiceTest {
    private static final DeviceState UNSUPPORTED_DEVICE_STATE =
            new DeviceState(255, "UNSUPPORTED", 0 /* flags */);

    private static final int FAKE_PROCESS_ID = 100;

    private TestDeviceStatePolicy mPolicy;
    private TestDeviceStateProvider mProvider;
    private DeviceStateManagerService mService;
@@ -72,6 +80,14 @@ public final class DeviceStateManagerServiceTest {
        mProvider = new TestDeviceStateProvider();
        mPolicy = new TestDeviceStatePolicy(mProvider);
        mService = new DeviceStateManagerService(InstrumentationRegistry.getContext(), mPolicy);

        // Necessary to allow us to check for top app process id in tests
        mService.mActivityTaskManagerInternal = mock(ActivityTaskManagerInternal.class);
        WindowProcessController windowProcessController = mock(WindowProcessController.class);
        when(mService.mActivityTaskManagerInternal.getTopApp())
                .thenReturn(windowProcessController);
        when(windowProcessController.getPid()).thenReturn(FAKE_PROCESS_ID);

        flushHandler(); // Flush the handler to ensure the initial values are committed.
    }