• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package com.android.server;
18 
19 import android.content.Context;
20 import android.content.pm.PackageManager;
21 import android.os.Handler;
22 import android.os.IHardwareService;
23 import android.os.ServiceManager;
24 import android.os.Message;
25 import android.util.Slog;
26 
27 import java.io.FileInputStream;
28 import java.io.FileOutputStream;
29 
30 public class LightsService {
31     private static final String TAG = "LightsService";
32     private static final boolean DEBUG = false;
33 
34     static final int LIGHT_ID_BACKLIGHT = 0;
35     static final int LIGHT_ID_KEYBOARD = 1;
36     static final int LIGHT_ID_BUTTONS = 2;
37     static final int LIGHT_ID_BATTERY = 3;
38     static final int LIGHT_ID_NOTIFICATIONS = 4;
39     static final int LIGHT_ID_ATTENTION = 5;
40     static final int LIGHT_ID_BLUETOOTH = 6;
41     static final int LIGHT_ID_WIFI = 7;
42     static final int LIGHT_ID_COUNT = 8;
43 
44     static final int LIGHT_FLASH_NONE = 0;
45     static final int LIGHT_FLASH_TIMED = 1;
46     static final int LIGHT_FLASH_HARDWARE = 2;
47 
48     /**
49      * Light brightness is managed by a user setting.
50      */
51     static final int BRIGHTNESS_MODE_USER = 0;
52 
53     /**
54      * Light brightness is managed by a light sensor.
55      */
56     static final int BRIGHTNESS_MODE_SENSOR = 1;
57 
58     private final Light mLights[] = new Light[LIGHT_ID_COUNT];
59 
60     public final class Light {
61 
Light(int id)62         private Light(int id) {
63             mId = id;
64         }
65 
setBrightness(int brightness)66         public void setBrightness(int brightness) {
67             setBrightness(brightness, BRIGHTNESS_MODE_USER);
68         }
69 
setBrightness(int brightness, int brightnessMode)70         public void setBrightness(int brightness, int brightnessMode) {
71             synchronized (this) {
72                 int color = brightness & 0x000000ff;
73                 color = 0xff000000 | (color << 16) | (color << 8) | color;
74                 setLightLocked(color, LIGHT_FLASH_NONE, 0, 0, brightnessMode);
75             }
76         }
77 
setColor(int color)78         public void setColor(int color) {
79             synchronized (this) {
80                 setLightLocked(color, LIGHT_FLASH_NONE, 0, 0, 0);
81             }
82         }
83 
setFlashing(int color, int mode, int onMS, int offMS)84         public void setFlashing(int color, int mode, int onMS, int offMS) {
85             synchronized (this) {
86                 setLightLocked(color, mode, onMS, offMS, BRIGHTNESS_MODE_USER);
87             }
88         }
89 
90 
pulse()91         public void pulse() {
92             pulse(0x00ffffff, 7);
93         }
94 
pulse(int color, int onMS)95         public void pulse(int color, int onMS) {
96             synchronized (this) {
97                 if (mColor == 0 && !mFlashing) {
98                     setLightLocked(color, LIGHT_FLASH_HARDWARE, onMS, 1000, BRIGHTNESS_MODE_USER);
99                     mH.sendMessageDelayed(Message.obtain(mH, 1, this), onMS);
100                 }
101             }
102         }
103 
turnOff()104         public void turnOff() {
105             synchronized (this) {
106                 setLightLocked(0, LIGHT_FLASH_NONE, 0, 0, 0);
107             }
108         }
109 
stopFlashing()110         private void stopFlashing() {
111             synchronized (this) {
112                 setLightLocked(mColor, LIGHT_FLASH_NONE, 0, 0, BRIGHTNESS_MODE_USER);
113             }
114         }
115 
setLightLocked(int color, int mode, int onMS, int offMS, int brightnessMode)116         private void setLightLocked(int color, int mode, int onMS, int offMS, int brightnessMode) {
117             if (color != mColor || mode != mMode || onMS != mOnMS || offMS != mOffMS) {
118                 if (DEBUG) Slog.v(TAG, "setLight #" + mId + ": color=#"
119                         + Integer.toHexString(color));
120                 mColor = color;
121                 mMode = mode;
122                 mOnMS = onMS;
123                 mOffMS = offMS;
124                 setLight_native(mNativePointer, mId, color, mode, onMS, offMS, brightnessMode);
125             }
126         }
127 
128         private int mId;
129         private int mColor;
130         private int mMode;
131         private int mOnMS;
132         private int mOffMS;
133         private boolean mFlashing;
134     }
135 
136     /* This class implements an obsolete API that was removed after eclair and re-added during the
137      * final moments of the froyo release to support flashlight apps that had been using the private
138      * IHardwareService API. This is expected to go away in the next release.
139      */
140     private final IHardwareService.Stub mLegacyFlashlightHack = new IHardwareService.Stub() {
141 
142         private static final String FLASHLIGHT_FILE = "/sys/class/leds/spotlight/brightness";
143 
144         public boolean getFlashlightEnabled() {
145             try {
146                 FileInputStream fis = new FileInputStream(FLASHLIGHT_FILE);
147                 int result = fis.read();
148                 fis.close();
149                 return (result != '0');
150             } catch (Exception e) {
151                 return false;
152             }
153         }
154 
155         public void setFlashlightEnabled(boolean on) {
156             if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FLASHLIGHT)
157                     != PackageManager.PERMISSION_GRANTED &&
158                     mContext.checkCallingOrSelfPermission(android.Manifest.permission.HARDWARE_TEST)
159                     != PackageManager.PERMISSION_GRANTED) {
160                 throw new SecurityException("Requires FLASHLIGHT or HARDWARE_TEST permission");
161             }
162             try {
163                 FileOutputStream fos = new FileOutputStream(FLASHLIGHT_FILE);
164                 byte[] bytes = new byte[2];
165                 bytes[0] = (byte)(on ? '1' : '0');
166                 bytes[1] = '\n';
167                 fos.write(bytes);
168                 fos.close();
169             } catch (Exception e) {
170                 // fail silently
171             }
172         }
173     };
174 
LightsService(Context context)175     LightsService(Context context) {
176 
177         mNativePointer = init_native();
178         mContext = context;
179 
180         ServiceManager.addService("hardware", mLegacyFlashlightHack);
181 
182         for (int i = 0; i < LIGHT_ID_COUNT; i++) {
183             mLights[i] = new Light(i);
184         }
185     }
186 
finalize()187     protected void finalize() throws Throwable {
188         finalize_native(mNativePointer);
189         super.finalize();
190     }
191 
getLight(int id)192     public Light getLight(int id) {
193         return mLights[id];
194     }
195 
196     private Handler mH = new Handler() {
197         @Override
198         public void handleMessage(Message msg) {
199             Light light = (Light)msg.obj;
200             light.stopFlashing();
201         }
202     };
203 
init_native()204     private static native int init_native();
finalize_native(int ptr)205     private static native void finalize_native(int ptr);
206 
setLight_native(int ptr, int light, int color, int mode, int onMS, int offMS, int brightnessMode)207     private static native void setLight_native(int ptr, int light, int color, int mode,
208             int onMS, int offMS, int brightnessMode);
209 
210     private final Context mContext;
211 
212     private int mNativePointer;
213 }
214