Merge "Add capabilities to android.hardware.lights.Light." into sc-dev am: b3d0a2afe3

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

Change-Id: I66c3b69bb7af59439555fc2875877c753419f657
This commit is contained in:
Chris Ye
2021-05-24 18:00:36 +00:00
committed by Automerger Merge Worker
9 changed files with 207 additions and 112 deletions

View File

@@ -18989,12 +18989,15 @@ package android.hardware.lights {
method @NonNull public String getName(); method @NonNull public String getName();
method public int getOrdinal(); method public int getOrdinal();
method public int getType(); method public int getType();
method public boolean hasBrightnessControl();
method public boolean hasRgbControl();
method public void writeToParcel(@NonNull android.os.Parcel, int); method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.hardware.lights.Light> CREATOR; field @NonNull public static final android.os.Parcelable.Creator<android.hardware.lights.Light> CREATOR;
field public static final int LIGHT_TYPE_INPUT_PLAYER_ID = 10002; // 0x2712 field public static final int LIGHT_CAPABILITY_BRIGHTNESS = 1; // 0x1
field public static final int LIGHT_TYPE_INPUT_RGB = 10003; // 0x2713 field public static final int LIGHT_CAPABILITY_RGB = 0; // 0x0
field public static final int LIGHT_TYPE_INPUT_SINGLE = 10001; // 0x2711 field public static final int LIGHT_TYPE_INPUT = 10001; // 0x2711
field public static final int LIGHT_TYPE_MICROPHONE = 8; // 0x8 field public static final int LIGHT_TYPE_MICROPHONE = 8; // 0x8
field public static final int LIGHT_TYPE_PLAYER_ID = 10002; // 0x2712
} }
public final class LightState implements android.os.Parcelable { public final class LightState implements android.os.Parcelable {
@@ -19026,7 +19029,7 @@ package android.hardware.lights {
public final class LightsRequest { public final class LightsRequest {
method @NonNull public java.util.List<android.hardware.lights.LightState> getLightStates(); method @NonNull public java.util.List<android.hardware.lights.LightState> getLightStates();
method @NonNull public java.util.List<java.lang.Integer> getLights(); method @NonNull public java.util.List<java.lang.Integer> getLights();
method @NonNull public java.util.Map<java.lang.Integer,android.hardware.lights.LightState> getLightsAndStates(); method @NonNull public java.util.Map<android.hardware.lights.Light,android.hardware.lights.LightState> getLightsAndStates();
} }
public static final class LightsRequest.Builder { public static final class LightsRequest.Builder {

View File

@@ -1204,6 +1204,10 @@ package android.hardware.input {
package android.hardware.lights { package android.hardware.lights {
public final class Light implements android.os.Parcelable {
method public int getCapabilities();
}
public abstract class LightsManager { public abstract class LightsManager {
method @NonNull public abstract android.hardware.lights.LightsManager.LightsSession openSession(int); method @NonNull public abstract android.hardware.lights.LightsManager.LightsSession openSession(int);
} }

View File

@@ -19,6 +19,7 @@ package android.hardware.lights;
import android.annotation.IntDef; import android.annotation.IntDef;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.annotation.TestApi;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
@@ -41,36 +42,52 @@ public final class Light implements Parcelable {
/** /**
* Type for lights that indicate a monochrome color LED light. * Type for lights that indicate a monochrome color LED light.
*/ */
public static final int LIGHT_TYPE_INPUT_SINGLE = 10001; public static final int LIGHT_TYPE_INPUT = 10001;
/** /**
* Type for lights that indicate a group of LED lights representing player ID. * Type for lights that indicate a group of LED lights representing player id.
* Player ID lights normally present on game controllers are lights that consist of a row of * Player id lights normally present on game controllers are lights that consist of a row of
* LEDs. * LEDs.
* During multi-player game, the player ID for the current game controller is represented by * During multi-player game, the player id for the current game controller is represented by
* one of the LED that is lit according to its position in the row. * one of the LED that is lit according to its position in the row.
*/ */
public static final int LIGHT_TYPE_INPUT_PLAYER_ID = 10002; public static final int LIGHT_TYPE_PLAYER_ID = 10002;
/** /**
* Type for lights that indicate a color LED light. * Capability for lights that could adjust its LED brightness. If the capability is not present
* the led can only be turned either on or off.
*/ */
public static final int LIGHT_TYPE_INPUT_RGB = 10003; public static final int LIGHT_CAPABILITY_BRIGHTNESS = 1 << 0;
/**
* Capability for lights that has red, green and blue LEDs to control the light's color.
*/
public static final int LIGHT_CAPABILITY_RGB = 0 << 1;
/** @hide */ /** @hide */
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = {"LIGHT_TYPE_"}, @IntDef(prefix = {"LIGHT_TYPE_"},
value = { value = {
LIGHT_TYPE_INPUT_PLAYER_ID, LIGHT_TYPE_MICROPHONE,
LIGHT_TYPE_INPUT_SINGLE, LIGHT_TYPE_INPUT,
LIGHT_TYPE_INPUT_RGB, LIGHT_TYPE_PLAYER_ID,
}) })
public @interface LightType {} public @interface LightType {}
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true, prefix = {"LIGHT_CAPABILITY_"},
value = {
LIGHT_CAPABILITY_BRIGHTNESS,
LIGHT_CAPABILITY_RGB,
})
public @interface LightCapability {}
private final int mId; private final int mId;
private final String mName;
private final int mOrdinal; private final int mOrdinal;
private final int mType; private final int mType;
private final String mName; private final int mCapabilities;
/** /**
* Creates a new light with the given data. * Creates a new light with the given data.
@@ -78,7 +95,7 @@ public final class Light implements Parcelable {
* @hide * @hide
*/ */
public Light(int id, int ordinal, int type) { public Light(int id, int ordinal, int type) {
this(id, ordinal, type, "Light"); this(id, "Light", ordinal, type, 0);
} }
/** /**
@@ -86,27 +103,30 @@ public final class Light implements Parcelable {
* *
* @hide * @hide
*/ */
public Light(int id, int ordinal, int type, String name) { public Light(int id, String name, int ordinal, int type, int capabilities) {
mId = id; mId = id;
mName = name;
mOrdinal = ordinal; mOrdinal = ordinal;
mType = type; mType = type;
mName = name; mCapabilities = capabilities;
} }
private Light(@NonNull Parcel in) { private Light(@NonNull Parcel in) {
mId = in.readInt(); mId = in.readInt();
mName = in.readString();
mOrdinal = in.readInt(); mOrdinal = in.readInt();
mType = in.readInt(); mType = in.readInt();
mName = in.readString(); mCapabilities = in.readInt();
} }
/** Implement the Parcelable interface */ /** Implement the Parcelable interface */
@Override @Override
public void writeToParcel(@NonNull Parcel dest, int flags) { public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeInt(mId); dest.writeInt(mId);
dest.writeString(mName);
dest.writeInt(mOrdinal); dest.writeInt(mOrdinal);
dest.writeInt(mType); dest.writeInt(mType);
dest.writeString(mName); dest.writeInt(mCapabilities);
} }
/** Implement the Parcelable interface */ /** Implement the Parcelable interface */
@@ -131,7 +151,8 @@ public final class Light implements Parcelable {
public boolean equals(@Nullable Object obj) { public boolean equals(@Nullable Object obj) {
if (obj instanceof Light) { if (obj instanceof Light) {
Light light = (Light) obj; Light light = (Light) obj;
return mId == light.mId && mOrdinal == light.mOrdinal && mType == light.mType; return mId == light.mId && mOrdinal == light.mOrdinal && mType == light.mType
&& mCapabilities == light.mCapabilities;
} }
return false; return false;
} }
@@ -143,7 +164,8 @@ public final class Light implements Parcelable {
@Override @Override
public String toString() { public String toString() {
return "[Name=" + mName + " Id=" + mId + " Type=" + mType + " Ordinal=" + mOrdinal + "]"; return "[Name=" + mName + " Id=" + mId + " Type=" + mType + " Capabilities="
+ mCapabilities + " Ordinal=" + mOrdinal + "]";
} }
/** /**
@@ -177,7 +199,35 @@ public final class Light implements Parcelable {
/** /**
* Returns the logical type of the light. * Returns the logical type of the light.
*/ */
public @LightsManager.LightType int getType() { public @LightType int getType() {
return mType; return mType;
} }
/**
* Returns the capabilities of the light.
* @hide
*/
@TestApi
public @LightCapability int getCapabilities() {
return mCapabilities;
}
/**
* Check whether the light has led brightness control.
*
* @return True if the hardware can control the led brightness, otherwise false.
*/
public boolean hasBrightnessControl() {
return (mCapabilities & LIGHT_CAPABILITY_BRIGHTNESS) == LIGHT_CAPABILITY_BRIGHTNESS;
}
/**
* Check whether the light has RGB led control.
*
* @return True if the hardware can control the RGB led, otherwise false.
*/
public boolean hasRgbControl() {
return (mCapabilities & LIGHT_CAPABILITY_RGB) == LIGHT_CAPABILITY_RGB;
}
} }

View File

@@ -43,7 +43,7 @@ public final class LightState implements Parcelable {
* of RBG color or monochrome color. * of RBG color or monochrome color.
* *
* @param color the desired color and intensity in ARGB format. * @param color the desired color and intensity in ARGB format.
* @deprecated this has been replaced with {@link android.hardware.lights.LightState#forColor } * @deprecated this has been replaced with {@link android.hardware.lights.LightState.Builder }
* @hide * @hide
*/ */
@Deprecated @Deprecated
@@ -54,8 +54,8 @@ public final class LightState implements Parcelable {
/** /**
* Creates a new LightState with the desired color and intensity, and the player Id. * Creates a new LightState with the desired color and intensity, and the player Id.
* Player Id will only be applied on Light type * Player Id will only be applied on Light with type
* {@link android.hardware.lights.Light#LIGHT_TYPE_INPUT_PLAYER_ID} * {@link android.hardware.lights.Light#LIGHT_TYPE_PLAYER_ID}
* *
* @param color the desired color and intensity in ARGB format. * @param color the desired color and intensity in ARGB format.
* @hide * @hide
@@ -94,8 +94,8 @@ public final class LightState implements Parcelable {
} }
/** /**
* Set the desired player id of the LightState Builder, for a light of type * Set the desired player id of the LightState Builder, for a light with type
* {@link android.hardware.lights.Light#LIGHT_TYPE_INPUT_PLAYER_ID}. * {@link android.hardware.lights.Light#LIGHT_TYPE_PLAYER_ID}.
* *
* @param playerId the desired player id. * @param playerId the desired player id.
* @return The {@link LightState.Builder} object contains the player id. * @return The {@link LightState.Builder} object contains the player id.
@@ -134,15 +134,16 @@ public final class LightState implements Parcelable {
/** /**
* Returns the color and intensity associated with this LightState. * Returns the color and intensity associated with this LightState.
* @return the color and intensity in ARGB format. The A channel is ignored. return 0 when * @return the color and intensity in ARGB format. The A channel is ignored. return 0 when
* calling LightsManager.getLightState with LIGHT_TYPE_INPUT_PLAYER_ID. * calling LightsManager.getLightState with
* {@link android.hardware.lights.Light#LIGHT_TYPE_PLAYER_ID}.
*/ */
public @ColorInt int getColor() { public @ColorInt int getColor() {
return mColor; return mColor;
} }
/** /**
* Returns the player ID associated with this LightState for Light type * Returns the player ID associated with this LightState for Light with type
* {@link android.hardware.lights.Light#LIGHT_TYPE_INPUT_PLAYER_ID}, * {@link android.hardware.lights.Light#LIGHT_TYPE_PLAYER_ID},
* or 0 for other types. * or 0 for other types.
* @return the player ID. * @return the player ID.
*/ */

View File

@@ -18,12 +18,10 @@ package android.hardware.lights;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.SystemApi; import android.annotation.SystemApi;
import android.util.SparseArray;
import com.android.internal.util.Preconditions; import com.android.internal.util.Preconditions;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -34,58 +32,48 @@ import java.util.Map;
public final class LightsRequest { public final class LightsRequest {
/** Visible to {@link LightsManager.Session}. */ /** Visible to {@link LightsManager.Session}. */
final int[] mLightIds; final Map<Light, LightState> mRequests = new HashMap<>();
final List<Integer> mLightIds = new ArrayList<>();
/** Visible to {@link LightsManager.Session}. */ final List<LightState> mLightStates = new ArrayList<>();
final LightState[] mLightStates;
/** /**
* Can only be constructed via {@link LightsRequest.Builder#build()}. * Can only be constructed via {@link LightsRequest.Builder#build()}.
*/ */
private LightsRequest(SparseArray<LightState> changes) { private LightsRequest(Map<Light, LightState> requests) {
final int n = changes.size(); mRequests.putAll(requests);
mLightIds = new int[n]; List<Light> lights = new ArrayList<Light>(mRequests.keySet());
mLightStates = new LightState[n]; for (int i = 0; i < lights.size(); i++) {
for (int i = 0; i < n; i++) { final Light light = lights.get(i);
mLightIds[i] = changes.keyAt(i); mLightIds.add(i, light.getId());
mLightStates[i] = changes.valueAt(i); mLightStates.add(i, mRequests.get(light));
} }
} }
/** /**
* Get a list of Light as ids. The ids will returned in same order as the lights passed * Get a list of Light as ids.
* in Builder.
* *
* @return List of light ids * @return List of light ids in the request.
*/ */
public @NonNull List<Integer> getLights() { public @NonNull List<Integer> getLights() {
List<Integer> lightList = new ArrayList<Integer>(mLightIds.length); return mLightIds;
for (int i = 0; i < mLightIds.length; i++) {
lightList.add(mLightIds[i]);
}
return lightList;
} }
/** /**
* Get a list of LightState. The states will be returned in same order as the light states * Get a list of LightState. The states will be returned in same order as the light ids
* passed in Builder. * returned by {@link #getLights()}.
* *
* @return List of light states * @return List of light states
*/ */
public @NonNull List<LightState> getLightStates() { public @NonNull List<LightState> getLightStates() {
return Arrays.asList(mLightStates); return mLightStates;
} }
/** /**
* Get a map of light ids and states. The map will contain all the light ids as keys and * Get a map of lights and states. The map will contain all the lights as keys and
* the corresponding LightState requested as values. * the corresponding LightState requested as values.
*/ */
public @NonNull Map<Integer, LightState> getLightsAndStates() { public @NonNull Map<Light, LightState> getLightsAndStates() {
Map<Integer, LightState> map = new HashMap<>(); return mRequests;
for (int i = 0; i < mLightIds.length; i++) {
map.put(mLightIds[i], mLightStates[i]);
}
return map;
} }
/** /**
@@ -93,8 +81,7 @@ public final class LightsRequest {
*/ */
public static final class Builder { public static final class Builder {
private final SparseArray<LightState> mChanges = new SparseArray<>(); final Map<Light, LightState> mChanges = new HashMap<>();
/** /**
* Overrides the color and intensity of a given light. * Overrides the color and intensity of a given light.
* *
@@ -104,7 +91,7 @@ public final class LightsRequest {
public @NonNull Builder addLight(@NonNull Light light, @NonNull LightState state) { public @NonNull Builder addLight(@NonNull Light light, @NonNull LightState state) {
Preconditions.checkNotNull(light); Preconditions.checkNotNull(light);
Preconditions.checkNotNull(state); Preconditions.checkNotNull(state);
mChanges.put(light.getId(), state); mChanges.put(light, state);
return this; return this;
} }
@@ -129,7 +116,7 @@ public final class LightsRequest {
*/ */
public @NonNull Builder clearLight(@NonNull Light light) { public @NonNull Builder clearLight(@NonNull Light light) {
Preconditions.checkNotNull(light); Preconditions.checkNotNull(light);
mChanges.put(light.getId(), null); mChanges.put(light, null);
return this; return this;
} }

View File

@@ -163,7 +163,17 @@ public final class SystemLightsManager extends LightsManager {
Preconditions.checkNotNull(request); Preconditions.checkNotNull(request);
if (!mClosed) { if (!mClosed) {
try { try {
mService.setLightStates(getToken(), request.mLightIds, request.mLightStates); List<Integer> idList = request.getLights();
List<LightState> stateList = request.getLightStates();
int[] ids = new int[idList.size()];
for (int i = 0; i < idList.size(); i++) {
ids[i] = idList.get(i);
}
LightState[] states = new LightState[stateList.size()];
for (int i = 0; i < stateList.size(); i++) {
states[i] = stateList.get(i);
}
mService.setLightStates(getToken(), ids, states);
} catch (RemoteException e) { } catch (RemoteException e) {
throw e.rethrowFromSystemServer(); throw e.rethrowFromSystemServer();
} }

View File

@@ -23,6 +23,8 @@ import static com.google.common.truth.Truth.assertThat;
import static junit.framework.TestCase.assertEquals; import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertNotNull; import static junit.framework.TestCase.assertNotNull;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
@@ -128,9 +130,12 @@ public class InputDeviceLightsManagerTest {
assertNotNull(device); assertNotNull(device);
Light[] mockedLights = { Light[] mockedLights = {
new Light(1 /* id */, 0 /* ordinal */, Light.LIGHT_TYPE_INPUT_SINGLE), new Light(1 /* id */, "Light1", 0 /* ordinal */, Light.LIGHT_TYPE_INPUT,
new Light(2 /* id */, 0 /* ordinal */, Light.LIGHT_TYPE_INPUT_RGB), Light.LIGHT_CAPABILITY_BRIGHTNESS),
new Light(3 /* id */, 0 /* ordinal */, Light.LIGHT_TYPE_INPUT_PLAYER_ID) new Light(2 /* id */, "Light2", 0 /* ordinal */, Light.LIGHT_TYPE_INPUT,
Light.LIGHT_CAPABILITY_RGB),
new Light(3 /* id */, "Light3", 0 /* ordinal */, Light.LIGHT_TYPE_INPUT,
0 /* capabilities */)
}; };
mockLights(mockedLights); mockLights(mockedLights);
@@ -146,10 +151,14 @@ public class InputDeviceLightsManagerTest {
assertNotNull(device); assertNotNull(device);
Light[] mockedLights = { Light[] mockedLights = {
new Light(1 /* id */, 0 /* ordinal */, Light.LIGHT_TYPE_INPUT_RGB), new Light(1 /* id */, "Light1", 0 /* ordinal */, Light.LIGHT_TYPE_INPUT,
new Light(2 /* id */, 0 /* ordinal */, Light.LIGHT_TYPE_INPUT_RGB), Light.LIGHT_CAPABILITY_RGB),
new Light(3 /* id */, 0 /* ordinal */, Light.LIGHT_TYPE_INPUT_RGB), new Light(2 /* id */, "Light2", 0 /* ordinal */, Light.LIGHT_TYPE_INPUT,
new Light(4 /* id */, 0 /* ordinal */, Light.LIGHT_TYPE_INPUT_RGB) Light.LIGHT_CAPABILITY_RGB),
new Light(3 /* id */, "Light3", 0 /* ordinal */, Light.LIGHT_TYPE_INPUT,
Light.LIGHT_CAPABILITY_RGB),
new Light(4 /* id */, "Light4", 0 /* ordinal */, Light.LIGHT_TYPE_INPUT,
Light.LIGHT_CAPABILITY_RGB)
}; };
mockLights(mockedLights); mockLights(mockedLights);
@@ -194,9 +203,12 @@ public class InputDeviceLightsManagerTest {
assertNotNull(device); assertNotNull(device);
Light[] mockedLights = { Light[] mockedLights = {
new Light(1 /* id */, 0 /* ordinal */, Light.LIGHT_TYPE_INPUT_PLAYER_ID), new Light(1 /* id */, "Light1", 0 /* ordinal */, Light.LIGHT_TYPE_PLAYER_ID,
new Light(2 /* id */, 0 /* ordinal */, Light.LIGHT_TYPE_INPUT_SINGLE), 0 /* capabilities */),
new Light(3 /* id */, 0 /* ordinal */, Light.LIGHT_TYPE_INPUT_RGB), new Light(2 /* id */, "Light2", 0 /* ordinal */, Light.LIGHT_TYPE_INPUT,
Light.LIGHT_CAPABILITY_RGB | Light.LIGHT_CAPABILITY_BRIGHTNESS),
new Light(3 /* id */, "Light3", 0 /* ordinal */, Light.LIGHT_TYPE_INPUT,
Light.LIGHT_CAPABILITY_BRIGHTNESS)
}; };
mockLights(mockedLights); mockLights(mockedLights);
@@ -226,24 +238,43 @@ public class InputDeviceLightsManagerTest {
verify(mIInputManagerMock).closeLightSession(eq(DEVICE_ID), eq(token)); verify(mIInputManagerMock).closeLightSession(eq(DEVICE_ID), eq(token));
} }
@Test
public void testLightCapabilities() throws Exception {
Light light = new Light(1 /* id */, "Light1", 0 /* ordinal */, Light.LIGHT_TYPE_INPUT,
Light.LIGHT_CAPABILITY_RGB | Light.LIGHT_CAPABILITY_BRIGHTNESS);
assertThat(light.getType()).isEqualTo(Light.LIGHT_TYPE_INPUT);
assertThat(light.getCapabilities()).isEqualTo(Light.LIGHT_CAPABILITY_RGB
| Light.LIGHT_CAPABILITY_BRIGHTNESS);
assertTrue(light.hasBrightnessControl());
assertTrue(light.hasRgbControl());
}
@Test @Test
public void testLightsRequest() throws Exception { public void testLightsRequest() throws Exception {
Light light = new Light(1 /* id */, 0 /* ordinal */, Light.LIGHT_TYPE_INPUT_PLAYER_ID); Light light1 = new Light(1 /* id */, "Light1", 0 /* ordinal */, Light.LIGHT_TYPE_INPUT,
LightState state = new LightState(0xf1); 0 /* capabilities */);
LightsRequest request = new Builder().addLight(light, state).build(); Light light2 = new Light(2 /* id */, "Light2", 0 /* ordinal */, Light.LIGHT_TYPE_PLAYER_ID,
0 /* capabilities */);
LightState state1 = new LightState(0xf1);
LightState state2 = new LightState(0xf2, PLAYER_ID);
LightsRequest request = new Builder().addLight(light1, state1)
.addLight(light2, state2).build();
// Covers the LightsRequest.getLights // Covers the LightsRequest.getLights
assertThat(request.getLights().size()).isEqualTo(1); assertThat(request.getLights().size()).isEqualTo(2);
assertThat(request.getLights().get(0)).isEqualTo(1); assertThat(request.getLights().get(0)).isEqualTo(1);
assertThat(request.getLights().get(1)).isEqualTo(2);
// Covers the LightsRequest.getLightStates // Covers the LightsRequest.getLightStates
assertThat(request.getLightStates().size()).isEqualTo(1); assertThat(request.getLightStates().size()).isEqualTo(2);
assertThat(request.getLightStates().get(0)).isEqualTo(state); assertThat(request.getLightStates().get(0)).isEqualTo(state1);
assertThat(request.getLightStates().get(1)).isEqualTo(state2);
// Covers the LightsRequest.getLightsAndStates // Covers the LightsRequest.getLightsAndStates
assertThat(request.getLightsAndStates().size()).isEqualTo(1); assertThat(request.getLightsAndStates().size()).isEqualTo(2);
assertThat(request.getLightsAndStates().containsKey(1)).isTrue(); assertThat(request.getLightsAndStates().containsKey(light1)).isTrue();
assertThat(request.getLightsAndStates().get(1)).isEqualTo(state); assertThat(request.getLightsAndStates().get(light1)).isEqualTo(state1);
assertThat(request.getLightsAndStates().get(light2)).isEqualTo(state2);
} }
} }

View File

@@ -2479,15 +2479,12 @@ public class InputManagerService extends IInputManager.Stub
Slog.d(TAG, "setLightStateInternal device " + deviceId + " light " + light Slog.d(TAG, "setLightStateInternal device " + deviceId + " light " + light
+ "lightState " + lightState); + "lightState " + lightState);
} }
if (light.getType() == Light.LIGHT_TYPE_INPUT_PLAYER_ID) { if (light.getType() == Light.LIGHT_TYPE_PLAYER_ID) {
nativeSetLightPlayerId(mPtr, deviceId, light.getId(), lightState.getPlayerId()); nativeSetLightPlayerId(mPtr, deviceId, light.getId(), lightState.getPlayerId());
} else if (light.getType() == Light.LIGHT_TYPE_INPUT_SINGLE } else {
|| light.getType() == Light.LIGHT_TYPE_INPUT_RGB) {
// Set ARGB format color to input device light // Set ARGB format color to input device light
// Refer to https://developer.android.com/reference/kotlin/android/graphics/Color // Refer to https://developer.android.com/reference/kotlin/android/graphics/Color
nativeSetLightColor(mPtr, deviceId, light.getId(), lightState.getColor()); nativeSetLightColor(mPtr, deviceId, light.getId(), lightState.getColor());
} else {
Slog.e(TAG, "setLightStates for unsupported light type " + light.getType());
} }
} }

View File

@@ -160,9 +160,10 @@ static struct {
static struct { static struct {
jclass clazz; jclass clazz;
jmethodID constructor; jmethodID constructor;
jfieldID lightTypeSingle; jfieldID lightTypeInput;
jfieldID lightTypePlayerId; jfieldID lightTypePlayerId;
jfieldID lightTypeRgb; jfieldID lightCapabilityBrightness;
jfieldID lightCapabilityRgb;
} gLightClassInfo; } gLightClassInfo;
static struct { static struct {
@@ -1996,25 +1997,34 @@ static jobject nativeGetLights(JNIEnv* env, jclass clazz, jlong ptr, jint device
continue; continue;
} }
jint jTypeId = 0; jint jTypeId =
if (lightInfo->type == InputDeviceLightType::SINGLE) { env->GetStaticIntField(gLightClassInfo.clazz, gLightClassInfo.lightTypeInput);
jTypeId = jint jCapability = 0;
env->GetStaticIntField(gLightClassInfo.clazz, gLightClassInfo.lightTypeSingle);
} else if (lightInfo->type == InputDeviceLightType::PLAYER_ID) { if (lightInfo->type == InputDeviceLightType::MONO) {
jTypeId = env->GetStaticIntField(gLightClassInfo.clazz, jCapability = env->GetStaticIntField(gLightClassInfo.clazz,
gLightClassInfo.lightTypePlayerId); gLightClassInfo.lightCapabilityBrightness);
} else if (lightInfo->type == InputDeviceLightType::RGB || } else if (lightInfo->type == InputDeviceLightType::RGB ||
lightInfo->type == InputDeviceLightType::MULTI_COLOR) { lightInfo->type == InputDeviceLightType::MULTI_COLOR) {
jTypeId = env->GetStaticIntField(gLightClassInfo.clazz, gLightClassInfo.lightTypeRgb); jCapability =
env->GetStaticIntField(gLightClassInfo.clazz,
gLightClassInfo.lightCapabilityBrightness) |
env->GetStaticIntField(gLightClassInfo.clazz,
gLightClassInfo.lightCapabilityRgb);
} else if (lightInfo->type == InputDeviceLightType::PLAYER_ID) {
jTypeId = env->GetStaticIntField(gLightClassInfo.clazz,
gLightClassInfo.lightTypePlayerId);
} else { } else {
ALOGW("Unknown light type %d", lightInfo->type); ALOGW("Unknown light type %d", lightInfo->type);
continue; continue;
} }
ScopedLocalRef<jobject> ScopedLocalRef<jobject> lightObj(env,
lightObj(env, env->NewObject(gLightClassInfo.clazz,
env->NewObject(gLightClassInfo.clazz, gLightClassInfo.constructor, gLightClassInfo.constructor,
(jint)lightInfo->id, (jint)lightInfo->ordinal, jTypeId, static_cast<jint>(lightInfo->id),
env->NewStringUTF(lightInfo->name.c_str()))); env->NewStringUTF(lightInfo->name.c_str()),
static_cast<jint>(lightInfo->ordinal),
jTypeId, jCapability));
// Add light object to list // Add light object to list
env->CallBooleanMethod(jLights, gArrayListClassInfo.add, lightObj.get()); env->CallBooleanMethod(jLights, gArrayListClassInfo.add, lightObj.get());
} }
@@ -2540,15 +2550,17 @@ int register_android_server_InputManager(JNIEnv* env) {
FIND_CLASS(gLightClassInfo.clazz, "android/hardware/lights/Light"); FIND_CLASS(gLightClassInfo.clazz, "android/hardware/lights/Light");
gLightClassInfo.clazz = jclass(env->NewGlobalRef(gLightClassInfo.clazz)); gLightClassInfo.clazz = jclass(env->NewGlobalRef(gLightClassInfo.clazz));
GET_METHOD_ID(gLightClassInfo.constructor, gLightClassInfo.clazz, "<init>", GET_METHOD_ID(gLightClassInfo.constructor, gLightClassInfo.clazz, "<init>",
"(IIILjava/lang/String;)V"); "(ILjava/lang/String;III)V");
gLightClassInfo.clazz = jclass(env->NewGlobalRef(gLightClassInfo.clazz)); gLightClassInfo.clazz = jclass(env->NewGlobalRef(gLightClassInfo.clazz));
gLightClassInfo.lightTypeSingle = gLightClassInfo.lightTypeInput =
env->GetStaticFieldID(gLightClassInfo.clazz, "LIGHT_TYPE_INPUT_SINGLE", "I"); env->GetStaticFieldID(gLightClassInfo.clazz, "LIGHT_TYPE_INPUT", "I");
gLightClassInfo.lightTypePlayerId = gLightClassInfo.lightTypePlayerId =
env->GetStaticFieldID(gLightClassInfo.clazz, "LIGHT_TYPE_INPUT_PLAYER_ID", "I"); env->GetStaticFieldID(gLightClassInfo.clazz, "LIGHT_TYPE_PLAYER_ID", "I");
gLightClassInfo.lightTypeRgb = gLightClassInfo.lightCapabilityBrightness =
env->GetStaticFieldID(gLightClassInfo.clazz, "LIGHT_TYPE_INPUT_RGB", "I"); env->GetStaticFieldID(gLightClassInfo.clazz, "LIGHT_CAPABILITY_BRIGHTNESS", "I");
gLightClassInfo.lightCapabilityRgb =
env->GetStaticFieldID(gLightClassInfo.clazz, "LIGHT_CAPABILITY_RGB", "I");
// ArrayList // ArrayList
FIND_CLASS(gArrayListClassInfo.clazz, "java/util/ArrayList"); FIND_CLASS(gArrayListClassInfo.clazz, "java/util/ArrayList");