Home | History | Annotate | Download | only in server
      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.File;
     28 import java.io.FileInputStream;
     29 import java.io.FileOutputStream;
     30 
     31 public class LightsService {
     32     private static final String TAG = "LightsService";
     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 
     62         private Light(int id) {
     63             mId = id;
     64         }
     65 
     66         public void setBrightness(int brightness) {
     67             setBrightness(brightness, BRIGHTNESS_MODE_USER);
     68         }
     69 
     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 
     78         public void setColor(int color) {
     79             synchronized (this) {
     80                 setLightLocked(color, LIGHT_FLASH_NONE, 0, 0, 0);
     81             }
     82         }
     83 
     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 
     91         public void pulse() {
     92             pulse(0x00ffffff, 7);
     93         }
     94 
     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 
    104         public void turnOff() {
    105             synchronized (this) {
    106                 setLightLocked(0, LIGHT_FLASH_NONE, 0, 0, 0);
    107             }
    108         }
    109 
    110         private void stopFlashing() {
    111             synchronized (this) {
    112                 setLightLocked(mColor, LIGHT_FLASH_NONE, 0, 0, BRIGHTNESS_MODE_USER);
    113             }
    114         }
    115 
    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                 mColor = color;
    119                 mMode = mode;
    120                 mOnMS = onMS;
    121                 mOffMS = offMS;
    122                 setLight_native(mNativePointer, mId, color, mode, onMS, offMS, brightnessMode);
    123             }
    124         }
    125 
    126         private int mId;
    127         private int mColor;
    128         private int mMode;
    129         private int mOnMS;
    130         private int mOffMS;
    131         private boolean mFlashing;
    132     }
    133 
    134     /* This class implements an obsolete API that was removed after eclair and re-added during the
    135      * final moments of the froyo release to support flashlight apps that had been using the private
    136      * IHardwareService API. This is expected to go away in the next release.
    137      */
    138     private final IHardwareService.Stub mLegacyFlashlightHack = new IHardwareService.Stub() {
    139 
    140         private static final String FLASHLIGHT_FILE = "/sys/class/leds/spotlight/brightness";
    141 
    142         public boolean getFlashlightEnabled() {
    143             try {
    144                 FileInputStream fis = new FileInputStream(FLASHLIGHT_FILE);
    145                 int result = fis.read();
    146                 fis.close();
    147                 return (result != '0');
    148             } catch (Exception e) {
    149                 Slog.e(TAG, "getFlashlightEnabled failed", e);
    150                 return false;
    151             }
    152         }
    153 
    154         public void setFlashlightEnabled(boolean on) {
    155             if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.FLASHLIGHT)
    156                     != PackageManager.PERMISSION_GRANTED &&
    157                     mContext.checkCallingOrSelfPermission(android.Manifest.permission.HARDWARE_TEST)
    158                     != PackageManager.PERMISSION_GRANTED) {
    159                 throw new SecurityException("Requires FLASHLIGHT or HARDWARE_TEST permission");
    160             }
    161             try {
    162                 FileOutputStream fos = new FileOutputStream(FLASHLIGHT_FILE);
    163                 byte[] bytes = new byte[2];
    164                 bytes[0] = (byte)(on ? '1' : '0');
    165                 bytes[1] = '\n';
    166                 fos.write(bytes);
    167                 fos.close();
    168             } catch (Exception e) {
    169                 Slog.e(TAG, "setFlashlightEnabled failed", e);
    170             }
    171         }
    172     };
    173 
    174     LightsService(Context context) {
    175 
    176         mNativePointer = init_native();
    177         mContext = context;
    178 
    179         ServiceManager.addService("hardware", mLegacyFlashlightHack);
    180 
    181         for (int i = 0; i < LIGHT_ID_COUNT; i++) {
    182             mLights[i] = new Light(i);
    183         }
    184     }
    185 
    186     protected void finalize() throws Throwable {
    187         finalize_native(mNativePointer);
    188         super.finalize();
    189     }
    190 
    191     public Light getLight(int id) {
    192         return mLights[id];
    193     }
    194 
    195     private Handler mH = new Handler() {
    196         @Override
    197         public void handleMessage(Message msg) {
    198             Light light = (Light)msg.obj;
    199             light.stopFlashing();
    200         }
    201     };
    202 
    203     private static native int init_native();
    204     private static native void finalize_native(int ptr);
    205 
    206     private static native void setLight_native(int ptr, int light, int color, int mode,
    207             int onMS, int offMS, int brightnessMode);
    208 
    209     private final Context mContext;
    210 
    211     private int mNativePointer;
    212 }
    213