• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 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 #define LOG_TAG "LightsService"
18 
19 #include "jni.h"
20 #include <nativehelper/JNIHelp.h>
21 #include "android_runtime/AndroidRuntime.h"
22 
23 #include <android/hardware/light/2.0/ILight.h>
24 #include <android/hardware/light/2.0/types.h>
25 #include <android-base/chrono_utils.h>
26 #include <utils/misc.h>
27 #include <utils/Log.h>
28 #include <map>
29 #include <stdio.h>
30 
31 namespace android {
32 
33 using Brightness = ::android::hardware::light::V2_0::Brightness;
34 using Flash      = ::android::hardware::light::V2_0::Flash;
35 using ILight     = ::android::hardware::light::V2_0::ILight;
36 using LightState = ::android::hardware::light::V2_0::LightState;
37 using Status     = ::android::hardware::light::V2_0::Status;
38 using Type       = ::android::hardware::light::V2_0::Type;
39 template<typename T>
40 using Return     = ::android::hardware::Return<T>;
41 
42 class LightHal {
43 private:
44     static sp<ILight> sLight;
45     static bool sLightInit;
46 
LightHal()47     LightHal() {}
48 
49 public:
disassociate()50     static void disassociate() {
51         sLightInit = false;
52         sLight = nullptr;
53     }
54 
associate()55     static sp<ILight> associate() {
56         if ((sLight == nullptr && !sLightInit) ||
57                 (sLight != nullptr && !sLight->ping().isOk())) {
58             // will return the hal if it exists the first time.
59             sLight = ILight::getService();
60             sLightInit = true;
61 
62             if (sLight == nullptr) {
63                 ALOGE("Unable to get ILight interface.");
64             }
65         }
66 
67         return sLight;
68     }
69 };
70 
71 sp<ILight> LightHal::sLight = nullptr;
72 bool LightHal::sLightInit = false;
73 
validate(jint light,jint flash,jint brightness)74 static bool validate(jint light, jint flash, jint brightness) {
75     bool valid = true;
76 
77     if (light < 0 || light >= static_cast<jint>(Type::COUNT)) {
78         ALOGE("Invalid light parameter %d.", light);
79         valid = false;
80     }
81 
82     if (flash != static_cast<jint>(Flash::NONE) &&
83         flash != static_cast<jint>(Flash::TIMED) &&
84         flash != static_cast<jint>(Flash::HARDWARE)) {
85         ALOGE("Invalid flash parameter %d.", flash);
86         valid = false;
87     }
88 
89     if (brightness != static_cast<jint>(Brightness::USER) &&
90         brightness != static_cast<jint>(Brightness::SENSOR) &&
91         brightness != static_cast<jint>(Brightness::LOW_PERSISTENCE)) {
92         ALOGE("Invalid brightness parameter %d.", brightness);
93         valid = false;
94     }
95 
96     if (brightness == static_cast<jint>(Brightness::LOW_PERSISTENCE) &&
97         light != static_cast<jint>(Type::BACKLIGHT)) {
98         ALOGE("Cannot set low-persistence mode for non-backlight device.");
99         valid = false;
100     }
101 
102     return valid;
103 }
104 
constructState(jint colorARGB,jint flashMode,jint onMS,jint offMS,jint brightnessMode)105 static LightState constructState(
106         jint colorARGB,
107         jint flashMode,
108         jint onMS,
109         jint offMS,
110         jint brightnessMode){
111     Flash flash = static_cast<Flash>(flashMode);
112     Brightness brightness = static_cast<Brightness>(brightnessMode);
113 
114     LightState state{};
115 
116     if (brightness == Brightness::LOW_PERSISTENCE) {
117         state.flashMode = Flash::NONE;
118     } else {
119         // Only set non-brightness settings when not in low-persistence mode
120         state.flashMode = flash;
121         state.flashOnMs = onMS;
122         state.flashOffMs = offMS;
123     }
124 
125     state.color = colorARGB;
126     state.brightnessMode = brightness;
127 
128     return state;
129 }
130 
processReturn(const Return<Status> & ret,Type type,const LightState & state)131 static void processReturn(
132         const Return<Status> &ret,
133         Type type,
134         const LightState &state) {
135     if (!ret.isOk()) {
136         ALOGE("Failed to issue set light command.");
137         LightHal::disassociate();
138         return;
139     }
140 
141     switch (static_cast<Status>(ret)) {
142         case Status::SUCCESS:
143             break;
144         case Status::LIGHT_NOT_SUPPORTED:
145             ALOGE("Light requested not available on this device. %d", type);
146             break;
147         case Status::BRIGHTNESS_NOT_SUPPORTED:
148             ALOGE("Brightness parameter not supported on this device: %d",
149                 state.brightnessMode);
150             break;
151         case Status::UNKNOWN:
152         default:
153             ALOGE("Unknown error setting light.");
154     }
155 }
156 
setLight_native(JNIEnv *,jobject,jint light,jint colorARGB,jint flashMode,jint onMS,jint offMS,jint brightnessMode)157 static void setLight_native(
158         JNIEnv* /* env */,
159         jobject /* clazz */,
160         jint light,
161         jint colorARGB,
162         jint flashMode,
163         jint onMS,
164         jint offMS,
165         jint brightnessMode) {
166 
167     if (!validate(light, flashMode, brightnessMode)) {
168         return;
169     }
170 
171     sp<ILight> hal = LightHal::associate();
172 
173     if (hal == nullptr) {
174         return;
175     }
176 
177     Type type = static_cast<Type>(light);
178     LightState state = constructState(
179         colorARGB, flashMode, onMS, offMS, brightnessMode);
180 
181     {
182         android::base::Timer t;
183         Return<Status> ret = hal->setLight(type, state);
184         processReturn(ret, type, state);
185         if (t.duration() > 50ms) ALOGD("Excessive delay setting light");
186     }
187 }
188 
189 static const JNINativeMethod method_table[] = {
190     { "setLight_native", "(IIIIII)V", (void*)setLight_native },
191 };
192 
register_android_server_LightsService(JNIEnv * env)193 int register_android_server_LightsService(JNIEnv *env) {
194     return jniRegisterNativeMethods(env, "com/android/server/lights/LightsService",
195             method_table, NELEM(method_table));
196 }
197 
198 };
199