From 275f9e2912f29bf6f6bdef95c66df8bdc413e133 Mon Sep 17 00:00:00 2001 From: Philip Junker Date: Tue, 20 Apr 2021 17:54:20 +0200 Subject: [PATCH] Add TestApi to suppress other LightsSession clients Add TestApi LightsManager#openSession(int priority) to allow sorting of sessions by descending priority. Assuming priority 0 for public API LightsManager#openSession(). Bug: 185877106 Test: atest LightsManagerTest Change-Id: I4a2d9f8982119b47cbcbf77ff43377fecb343112 --- core/api/test-current.txt | 8 +++++++ .../input/InputDeviceLightsManager.java | 5 ++++ .../hardware/lights/ILightsManager.aidl | 2 +- .../hardware/lights/LightsManager.java | 14 +++++++++++ .../hardware/lights/SystemLightsManager.java | 23 +++++++++++++++++- .../android/server/lights/LightsService.java | 24 +++++++++++++------ 6 files changed, 67 insertions(+), 9 deletions(-) diff --git a/core/api/test-current.txt b/core/api/test-current.txt index b8edf41bb5c13..0163fc95996eb 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -1232,6 +1232,14 @@ package android.hardware.input { } +package android.hardware.lights { + + public abstract class LightsManager { + method @NonNull public abstract android.hardware.lights.LightsManager.LightsSession openSession(int); + } + +} + package android.hardware.soundtrigger { public class KeyphraseEnrollmentInfo { diff --git a/core/java/android/hardware/input/InputDeviceLightsManager.java b/core/java/android/hardware/input/InputDeviceLightsManager.java index a3b91a99fdb7a..885df7be25100 100644 --- a/core/java/android/hardware/input/InputDeviceLightsManager.java +++ b/core/java/android/hardware/input/InputDeviceLightsManager.java @@ -81,6 +81,11 @@ class InputDeviceLightsManager extends LightsManager { return session; } + @Override + public @NonNull LightsSession openSession(int priority) { + throw new UnsupportedOperationException(); + } + /** * Encapsulates a session that can be used to control device lights and represents the lifetime * of the requests. diff --git a/core/java/android/hardware/lights/ILightsManager.aidl b/core/java/android/hardware/lights/ILightsManager.aidl index 6ea24b74a4a35..077797f5b0f5d 100644 --- a/core/java/android/hardware/lights/ILightsManager.aidl +++ b/core/java/android/hardware/lights/ILightsManager.aidl @@ -27,7 +27,7 @@ import android.hardware.lights.LightState; interface ILightsManager { List getLights(); LightState getLightState(int lightId); - void openSession(in IBinder sessionToken); + void openSession(in IBinder sessionToken, in int priority); void closeSession(in IBinder sessionToken); void setLightStates(in IBinder sessionToken, in int[] lightIds, in LightState[] states); } diff --git a/core/java/android/hardware/lights/LightsManager.java b/core/java/android/hardware/lights/LightsManager.java index 8fd56db33c4be..8bc86dac0a8c1 100644 --- a/core/java/android/hardware/lights/LightsManager.java +++ b/core/java/android/hardware/lights/LightsManager.java @@ -20,6 +20,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.SystemApi; import android.annotation.SystemService; +import android.annotation.TestApi; import android.content.Context; import android.os.Binder; import android.os.IBinder; @@ -83,12 +84,25 @@ public abstract class LightsManager { */ public abstract @NonNull LightsSession openSession(); + /** + * + * Creates a new {@link LightsSession} + * + * @param priority the larger this number, the higher the priority of this session when multiple + * light state requests arrive simultaneously. + * + * @hide + */ + @TestApi + public abstract @NonNull LightsSession openSession(int priority); + /** * Encapsulates a session that can be used to control device lights and represents the lifetime * of the requests. */ public abstract static class LightsSession implements AutoCloseable { private final IBinder mToken = new Binder(); + /** * Sends a request to modify the states of multiple lights. * diff --git a/core/java/android/hardware/lights/SystemLightsManager.java b/core/java/android/hardware/lights/SystemLightsManager.java index 726a61359c01e..da034eefc09ad 100644 --- a/core/java/android/hardware/lights/SystemLightsManager.java +++ b/core/java/android/hardware/lights/SystemLightsManager.java @@ -102,7 +102,28 @@ public final class SystemLightsManager extends LightsManager { public @NonNull LightsSession openSession() { try { final LightsSession session = new SystemLightsSession(); - mService.openSession(session.getToken()); + mService.openSession(session.getToken(), 0); + return session; + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * + * Creates a new {@link LightsSession} + * + * @param priority the larger this number, the higher the priority of this session when multiple + * light state requests arrive simultaneously. + * + * @hide + */ + @RequiresPermission(Manifest.permission.CONTROL_DEVICE_LIGHTS) + @Override + public @NonNull LightsSession openSession(int priority) { + try { + final LightsSession session = new SystemLightsSession(); + mService.openSession(session.getToken(), priority); return session; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); diff --git a/services/core/java/com/android/server/lights/LightsService.java b/services/core/java/com/android/server/lights/LightsService.java index 42b0add6136e9..91f14de040fe4 100644 --- a/services/core/java/com/android/server/lights/LightsService.java +++ b/services/core/java/com/android/server/lights/LightsService.java @@ -46,6 +46,7 @@ import com.android.server.SystemService; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -68,12 +69,14 @@ public class LightsService extends SystemService { private final class LightsManagerBinderService extends ILightsManager.Stub { - private final class Session { + private final class Session implements Comparable { final IBinder mToken; final SparseArray mRequests = new SparseArray<>(); + final int mPriority; - Session(IBinder token) { + Session(IBinder token, int priority) { mToken = token; + mPriority = priority; } void setRequest(int lightId, LightState state) { @@ -83,6 +86,12 @@ public class LightsService extends SystemService { mRequests.remove(lightId); } } + + @Override + public int compareTo(Session otherSession) { + // Sort descending by priority + return Integer.compare(otherSession.mPriority, mPriority); + } } @GuardedBy("LightsService.this") @@ -150,7 +159,7 @@ public class LightsService extends SystemService { } @Override - public void openSession(IBinder token) { + public void openSession(IBinder token, int priority) { getContext().enforceCallingOrSelfPermission(Manifest.permission.CONTROL_DEVICE_LIGHTS, "openSession requires CONTROL_DEVICE_LIGHTS permission"); Preconditions.checkNotNull(token); @@ -159,7 +168,8 @@ public class LightsService extends SystemService { Preconditions.checkState(getSessionLocked(token) == null, "already registered"); try { token.linkToDeath(() -> closeSessionInternal(token), 0); - mSessions.add(new Session(token)); + mSessions.add(new Session(token, priority)); + Collections.sort(mSessions); } catch (RemoteException e) { Slog.e(TAG, "Couldn't open session, client already died" , e); throw new IllegalArgumentException("Client is already dead."); @@ -216,10 +226,10 @@ public class LightsService extends SystemService { } private void checkRequestIsValid(int[] lightIds) { - for (int i = 0; i < lightIds.length; i++) { - final LightImpl light = mLightsById.get(lightIds[i]); + for (int lightId : lightIds) { + final LightImpl light = mLightsById.get(lightId); Preconditions.checkState(light != null && !light.isSystemLight(), - "Invalid lightId " + lightIds[i]); + "Invalid lightId " + lightId); } }