1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.hardware.input;
18 
19 import android.annotation.NonNull;
20 import android.app.ActivityThread;
21 import android.hardware.lights.Light;
22 import android.hardware.lights.LightState;
23 import android.hardware.lights.LightsManager;
24 import android.hardware.lights.LightsRequest;
25 import android.util.CloseGuard;
26 
27 import com.android.internal.util.Preconditions;
28 
29 import java.lang.ref.Reference;
30 import java.util.List;
31 
32 /**
33  * LightsManager manages an input device's lights {@link android.hardware.lights.Light}
34  */
35 class InputDeviceLightsManager extends LightsManager {
36     private static final String TAG = "InputDeviceLightsManager";
37     private static final boolean DEBUG = false;
38 
39     private final InputManagerGlobal mGlobal;
40 
41     // The input device ID.
42     private final int mDeviceId;
43     // Package name
44     private final String mPackageName;
45 
InputDeviceLightsManager(int deviceId)46     InputDeviceLightsManager(int deviceId) {
47         mGlobal = InputManagerGlobal.getInstance();
48         mDeviceId = deviceId;
49         mPackageName = ActivityThread.currentPackageName();
50     }
51 
52     /**
53      * Returns the lights available on the device.
54      *
55      * @return A list of available lights
56      */
57     @Override
getLights()58     public @NonNull List<Light> getLights() {
59         return mGlobal.getLights(mDeviceId);
60     }
61 
62     /**
63      * Returns the state of a specified light.
64      *
65      * @hide
66      */
67     @Override
getLightState(@onNull Light light)68     public @NonNull LightState getLightState(@NonNull Light light) {
69         Preconditions.checkNotNull(light);
70         return mGlobal.getLightState(mDeviceId, light);
71     }
72 
73     /**
74      * Creates a new LightsSession that can be used to control the device lights.
75      */
76     @Override
openSession()77     public @NonNull LightsSession openSession() {
78         final LightsSession session = new InputDeviceLightsSession();
79         mGlobal.openLightSession(mDeviceId, mPackageName, session.getToken());
80         return session;
81     }
82 
83     @Override
openSession(int priority)84     public @NonNull LightsSession openSession(int priority) {
85         throw new UnsupportedOperationException();
86     }
87 
88     /**
89      * Encapsulates a session that can be used to control device lights and represents the lifetime
90      * of the requests.
91      */
92     public final class InputDeviceLightsSession extends LightsManager.LightsSession
93             implements AutoCloseable {
94 
95         private final CloseGuard mCloseGuard = new CloseGuard();
96         private boolean mClosed = false;
97 
98         /**
99          * Instantiated by {@link LightsManager#openSession()}.
100          */
InputDeviceLightsSession()101         private InputDeviceLightsSession() {
102             mCloseGuard.open("InputDeviceLightsSession.close");
103         }
104 
105         /**
106          * Sends a request to modify the states of multiple lights.
107          *
108          * @param request the settings for lights that should change
109          */
110         @Override
requestLights(@onNull LightsRequest request)111         public void requestLights(@NonNull LightsRequest request) {
112             Preconditions.checkNotNull(request);
113             Preconditions.checkArgument(!mClosed);
114 
115             mGlobal.requestLights(mDeviceId, request, getToken());
116         }
117 
118         /**
119          * Closes the session, reverting all changes made through it.
120          */
121         @Override
close()122         public void close() {
123             if (!mClosed) {
124                 mGlobal.closeLightSession(mDeviceId, getToken());
125                 mClosed = true;
126                 mCloseGuard.close();
127             }
128             Reference.reachabilityFence(this);
129         }
130 
131         /** @hide */
132         @Override
finalize()133         protected void finalize() throws Throwable {
134             try {
135                 mCloseGuard.warnIfOpen();
136                 close();
137             } finally {
138                 super.finalize();
139             }
140         }
141     }
142 
143 }
144