LightsService.java revision b880d880c6cd989eacc28c365fc9a41d31900da1
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 public LightsService(Context context) { 160 super(context); 161 162 mNativePointer = init_native(); 163 164 for (int i = 0; i < LightsManager.LIGHT_ID_COUNT; i++) { 165 mLights[i] = new LightImpl(i); 166 } 167 } 168 169 @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 186 @Override 187 protected void finalize() throws Throwable { 188 finalize_native(mNativePointer); 189 super.finalize(); 190 } 191 192 private Handler mH = new Handler() { 193 @Override 194 public void handleMessage(Message msg) { 195 LightImpl light = (LightImpl)msg.obj; 196 light.stopFlashing(); 197 } 198 }; 199 200 private static native long init_native(); 201 private static native void finalize_native(long ptr); 202 203 static native void setLight_native(long ptr, int light, int color, int mode, 204 int onMS, int offMS, int brightnessMode); 205 206 private long mNativePointer; 207} 208