summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/hardware/devicestate/DeviceStateManager.java47
-rw-r--r--core/java/android/hardware/devicestate/DeviceStateManagerGlobal.java85
-rw-r--r--core/java/android/hardware/devicestate/IDeviceStateManager.aidl45
3 files changed, 161 insertions, 16 deletions
diff --git a/core/java/android/hardware/devicestate/DeviceStateManager.java b/core/java/android/hardware/devicestate/DeviceStateManager.java
index 30aa4db938da..bdd45e6df448 100644
--- a/core/java/android/hardware/devicestate/DeviceStateManager.java
+++ b/core/java/android/hardware/devicestate/DeviceStateManager.java
@@ -16,6 +16,7 @@
package android.hardware.devicestate;
+import android.Manifest;
import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -115,6 +116,52 @@ public final class DeviceStateManager {
}
/**
+ * Submits a {@link DeviceStateRequest request} to override the base state of the device. This
+ * should only be used for testing, where you want to simulate the physical change to the
+ * device state.
+ * <p>
+ * By default, the request is kept active until one of the following occurs:
+ * <ul>
+ * <li>The physical state of the device changes</li>
+ * <li>The system deems the request can no longer be honored, for example if the requested
+ * state becomes unsupported.
+ * <li>A call to {@link #cancelBaseStateOverride}.
+ * <li>Another processes submits a request succeeding this request in which case the request
+ * will be canceled.
+ * </ul>
+ *
+ * Submitting a base state override request may not cause any change in the presentation
+ * of the system if there is an emulated request made through {@link #requestState}, as the
+ * emulated override requests take priority.
+ *
+ * @throws IllegalArgumentException if the requested state is unsupported.
+ * @throws SecurityException if the caller does not hold the
+ * {@link android.Manifest.permission#CONTROL_DEVICE_STATE} permission.
+ *
+ * @see DeviceStateRequest
+ */
+ @RequiresPermission(android.Manifest.permission.CONTROL_DEVICE_STATE)
+ public void requestBaseStateOverride(@NonNull DeviceStateRequest request,
+ @Nullable @CallbackExecutor Executor executor,
+ @Nullable DeviceStateRequest.Callback callback) {
+ mGlobal.requestBaseStateOverride(request, executor, callback);
+ }
+
+ /**
+ * Cancels the active {@link DeviceStateRequest} previously submitted with a call to
+ * {@link #requestBaseStateOverride(DeviceStateRequest, Executor, DeviceStateRequest.Callback)}.
+ * <p>
+ * This method is noop if there is no base state request currently active.
+ *
+ * @throws SecurityException if the caller does not hold the
+ * {@link android.Manifest.permission#CONTROL_DEVICE_STATE} permission.
+ */
+ @RequiresPermission(Manifest.permission.CONTROL_DEVICE_STATE)
+ public void cancelBaseStateOverride() {
+ mGlobal.cancelBaseStateOverride();
+ }
+
+ /**
* Registers a callback to receive notifications about changes in device state.
*
* @param executor the executor to process notifications.
diff --git a/core/java/android/hardware/devicestate/DeviceStateManagerGlobal.java b/core/java/android/hardware/devicestate/DeviceStateManagerGlobal.java
index aba538f51043..738045dafdf1 100644
--- a/core/java/android/hardware/devicestate/DeviceStateManagerGlobal.java
+++ b/core/java/android/hardware/devicestate/DeviceStateManagerGlobal.java
@@ -18,6 +18,7 @@ package android.hardware.devicestate;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
import android.content.Context;
import android.hardware.devicestate.DeviceStateManager.DeviceStateCallback;
import android.os.Binder;
@@ -81,6 +82,7 @@ public final class DeviceStateManagerGlobal {
@VisibleForTesting
public DeviceStateManagerGlobal(@NonNull IDeviceStateManager deviceStateManager) {
mDeviceStateManager = deviceStateManager;
+ registerCallbackIfNeededLocked();
}
/**
@@ -116,27 +118,22 @@ public final class DeviceStateManagerGlobal {
* DeviceStateRequest.Callback)
* @see DeviceStateRequest
*/
+ @RequiresPermission(value = android.Manifest.permission.CONTROL_DEVICE_STATE,
+ conditional = true)
public void requestState(@NonNull DeviceStateRequest request,
@Nullable Executor executor, @Nullable DeviceStateRequest.Callback callback) {
- if (callback == null && executor != null) {
- throw new IllegalArgumentException("Callback must be supplied with executor.");
- } else if (executor == null && callback != null) {
- throw new IllegalArgumentException("Executor must be supplied with callback.");
- }
-
+ DeviceStateRequestWrapper requestWrapper = new DeviceStateRequestWrapper(request, callback,
+ executor);
synchronized (mLock) {
- registerCallbackIfNeededLocked();
-
if (findRequestTokenLocked(request) != null) {
// This request has already been submitted.
return;
}
-
// Add the request wrapper to the mRequests array before requesting the state as the
// callback could be triggered immediately if the mDeviceStateManager IBinder is in the
// same process as this instance.
IBinder token = new Binder();
- mRequests.put(token, new DeviceStateRequestWrapper(request, callback, executor));
+ mRequests.put(token, requestWrapper);
try {
mDeviceStateManager.requestState(token, request.getState(), request.getFlags());
@@ -153,10 +150,10 @@ public final class DeviceStateManagerGlobal {
*
* @see DeviceStateManager#cancelStateRequest
*/
+ @RequiresPermission(value = android.Manifest.permission.CONTROL_DEVICE_STATE,
+ conditional = true)
public void cancelStateRequest() {
synchronized (mLock) {
- registerCallbackIfNeededLocked();
-
try {
mDeviceStateManager.cancelStateRequest();
} catch (RemoteException ex) {
@@ -166,6 +163,56 @@ public final class DeviceStateManagerGlobal {
}
/**
+ * Submits a {@link DeviceStateRequest request} to modify the base state of the device.
+ *
+ * @see DeviceStateManager#requestBaseStateOverride(DeviceStateRequest, Executor,
+ * DeviceStateRequest.Callback)
+ * @see DeviceStateRequest
+ */
+ @RequiresPermission(android.Manifest.permission.CONTROL_DEVICE_STATE)
+ public void requestBaseStateOverride(@NonNull DeviceStateRequest request,
+ @Nullable Executor executor, @Nullable DeviceStateRequest.Callback callback) {
+ DeviceStateRequestWrapper requestWrapper = new DeviceStateRequestWrapper(request, callback,
+ executor);
+ synchronized (mLock) {
+ if (findRequestTokenLocked(request) != null) {
+ // This request has already been submitted.
+ return;
+ }
+ // Add the request wrapper to the mRequests array before requesting the state as the
+ // callback could be triggered immediately if the mDeviceStateManager IBinder is in the
+ // same process as this instance.
+ IBinder token = new Binder();
+ mRequests.put(token, requestWrapper);
+
+ try {
+ mDeviceStateManager.requestBaseStateOverride(token, request.getState(),
+ request.getFlags());
+ } catch (RemoteException ex) {
+ mRequests.remove(token);
+ throw ex.rethrowFromSystemServer();
+ }
+ }
+ }
+
+ /**
+ * Cancels a {@link DeviceStateRequest request} previously submitted with a call to
+ * {@link #requestBaseStateOverride(DeviceStateRequest, Executor, DeviceStateRequest.Callback)}.
+ *
+ * @see DeviceStateManager#cancelBaseStateOverride
+ */
+ @RequiresPermission(android.Manifest.permission.CONTROL_DEVICE_STATE)
+ public void cancelBaseStateOverride() {
+ synchronized (mLock) {
+ try {
+ mDeviceStateManager.cancelBaseStateOverride();
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
+ }
+ }
+ }
+
+ /**
* Registers a callback to receive notifications about changes in device state.
*
* @see DeviceStateManager#registerCallback(Executor, DeviceStateCallback)
@@ -179,9 +226,6 @@ public final class DeviceStateManagerGlobal {
// This callback is already registered.
return;
}
-
- registerCallbackIfNeededLocked();
-
// Add the callback wrapper to the mCallbacks array after registering the callback as
// the callback could be triggered immediately if the mDeviceStateManager IBinder is in
// the same process as this instance.
@@ -357,6 +401,8 @@ public final class DeviceStateManagerGlobal {
DeviceStateRequestWrapper(@NonNull DeviceStateRequest request,
@Nullable DeviceStateRequest.Callback callback, @Nullable Executor executor) {
+ validateRequestWrapperParameters(callback, executor);
+
mRequest = request;
mCallback = callback;
mExecutor = executor;
@@ -377,5 +423,14 @@ public final class DeviceStateManagerGlobal {
mExecutor.execute(() -> mCallback.onRequestCanceled(mRequest));
}
+
+ private void validateRequestWrapperParameters(
+ @Nullable DeviceStateRequest.Callback callback, @Nullable Executor executor) {
+ if (callback == null && executor != null) {
+ throw new IllegalArgumentException("Callback must be supplied with executor.");
+ } else if (executor == null && callback != null) {
+ throw new IllegalArgumentException("Executor must be supplied with callback.");
+ }
+ }
}
}
diff --git a/core/java/android/hardware/devicestate/IDeviceStateManager.aidl b/core/java/android/hardware/devicestate/IDeviceStateManager.aidl
index e450e42497a0..7175eae58a26 100644
--- a/core/java/android/hardware/devicestate/IDeviceStateManager.aidl
+++ b/core/java/android/hardware/devicestate/IDeviceStateManager.aidl
@@ -41,6 +41,10 @@ interface IDeviceStateManager {
* previously registered with {@link #registerCallback(IDeviceStateManagerCallback)} before a
* call to this method.
*
+ * Requesting a state does not cancel a base state override made through
+ * {@link #requestBaseStateOverride}, but will still attempt to put the device into the
+ * supplied {@code state}.
+ *
* @param token the request token provided
* @param state the state of device the request is asking for
* @param flags any flags that correspond to the request
@@ -50,14 +54,53 @@ interface IDeviceStateManager {
* @throws IllegalStateException if the supplied {@code token} has already been registered.
* @throws IllegalArgumentException if the supplied {@code state} is not supported.
*/
+ @JavaPassthrough(annotation=
+ "@android.annotation.RequiresPermission(value=android.Manifest.permission.CONTROL_DEVICE_STATE, conditional=true)")
void requestState(IBinder token, int state, int flags);
/**
* Cancels the active request previously submitted with a call to
- * {@link #requestState(IBinder, int, int)}.
+ * {@link #requestState(IBinder, int, int)}. Will have no effect on any base state override that
+ * was previously requested with {@link #requestBaseStateOverride}.
*
* @throws IllegalStateException if a callback has not yet been registered for the calling
* process.
*/
+ @JavaPassthrough(annotation=
+ "@android.annotation.RequiresPermission(value=android.Manifest.permission.CONTROL_DEVICE_STATE, conditional=true)")
void cancelStateRequest();
+
+ /**
+ * Requests that the device's base state be overridden to the supplied {@code state}. A callback
+ * <b>MUST</b> have been previously registered with
+ * {@link #registerCallback(IDeviceStateManagerCallback)} before a call to this method.
+ *
+ * This method should only be used for testing, when you want to simulate the device physically
+ * changing states. If you are looking to change device state for a feature, where the system
+ * should still be aware that the physical state is different than the emulated state, use
+ * {@link #requestState}.
+ *
+ * @param token the request token provided
+ * @param state the state of device the request is asking for
+ * @param flags any flags that correspond to the request
+ *
+ * @throws IllegalStateException if a callback has not yet been registered for the calling
+ * process.
+ * @throws IllegalStateException if the supplied {@code token} has already been registered.
+ * @throws IllegalArgumentException if the supplied {@code state} is not supported.
+ */
+ @JavaPassthrough(annotation=
+ "@android.annotation.RequiresPermission(android.Manifest.permission.CONTROL_DEVICE_STATE)")
+ void requestBaseStateOverride(IBinder token, int state, int flags);
+
+ /**
+ * Cancels the active base state request previously submitted with a call to
+ * {@link #overrideBaseState(IBinder, int, int)}.
+ *
+ * @throws IllegalStateException if a callback has not yet been registered for the calling
+ * process.
+ */
+ @JavaPassthrough(annotation=
+ "@android.annotation.RequiresPermission(android.Manifest.permission.CONTROL_DEVICE_STATE)")
+ void cancelBaseStateOverride();
}