Merge changes from topic "top-focused-DevStMan" into sc-v2-dev am: c810e5c6dd
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15474618 Change-Id: I353f3d5ff6c4ad4b3780cb729e62920d6eb2ce7f
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
getContext().enforceCallingOrSelfPermission(CONTROL_DEVICE_STATE,
|
||||
"Permission required to request device state.");
|
||||
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, "
|
||||
+ "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) {
|
||||
getContext().enforceCallingOrSelfPermission(CONTROL_DEVICE_STATE,
|
||||
"Permission required to clear requested device state.");
|
||||
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 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);
|
||||
|
||||
@@ -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.
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user