13a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood/* 23a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood * Copyright (C) 2008 The Android Open Source Project 33a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood * 43a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood * Licensed under the Apache License, Version 2.0 (the "License"); 53a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood * you may not use this file except in compliance with the License. 63a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood * You may obtain a copy of the License at 73a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood * 83a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood * http://www.apache.org/licenses/LICENSE-2.0 93a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood * 103a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood * Unless required by applicable law or agreed to in writing, software 113a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood * distributed under the License is distributed on an "AS IS" BASIS, 123a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood * See the License for the specific language governing permissions and 143a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood * limitations under the License. 153a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood */ 163a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood 173a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwoodpackage com.android.server; 183a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood 193a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwoodimport android.content.Context; 20eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwoodimport android.content.pm.PackageManager; 213a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwoodimport android.os.Handler; 22eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwoodimport android.os.IHardwareService; 23eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwoodimport android.os.ServiceManager; 243a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwoodimport android.os.Message; 258a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog; 263a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood 27eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwoodimport java.io.FileInputStream; 28eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwoodimport java.io.FileOutputStream; 29eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood 303a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwoodpublic class LightsService { 313a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood private static final String TAG = "LightsService"; 32ff801ec71399f7e8aa95bcbb9937c53144fe17c5Dianne Hackborn private static final boolean DEBUG = false; 333a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood 343a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood static final int LIGHT_ID_BACKLIGHT = 0; 353a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood static final int LIGHT_ID_KEYBOARD = 1; 363a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood static final int LIGHT_ID_BUTTONS = 2; 373a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood static final int LIGHT_ID_BATTERY = 3; 383a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood static final int LIGHT_ID_NOTIFICATIONS = 4; 393a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood static final int LIGHT_ID_ATTENTION = 5; 403cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood static final int LIGHT_ID_BLUETOOTH = 6; 413cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood static final int LIGHT_ID_WIFI = 7; 423cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood static final int LIGHT_ID_COUNT = 8; 433a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood 443a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood static final int LIGHT_FLASH_NONE = 0; 453a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood static final int LIGHT_FLASH_TIMED = 1; 463a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood static final int LIGHT_FLASH_HARDWARE = 2; 473a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood 483a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood /** 493a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood * Light brightness is managed by a user setting. 503a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood */ 513a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood static final int BRIGHTNESS_MODE_USER = 0; 523a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood 533a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood /** 543a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood * Light brightness is managed by a light sensor. 553a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood */ 563a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood static final int BRIGHTNESS_MODE_SENSOR = 1; 573a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood 583cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood private final Light mLights[] = new Light[LIGHT_ID_COUNT]; 593a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood 603cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood public final class Light { 613a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood 623cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood private Light(int id) { 633cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood mId = id; 643cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood } 653a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood 663cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood public void setBrightness(int brightness) { 673cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood setBrightness(brightness, BRIGHTNESS_MODE_USER); 683cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood } 693a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood 703cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood public void setBrightness(int brightness, int brightnessMode) { 713cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood synchronized (this) { 723cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood int color = brightness & 0x000000ff; 733cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood color = 0xff000000 | (color << 16) | (color << 8) | color; 743cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood setLightLocked(color, LIGHT_FLASH_NONE, 0, 0, brightnessMode); 753cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood } 763cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood } 773a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood 783cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood public void setColor(int color) { 793cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood synchronized (this) { 803cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood setLightLocked(color, LIGHT_FLASH_NONE, 0, 0, 0); 813cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood } 823cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood } 833a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood 843cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood public void setFlashing(int color, int mode, int onMS, int offMS) { 853cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood synchronized (this) { 863cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood setLightLocked(color, mode, onMS, offMS, BRIGHTNESS_MODE_USER); 873cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood } 883cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood } 893a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood 90670f93283b5e2445c58998153de9c476acddc37bMike Lockwood 913cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood public void pulse() { 92670f93283b5e2445c58998153de9c476acddc37bMike Lockwood pulse(0x00ffffff, 7); 93670f93283b5e2445c58998153de9c476acddc37bMike Lockwood } 94670f93283b5e2445c58998153de9c476acddc37bMike Lockwood 95670f93283b5e2445c58998153de9c476acddc37bMike Lockwood public void pulse(int color, int onMS) { 963cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood synchronized (this) { 973cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood if (mColor == 0 && !mFlashing) { 98670f93283b5e2445c58998153de9c476acddc37bMike Lockwood setLightLocked(color, LIGHT_FLASH_HARDWARE, onMS, 1000, BRIGHTNESS_MODE_USER); 99670f93283b5e2445c58998153de9c476acddc37bMike Lockwood mH.sendMessageDelayed(Message.obtain(mH, 1, this), onMS); 1003cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood } 1013cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood } 1023cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood } 1033a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood 1043cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood public void turnOff() { 1053cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood synchronized (this) { 1063cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood setLightLocked(0, LIGHT_FLASH_NONE, 0, 0, 0); 1073cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood } 1083a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood } 1093a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood 1103cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood private void stopFlashing() { 1113cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood synchronized (this) { 1123cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood setLightLocked(mColor, LIGHT_FLASH_NONE, 0, 0, BRIGHTNESS_MODE_USER); 1133a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood } 1143cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood } 1153cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood 1163cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood private void setLightLocked(int color, int mode, int onMS, int offMS, int brightnessMode) { 1173cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood if (color != mColor || mode != mMode || onMS != mOnMS || offMS != mOffMS) { 118ff801ec71399f7e8aa95bcbb9937c53144fe17c5Dianne Hackborn if (DEBUG) Slog.v(TAG, "setLight #" + mId + ": color=#" 119ff801ec71399f7e8aa95bcbb9937c53144fe17c5Dianne Hackborn + Integer.toHexString(color)); 1203cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood mColor = color; 1213cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood mMode = mode; 1223cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood mOnMS = onMS; 1233cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood mOffMS = offMS; 1243cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood setLight_native(mNativePointer, mId, color, mode, onMS, offMS, brightnessMode); 1253a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood } 1263a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood } 1273cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood 1283cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood private int mId; 1293cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood private int mColor; 1303cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood private int mMode; 1313cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood private int mOnMS; 1323cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood private int mOffMS; 1333cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood private boolean mFlashing; 1343cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood } 1353cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood 136eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood /* This class implements an obsolete API that was removed after eclair and re-added during the 137eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood * final moments of the froyo release to support flashlight apps that had been using the private 138eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood * IHardwareService API. This is expected to go away in the next release. 139eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood */ 140eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood private final IHardwareService.Stub mLegacyFlashlightHack = new IHardwareService.Stub() { 141eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood 142eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood private static final String FLASHLIGHT_FILE = "/sys/class/leds/spotlight/brightness"; 143eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood 144eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood public boolean getFlashlightEnabled() { 145eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood try { 146eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood FileInputStream fis = new FileInputStream(FLASHLIGHT_FILE); 147eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood int result = fis.read(); 148eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood fis.close(); 149eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood return (result != '0'); 150eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood } catch (Exception e) { 151eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood return false; 152eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood } 153eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood } 154eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood 155eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood public void setFlashlightEnabled(boolean on) { 156eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FLASHLIGHT) 157eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood != PackageManager.PERMISSION_GRANTED && 158eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood mContext.checkCallingOrSelfPermission(android.Manifest.permission.HARDWARE_TEST) 159eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood != PackageManager.PERMISSION_GRANTED) { 160eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood throw new SecurityException("Requires FLASHLIGHT or HARDWARE_TEST permission"); 161eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood } 162eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood try { 163eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood FileOutputStream fos = new FileOutputStream(FLASHLIGHT_FILE); 164eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood byte[] bytes = new byte[2]; 165eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood bytes[0] = (byte)(on ? '1' : '0'); 166eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood bytes[1] = '\n'; 167eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood fos.write(bytes); 168eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood fos.close(); 169eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood } catch (Exception e) { 17035167d95e155f4b4a962bad9613ae66f6a36f88bMike Lockwood // fail silently 171eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood } 172eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood } 173eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood }; 174eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood 1753cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood LightsService(Context context) { 1763cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood 1773cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood mNativePointer = init_native(); 1783cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood mContext = context; 1793cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood 180eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood ServiceManager.addService("hardware", mLegacyFlashlightHack); 181eb9cbb8fdddf4c887004b20b504083035d57a15fMike Lockwood 1823cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood for (int i = 0; i < LIGHT_ID_COUNT; i++) { 1833cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood mLights[i] = new Light(i); 1843cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood } 1853cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood } 1863cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood 1873cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood protected void finalize() throws Throwable { 1883cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood finalize_native(mNativePointer); 1893cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood super.finalize(); 1903cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood } 1913cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood 1923cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood public Light getLight(int id) { 1933cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood return mLights[id]; 1943a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood } 1953a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood 1963a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood private Handler mH = new Handler() { 1973a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood @Override 1983a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood public void handleMessage(Message msg) { 1993cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood Light light = (Light)msg.obj; 2003cb67a37f185a7a5b12712907630acb68e0ac402Mike Lockwood light.stopFlashing(); 2013a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood } 2023a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood }; 2033a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood 2043a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood private static native int init_native(); 2053a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood private static native void finalize_native(int ptr); 2063a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood 2073a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood private static native void setLight_native(int ptr, int light, int color, int mode, 2083a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood int onMS, int offMS, int brightnessMode); 2093a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood 2103a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood private final Context mContext; 2113a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood 2123a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood private int mNativePointer; 2133a32213c4029a03fe39486f3d6ebd0ea18928ee1Mike Lockwood} 214