blob: 62c0ec9a2ce0846d07ce10220a49cc1e90c7e0d7 [file] [log] [blame]
Mike Lockwood3a322132009-11-24 00:30:52 -05001/*
2 * Copyright (C) 2008 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
Adam Lesinski182f73f2013-12-05 16:48:06 -080017package com.android.server.lights;
18
19import com.android.server.SystemService;
Mike Lockwood3a322132009-11-24 00:30:52 -050020
21import android.content.Context;
Mike Lockwoodeb9cbb82010-05-17 17:27:30 -040022import android.content.pm.PackageManager;
Mike Lockwood3a322132009-11-24 00:30:52 -050023import android.os.Handler;
Mike Lockwoodeb9cbb82010-05-17 17:27:30 -040024import android.os.IHardwareService;
Mike Lockwood3a322132009-11-24 00:30:52 -050025import android.os.Message;
Joe Onorato8a9b2202010-02-26 18:56:32 -080026import android.util.Slog;
Mike Lockwood3a322132009-11-24 00:30:52 -050027
Mike Lockwoodeb9cbb82010-05-17 17:27:30 -040028import java.io.FileInputStream;
29import java.io.FileOutputStream;
30
Adam Lesinski182f73f2013-12-05 16:48:06 -080031public class LightsService extends SystemService {
32 static final String TAG = "LightsService";
33 static final boolean DEBUG = false;
Mike Lockwood3a322132009-11-24 00:30:52 -050034
Adam Lesinski182f73f2013-12-05 16:48:06 -080035 final LightImpl mLights[] = new LightImpl[LightsManager.LIGHT_ID_COUNT];
Mike Lockwood3a322132009-11-24 00:30:52 -050036
Adam Lesinski182f73f2013-12-05 16:48:06 -080037 private final class LightImpl extends Light {
Mike Lockwood3a322132009-11-24 00:30:52 -050038
Adam Lesinski182f73f2013-12-05 16:48:06 -080039 private LightImpl(int id) {
Mike Lockwood3cb67a32009-11-27 14:25:58 -050040 mId = id;
41 }
42
Adam Lesinski182f73f2013-12-05 16:48:06 -080043 @Override
Mike Lockwood3cb67a32009-11-27 14:25:58 -050044 public void setBrightness(int brightness) {
45 setBrightness(brightness, BRIGHTNESS_MODE_USER);
46 }
47
Adam Lesinski182f73f2013-12-05 16:48:06 -080048 @Override
Mike Lockwood3cb67a32009-11-27 14:25:58 -050049 public void setBrightness(int brightness, int brightnessMode) {
50 synchronized (this) {
51 int color = brightness & 0x000000ff;
52 color = 0xff000000 | (color << 16) | (color << 8) | color;
53 setLightLocked(color, LIGHT_FLASH_NONE, 0, 0, brightnessMode);
54 }
55 }
56
Adam Lesinski182f73f2013-12-05 16:48:06 -080057 @Override
Mike Lockwood3cb67a32009-11-27 14:25:58 -050058 public void setColor(int color) {
59 synchronized (this) {
60 setLightLocked(color, LIGHT_FLASH_NONE, 0, 0, 0);
61 }
62 }
63
Adam Lesinski182f73f2013-12-05 16:48:06 -080064 @Override
Mike Lockwood3cb67a32009-11-27 14:25:58 -050065 public void setFlashing(int color, int mode, int onMS, int offMS) {
66 synchronized (this) {
67 setLightLocked(color, mode, onMS, offMS, BRIGHTNESS_MODE_USER);
68 }
69 }
70
Adam Lesinski182f73f2013-12-05 16:48:06 -080071 @Override
Mike Lockwood3cb67a32009-11-27 14:25:58 -050072 public void pulse() {
Mike Lockwood670f9322010-01-20 12:13:36 -050073 pulse(0x00ffffff, 7);
74 }
75
Adam Lesinski182f73f2013-12-05 16:48:06 -080076 @Override
Mike Lockwood670f9322010-01-20 12:13:36 -050077 public void pulse(int color, int onMS) {
Mike Lockwood3cb67a32009-11-27 14:25:58 -050078 synchronized (this) {
79 if (mColor == 0 && !mFlashing) {
Mike Lockwood670f9322010-01-20 12:13:36 -050080 setLightLocked(color, LIGHT_FLASH_HARDWARE, onMS, 1000, BRIGHTNESS_MODE_USER);
81 mH.sendMessageDelayed(Message.obtain(mH, 1, this), onMS);
Mike Lockwood3cb67a32009-11-27 14:25:58 -050082 }
83 }
84 }
85
Adam Lesinski182f73f2013-12-05 16:48:06 -080086 @Override
Mike Lockwood3cb67a32009-11-27 14:25:58 -050087 public void turnOff() {
88 synchronized (this) {
89 setLightLocked(0, LIGHT_FLASH_NONE, 0, 0, 0);
90 }
91 }
92
93 private void stopFlashing() {
94 synchronized (this) {
95 setLightLocked(mColor, LIGHT_FLASH_NONE, 0, 0, BRIGHTNESS_MODE_USER);
96 }
97 }
98
99 private void setLightLocked(int color, int mode, int onMS, int offMS, int brightnessMode) {
100 if (color != mColor || mode != mMode || onMS != mOnMS || offMS != mOffMS) {
Dianne Hackbornff801ec2011-01-22 18:05:38 -0800101 if (DEBUG) Slog.v(TAG, "setLight #" + mId + ": color=#"
102 + Integer.toHexString(color));
Mike Lockwood3cb67a32009-11-27 14:25:58 -0500103 mColor = color;
104 mMode = mode;
105 mOnMS = onMS;
106 mOffMS = offMS;
107 setLight_native(mNativePointer, mId, color, mode, onMS, offMS, brightnessMode);
108 }
109 }
110
111 private int mId;
112 private int mColor;
113 private int mMode;
114 private int mOnMS;
115 private int mOffMS;
116 private boolean mFlashing;
117 }
Mike Lockwood3a322132009-11-24 00:30:52 -0500118
Mike Lockwoodeb9cbb82010-05-17 17:27:30 -0400119 /* This class implements an obsolete API that was removed after eclair and re-added during the
120 * final moments of the froyo release to support flashlight apps that had been using the private
121 * IHardwareService API. This is expected to go away in the next release.
122 */
123 private final IHardwareService.Stub mLegacyFlashlightHack = new IHardwareService.Stub() {
124
125 private static final String FLASHLIGHT_FILE = "/sys/class/leds/spotlight/brightness";
126
127 public boolean getFlashlightEnabled() {
128 try {
129 FileInputStream fis = new FileInputStream(FLASHLIGHT_FILE);
130 int result = fis.read();
131 fis.close();
132 return (result != '0');
133 } catch (Exception e) {
Mike Lockwoodeb9cbb82010-05-17 17:27:30 -0400134 return false;
135 }
136 }
137
138 public void setFlashlightEnabled(boolean on) {
Adam Lesinski182f73f2013-12-05 16:48:06 -0800139 final Context context = getContext();
140 if (context.checkCallingOrSelfPermission(android.Manifest.permission.FLASHLIGHT)
Mike Lockwoodeb9cbb82010-05-17 17:27:30 -0400141 != PackageManager.PERMISSION_GRANTED &&
Adam Lesinski182f73f2013-12-05 16:48:06 -0800142 context.checkCallingOrSelfPermission(android.Manifest.permission.HARDWARE_TEST)
Mike Lockwoodeb9cbb82010-05-17 17:27:30 -0400143 != PackageManager.PERMISSION_GRANTED) {
144 throw new SecurityException("Requires FLASHLIGHT or HARDWARE_TEST permission");
145 }
146 try {
147 FileOutputStream fos = new FileOutputStream(FLASHLIGHT_FILE);
148 byte[] bytes = new byte[2];
149 bytes[0] = (byte)(on ? '1' : '0');
150 bytes[1] = '\n';
151 fos.write(bytes);
152 fos.close();
153 } catch (Exception e) {
Mike Lockwood35167d92011-03-28 20:29:14 -0700154 // fail silently
Mike Lockwoodeb9cbb82010-05-17 17:27:30 -0400155 }
156 }
157 };
158
Jeff Brownb880d882014-02-10 19:47:07 -0800159 public LightsService(Context context) {
160 super(context);
161
Mike Lockwood3a322132009-11-24 00:30:52 -0500162 mNativePointer = init_native();
Mike Lockwood3cb67a32009-11-27 14:25:58 -0500163
Adam Lesinski182f73f2013-12-05 16:48:06 -0800164 for (int i = 0; i < LightsManager.LIGHT_ID_COUNT; i++) {
165 mLights[i] = new LightImpl(i);
Mike Lockwood3cb67a32009-11-27 14:25:58 -0500166 }
Mike Lockwood3a322132009-11-24 00:30:52 -0500167 }
168
Adam Lesinski182f73f2013-12-05 16:48:06 -0800169 @Override
170 public void onStart() {
171 publishBinderService("hardware", mLegacyFlashlightHack);
172 publishLocalService(LightsManager.class, mService);
173 }
174
175 private final LightsManager mService = new LightsManager() {
176 @Override
177 public com.android.server.lights.Light getLight(int id) {
178 if (id < LIGHT_ID_COUNT) {
179 return mLights[id];
180 } else {
181 return null;
182 }
183 }
184 };
185
Jeff Brownb880d882014-02-10 19:47:07 -0800186 @Override
Mike Lockwood3a322132009-11-24 00:30:52 -0500187 protected void finalize() throws Throwable {
188 finalize_native(mNativePointer);
189 super.finalize();
190 }
191
Mike Lockwood3a322132009-11-24 00:30:52 -0500192 private Handler mH = new Handler() {
193 @Override
194 public void handleMessage(Message msg) {
Adam Lesinski182f73f2013-12-05 16:48:06 -0800195 LightImpl light = (LightImpl)msg.obj;
Mike Lockwood3cb67a32009-11-27 14:25:58 -0500196 light.stopFlashing();
Mike Lockwood3a322132009-11-24 00:30:52 -0500197 }
198 };
199
Ashok Bhat7e2a9dc2014-01-02 19:43:30 +0000200 private static native long init_native();
201 private static native void finalize_native(long ptr);
Mike Lockwood3a322132009-11-24 00:30:52 -0500202
Narayan Kamath3f7b8d02014-01-08 12:19:40 +0000203 static native void setLight_native(long ptr, int light, int color, int mode,
Mike Lockwood3a322132009-11-24 00:30:52 -0500204 int onMS, int offMS, int brightnessMode);
205
Ashok Bhat7e2a9dc2014-01-02 19:43:30 +0000206 private long mNativePointer;
Mike Lockwood3a322132009-11-24 00:30:52 -0500207}