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