LightsService.java revision 9158825f9c41869689d6b1786d7c7aa8bdd524ce
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 17package com.android.server.lights; 18 19import com.android.server.SystemService; 20 21import android.content.Context; 22import android.content.pm.PackageManager; 23import android.os.Handler; 24import android.os.IHardwareService; 25import android.os.Message; 26import android.util.Slog; 27 28import java.io.FileInputStream; 29import java.io.FileOutputStream; 30 31public class LightsService extends SystemService { 32 static final String TAG = "LightsService"; 33 static final boolean DEBUG = false; 34 35 final LightImpl mLights[] = new LightImpl[LightsManager.LIGHT_ID_COUNT]; 36 37 private final class LightImpl extends Light { 38 39 private LightImpl(int id) { 40 mId = id; 41 } 42 43 @Override 44 public void setBrightness(int brightness) { 45 setBrightness(brightness, BRIGHTNESS_MODE_USER); 46 } 47 48 @Override 49 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 57 @Override 58 public void setColor(int color) { 59 synchronized (this) { 60 setLightLocked(color, LIGHT_FLASH_NONE, 0, 0, 0); 61 } 62 } 63 64 @Override 65 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 71 @Override 72 public void pulse() { 73 pulse(0x00ffffff, 7); 74 } 75 76 @Override 77 public void pulse(int color, int onMS) { 78 synchronized (this) { 79 if (mColor == 0 && !mFlashing) { 80 setLightLocked(color, LIGHT_FLASH_HARDWARE, onMS, 1000, BRIGHTNESS_MODE_USER); 81 mH.sendMessageDelayed(Message.obtain(mH, 1, this), onMS); 82 } 83 } 84 } 85 86 @Override 87 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) { 101 if (DEBUG) Slog.v(TAG, "setLight #" + mId + ": color=#" 102 + Integer.toHexString(color)); 103 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 } 118 119 /* 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) { 134 return false; 135 } 136 } 137 138 public void setFlashlightEnabled(boolean on) { 139 final Context context = getContext(); 140 if (context.checkCallingOrSelfPermission(android.Manifest.permission.FLASHLIGHT) 141 != PackageManager.PERMISSION_GRANTED && 142 context.checkCallingOrSelfPermission(android.Manifest.permission.HARDWARE_TEST) 143 != 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) { 154 // fail silently 155 } 156 } 157 }; 158 159 @Override 160 public void onCreate(Context context) { 161 mNativePointer = init_native(); 162 163 for (int i = 0; i < LightsManager.LIGHT_ID_COUNT; i++) { 164 mLights[i] = new LightImpl(i); 165 } 166 } 167 168 @Override 169 public void onStart() { 170 publishBinderService("hardware", mLegacyFlashlightHack); 171 publishLocalService(LightsManager.class, mService); 172 } 173 174 private final LightsManager mService = new LightsManager() { 175 @Override 176 public com.android.server.lights.Light getLight(int id) { 177 if (id < LIGHT_ID_COUNT) { 178 return mLights[id]; 179 } else { 180 return null; 181 } 182 } 183 }; 184 185 protected void finalize() throws Throwable { 186 finalize_native(mNativePointer); 187 super.finalize(); 188 } 189 190 private Handler mH = new Handler() { 191 @Override 192 public void handleMessage(Message msg) { 193 LightImpl light = (LightImpl)msg.obj; 194 light.stopFlashing(); 195 } 196 }; 197 198 private static native int init_native(); 199 private static native void finalize_native(int ptr); 200 201 static native void setLight_native(int ptr, int light, int color, int mode, 202 int onMS, int offMS, int brightnessMode); 203 204 int mNativePointer; 205} 206