Merge "Add TestApi to suppress other LightsSession clients" into sc-dev
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 0e6e8a5..5d51ff6 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1240,6 +1240,14 @@
}
+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 a3b91a9..885df7b 100644
--- a/core/java/android/hardware/input/InputDeviceLightsManager.java
+++ b/core/java/android/hardware/input/InputDeviceLightsManager.java
@@ -81,6 +81,11 @@
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 6ea24b7..077797f 100644
--- a/core/java/android/hardware/lights/ILightsManager.aidl
+++ b/core/java/android/hardware/lights/ILightsManager.aidl
@@ -27,7 +27,7 @@
interface ILightsManager {
List<Light> 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 8fd56db..8bc86da 100644
--- a/core/java/android/hardware/lights/LightsManager.java
+++ b/core/java/android/hardware/lights/LightsManager.java
@@ -20,6 +20,7 @@
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;
@@ -84,11 +85,24 @@
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 726a613..da034ee 100644
--- a/core/java/android/hardware/lights/SystemLightsManager.java
+++ b/core/java/android/hardware/lights/SystemLightsManager.java
@@ -102,7 +102,28 @@
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 42b0add..91f14de 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 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 @@
private final class LightsManagerBinderService extends ILightsManager.Stub {
- private final class Session {
+ private final class Session implements Comparable<Session> {
final IBinder mToken;
final SparseArray<LightState> 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 @@
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 @@
}
@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 @@
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 @@
}
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);
}
}