参考博文:
http://www.cnblogs.com/flyme/archive/2011/07/27/2118541.html
http://blog.csdn.net/kc58236582/article/details/45647181
/**
* Starts some essential services that are not tangled up in the bootstrap process.
*/
private void startCoreServices() {
// Tracks the battery level. Requires LightService.
mSystemServiceManager.startService(BatteryService.class);//启动BatteryService
// Tracks application usage stats.
mSystemServiceManager.startService(UsageStatsService.class);
mActivityManagerService.setUsageStatsManager(
LocalServices.getService(UsageStatsManagerInternal.class));
// Update after UsageStatsService is available, needed before performBootDexOpt.
mPackageManagerService.getUsageStatsIfNoPackageUsageInfo();
// Tracks whether the updatable WebView is in a ready state and watches for update installs.
mSystemServiceManager.startService(WebViewUpdateService.class);
}
public BatteryService(Context context) {
super(context);
mContext = context;
mHandler = new Handler(true /*async*/);
mLed = new Led(context, getLocalService(LightsManager.class));//初始化Ligths
mBatteryStats = BatteryStatsService.getService();
mCriticalBatteryLevel = mContext.getResources().getInteger(
com.android.internal.R.integer.config_criticalBatteryWarningLevel);
mLowBatteryWarningLevel = mContext.getResources().getInteger(
com.android.internal.R.integer.config_lowBatteryWarningLevel);
mLowBatteryCloseWarningLevel = mLowBatteryWarningLevel + mContext.getResources().getInteger(
com.android.internal.R.integer.config_lowBatteryCloseWarningBump);
mShutdownBatteryTemperature = mContext.getResources().getInteger(
com.android.internal.R.integer.config_shutdownBatteryTemperature);
// watch for invalid charger messages if the invalid_charger switch exists
if (new File("/sys/devices/virtual/switch/invalid_charger/state").exists()) {
mInvalidChargerObserver.startObserving(
"DEVPATH=/devices/virtual/switch/invalid_charger");
}
}
/**
* 将电池监听注册到底层去
*/
@Override
public void onStart() {
IBinder b = ServiceManager.getService("batteryproperties");
final IBatteryPropertiesRegistrar batteryPropertiesRegistrar =
IBatteryPropertiesRegistrar.Stub.asInterface(b);
try {
//电池监听,注册到底层。当底层电量改变会调用此监听。然后执行update
batteryPropertiesRegistrar.registerListener(new BatteryListener());
} catch (RemoteException e) {
// Should never happen.
}
publishBinderService("battery", new BinderService());
publishLocalService(BatteryManagerInternal.class, new LocalService());//将本地接口publish出去。
}
private final class BatteryListener extends IBatteryPropertiesListener.Stub {
@Override
public void batteryPropertiesChanged(BatteryProperties props) {
final long identity = Binder.clearCallingIdentity();
try {
BatteryService.this.update(props);//调用 update()方法,来更新电池的信息数据
} finally {
Binder.restoreCallingIdentity(identity);
}
}
}
//将本地接口publish出去。
private final class LocalService extends BatteryManagerInternal {
@Override
public boolean isPowered(int plugTypeSet) {
synchronized (mLock) {
return isPoweredLocked(plugTypeSet);
}
}
@Override
public int getPlugType() {
synchronized (mLock) {
return mPlugType;
}
}
@Override
public int getBatteryLevel() {
synchronized (mLock) {
return mBatteryProps.batteryLevel;
}
}
@Override
public boolean getBatteryLevelLow() {
synchronized (mLock) {
return mBatteryLevelLow;
}
}
@Override
public int getInvalidCharger() {
synchronized (mLock) {
return mInvalidCharger;
}
}
}
//当底层有信息上来,会调用update函数更新BatteryService中的状态值.
private void update(BatteryProperties props) {
synchronized (mLock) {
if (!mUpdatesStopped) {
mBatteryProps = props;
if (SystemProperties.get("ro.mtk_ipo_support").equals("1")) {
if (mIPOShutdown)
return;
}
// Process the new values.
if (mBootCompleted)
processValuesLocked(false);
} else {
mLastBatteryProps.set(props);
}
}
}
接下来分析主函数processValuesLocked:
private void processValuesLocked(boolean force) {
boolean logOutlier = false;
long dischargeDuration = 0;
mBatteryLevelCritical = (mBatteryProps.batteryLevel <= mCriticalBatteryLevel);
//判断充电类型
if (mBatteryProps.chargerAcOnline) {// AC
mPlugType = BatteryManager.BATTERY_PLUGGED_AC;
} else if (mBatteryProps.chargerUsbOnline) {//USB
mPlugType = BatteryManager.BATTERY_PLUGGED_USB;
} else if (mBatteryProps.chargerWirelessOnline) {//无线
mPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS;
} else {
mPlugType = BATTERY_PLUGGED_NONE;
}
/// M: Add for DUAL_INPUT_CHARGER_SUPPORT @{
if (SystemProperties.get("ro.mtk_diso_support").equals("true")) {
if (mBatteryProps.chargerAcOnline && mBatteryProps.chargerUsbOnline) {
mPlugType = BatteryManager.BATTERY_PLUGGED_AC | BatteryManager.BATTERY_PLUGGED_USB;
}
}
/// M: @}
if (mLastBatteryVoltage != mBatteryProps.batteryVoltage) {
Log.d(TAG, "mBatteryVoltage=" + mBatteryProps.batteryVoltage + ", batteryLevel=" + mBatteryProps.batteryLevel_smb);
}
// Update the battery LED
mLed.updateLightsLocked();//更新电池的LED(BreathLights)
// Let the battery stats keep track of the current level.
try {
mBatteryStats.setBatteryState(mBatteryProps.batteryStatus, mBatteryProps.batteryHealth,
mPlugType, mBatteryProps.batteryLevel, mBatteryProps.batteryTemperature,
mBatteryProps.batteryVoltage);
} catch (RemoteException e) {
// Should never happen.
}
//没电了
shutdownIfNoPowerLocked();
// 温度过高
shutdownIfOverTempLocked();
if (force || (mBatteryProps.batteryStatus != mLastBatteryStatus ||
mBatteryProps.batteryStatus_smb != mLastBatteryStatus_smb ||
mBatteryProps.batteryHealth != mLastBatteryHealth ||
mBatteryProps.batteryPresent != mLastBatteryPresent ||
mBatteryProps.batteryPresent_smb != mLastBatteryPresent_smb ||
mBatteryProps.batteryLevel != mLastBatteryLevel ||
mBatteryProps.batteryLevel_smb != mLastBatteryLevel_smb ||
mPlugType != mLastPlugType ||
mBatteryProps.batteryVoltage != mLastBatteryVoltage ||
mBatteryProps.batteryTemperature != mLastBatteryTemperature ||
mInvalidCharger != mLastInvalidCharger)) {
if (mPlugType != mLastPlugType) {
if (mLastPlugType == BATTERY_PLUGGED_NONE) {
// discharging -> charging
// There's no value in this data unless we've discharged at least once and the
// battery level has changed; so don't log until it does.
//不充电到充电
if (mDischargeStartTime != 0 && mDischargeStartLevel != mBatteryProps.batteryLevel) {
dischargeDuration = SystemClock.elapsedRealtime() - mDischargeStartTime;
logOutlier = true;
EventLog.writeEvent(EventLogTags.BATTERY_DISCHARGE, dischargeDuration,
mDischargeStartLevel, mBatteryProps.batteryLevel);
// make sure we see a discharge event before logging again
mDischargeStartTime = 0;
}
} else if (mPlugType == BATTERY_PLUGGED_NONE) {
// 刚开始充电
// charging -> discharging or we just powered up
mDischargeStartTime = SystemClock.elapsedRealtime();
mDischargeStartLevel = mBatteryProps.batteryLevel;
}
}
if (mBatteryProps.batteryStatus != mLastBatteryStatus ||
mBatteryProps.batteryHealth != mLastBatteryHealth ||
mBatteryProps.batteryPresent != mLastBatteryPresent ||
mPlugType != mLastPlugType) {
EventLog.writeEvent(EventLogTags.BATTERY_STATUS,
mBatteryProps.batteryStatus, mBatteryProps.batteryHealth, mBatteryProps.batteryPresent ? 1 : 0,
mPlugType, mBatteryProps.batteryTechnology);
}
if (mBatteryProps.batteryLevel != mLastBatteryLevel) {
// Don't do this just from voltage or temperature changes, that is
// too noisy.
EventLog.writeEvent(EventLogTags.BATTERY_LEVEL,
mBatteryProps.batteryLevel, mBatteryProps.batteryVoltage, mBatteryProps.batteryTemperature);
}
if (mBatteryLevelCritical && !mLastBatteryLevelCritical &&
mPlugType == BATTERY_PLUGGED_NONE) {
// We want to make sure we log discharge cycle outliers
// if the battery is about to die.
dischargeDuration = SystemClock.elapsedRealtime() - mDischargeStartTime;
logOutlier = true;
}
if (!mBatteryLevelLow) {
// Should we now switch in to low battery mode?
if (mPlugType == BATTERY_PLUGGED_NONE
&& mBatteryProps.batteryLevel <= mLowBatteryWarningLevel) {
mBatteryLevelLow = true;
}
} else {
// Should we now switch out of low battery mode?
if (mPlugType != BATTERY_PLUGGED_NONE) {
mBatteryLevelLow = false;
} else if (mBatteryProps.batteryLevel >= mLowBatteryCloseWarningLevel) {
mBatteryLevelLow = false;
} else if (force && mBatteryProps.batteryLevel >= mLowBatteryWarningLevel) {
// If being forced, the previous state doesn't matter, we will just
// absolutely check to see if we are now above the warning level.
mBatteryLevelLow = false;
}
}
sendIntentLocked();//发送电池状态改变的广播
// Separate broadcast is sent for power connected / not connected
// since the standard intent will not wake any applications and some
// applications may want to have smart behavior based on this.
if (mPlugType != 0 && mLastPlugType == 0) {
mHandler.post(new Runnable() {
@Override
public void run() {
Intent statusIntent = new Intent(Intent.ACTION_POWER_CONNECTED);
statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
}
});
}
else if (mPlugType == 0 && mLastPlugType != 0) {
mHandler.post(new Runnable() {
@Override
public void run() {
Intent statusIntent = new Intent(Intent.ACTION_POWER_DISCONNECTED);
statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
}
});
}
if (shouldSendBatteryLowLocked()) {
mSentLowBatteryBroadcast = true;
mHandler.post(new Runnable() {
@Override
public void run() {
Intent statusIntent = new Intent(Intent.ACTION_BATTERY_LOW);
statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
}
});
} else if (mSentLowBatteryBroadcast && mLastBatteryLevel >= mLowBatteryCloseWarningLevel) {
mSentLowBatteryBroadcast = false;
mHandler.post(new Runnable() {
@Override
public void run() {
Intent statusIntent = new Intent(Intent.ACTION_BATTERY_OKAY);
statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
}
});
}
if (mBatteryProps.batteryStatus != mLastBatteryStatus &&
mBatteryProps.batteryStatus == BatteryManager.BATTERY_STATUS_CMD_DISCHARGING) {
mHandler.post(new Runnable() {
@Override
public void run() {
final String ACTION_IGNORE_DATA_USAGE_ALERT =
"android.intent.action.IGNORE_DATA_USAGE_ALERT";
Log.d(TAG, "sendBroadcast ACTION_IGNORE_DATA_USAGE_ALERT");
Intent statusIntent = new Intent(ACTION_IGNORE_DATA_USAGE_ALERT);
statusIntent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
}
});
}
// Update the battery LED
/*
* bugfix #134486 low battery not charging led keep red
// mLed.updateLightsLocked();
*/
mLed.updateLightsLocked();//更新电池的LED(BreathLights)
// This needs to be done after sendIntent() so that we get the lastest battery stats.
if (logOutlier && dischargeDuration != 0) {
logOutlierLocked(dischargeDuration);
}
mLastBatteryStatus = mBatteryProps.batteryStatus;
mLastBatteryStatus_smb = mBatteryProps.batteryStatus_smb;
mLastBatteryHealth = mBatteryProps.batteryHealth;
mLastBatteryPresent = mBatteryProps.batteryPresent;
mLastBatteryPresent_smb = mBatteryProps.batteryPresent_smb;
mLastBatteryLevel = mBatteryProps.batteryLevel;
mLastBatteryLevel_smb = mBatteryProps.batteryLevel_smb;
mLastPlugType = mPlugType;
mLastBatteryVoltage = mBatteryProps.batteryVoltage;
mLastBatteryTemperature = mBatteryProps.batteryTemperature;
mLastBatteryLevelCritical = mBatteryLevelCritical;
mLastInvalidCharger = mInvalidCharger;
}
}
电池的这些信息是通过何种方式,被其他应用所获得的。可以想到的有两种方式,第一种,应用主动从BatteryService获得数据;第二种,BatteryService主动把数据传送给所关心的应用程序。
BatteryService采用的是第二种方式,所有的电池的信息数据是通过Intent传送出去的。在BatteryService.java中,Code如下:
private void sendIntentLocked() {
// Pack up the values and broadcast them to everyone
final Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
| Intent.FLAG_RECEIVER_REPLACE_PENDING);
int icon = getIconLocked(mBatteryProps.batteryLevel);
intent.putExtra(BatteryManager.EXTRA_STATUS, mBatteryProps.batteryStatus);
intent.putExtra(BatteryManager.EXTRA_STATUS_SMARTBOOK, mBatteryProps.batteryStatus_smb);
intent.putExtra(BatteryManager.EXTRA_HEALTH, mBatteryProps.batteryHealth);
intent.putExtra(BatteryManager.EXTRA_PRESENT, mBatteryProps.batteryPresent);
intent.putExtra(BatteryManager.EXTRA_PRESENT_SMARTBOOK, mBatteryProps.batteryPresent_smb);
intent.putExtra(BatteryManager.EXTRA_LEVEL, mBatteryProps.batteryLevel);
intent.putExtra(BatteryManager.EXTRA_LEVEL_SMARTBOOK, mBatteryProps.batteryLevel_smb);
intent.putExtra(BatteryManager.EXTRA_SCALE, BATTERY_SCALE);
intent.putExtra(BatteryManager.EXTRA_ICON_SMALL, icon);
intent.putExtra(BatteryManager.EXTRA_PLUGGED, mPlugType);
intent.putExtra(BatteryManager.EXTRA_VOLTAGE, mBatteryProps.batteryVoltage);
intent.putExtra(BatteryManager.EXTRA_TEMPERATURE, mBatteryProps.batteryTemperature);
intent.putExtra(BatteryManager.EXTRA_TECHNOLOGY, mBatteryProps.batteryTechnology);
intent.putExtra(BatteryManager.EXTRA_INVALID_CHARGER, mInvalidCharger);
mHandler.post(new Runnable() {
@Override
public void run() {
ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.USER_ALL);
}
});
}
====================================================
充电呼吸灯实现的流程
在上边的processValuesLocked()方法里边,通过调用mLed.updateLightsLocked()来处理呼吸灯的各个状态
/**
*通过Led来调用LightsService.java对应的方法(frameworks/base/services/core/java/com/android/server/lights/LightsService.java)
*/
private final class Led {
private final Light mBatteryLight;
private final int mBatteryLowARGB;
private final int mBatteryMediumARGB;
private final int mBatteryFullARGB;
private final int mBatteryLedOn;
private final int mBatteryLedOff;
public Led(Context context, LightsManager lights) {//构造函数做初始化
mBatteryLight = lights.getLight(LightsManager.LIGHT_ID_BATTERY);
mBatteryLowARGB = context.getResources().getInteger(
com.android.internal.R.integer.config_notificationsBatteryLowARGB);
mBatteryMediumARGB = context.getResources().getInteger(
com.android.internal.R.integer.config_notificationsBatteryMediumARGB);
mBatteryFullARGB = context.getResources().getInteger(
com.android.internal.R.integer.config_notificationsBatteryFullARGB);
mBatteryLedOn = context.getResources().getInteger(
com.android.internal.R.integer.config_notificationsBatteryLedOn);
mBatteryLedOff = context.getResources().getInteger(
com.android.internal.R.integer.config_notificationsBatteryLedOff);
}
/**
* Synchronize on BatteryService.
*/
public void updateLightsLocked() {
final int level = mBatteryProps.batteryLevel;
final int status = mBatteryProps.batteryStatus;
if (mIPOBoot)
{
//Get led status in IPO mode
getIpoLedStatus();
}
if (level < mLowBatteryWarningLevel) {//判断是否低电量
if (status == BatteryManager.BATTERY_STATUS_CHARGING) {//低电量充电状态
updateLedStatus();
// Solid red when battery is charging
mBatteryLight.setColor(mBatteryLowARGB);//调用LightsService里边的setColor
} else {//低电量
mBatteryLight.turnOff();
LowLevelFlag = true;
updateLedStatus();
// Flash red when battery is low and not charging
mBatteryLight.setFlashing(mBatteryLowARGB, Light.LIGHT_FLASH_TIMED,
mBatteryLedOn, mBatteryLedOff);//调用LightsService里边的setFlashing
}
} else if (status == BatteryManager.BATTERY_STATUS_CHARGING
|| status == BatteryManager.BATTERY_STATUS_FULL) {//充电状态
if (status == BatteryManager.BATTERY_STATUS_FULL || level >= 90) {//电量满或者大于百分之90
updateLedStatus();
// Solid green when full or charging and nearly full
mBatteryLight.setColor(mBatteryFullARGB);//调用LightsService里边的setColor
} else {//小于百分之90
updateLedStatus();
// Solid orange when charging and halfway full
mBatteryLight.setColor(mBatteryMediumARGB);//调用LightsService里边的setColor
}
} else {
if (ipo_led_on && mIPOBoot) {
if (status == BatteryManager.BATTERY_STATUS_FULL || level >= 90) {
mBatteryLight.setColor(mBatteryFullARGB);
}
else {
mBatteryLight.setColor(mBatteryMediumARGB);
}
mIPOBoot = false;
ipo_led_on = false;
}
// No lights if not charging and not low
mBatteryLight.turnOff();
}
}
private void getIpoLedStatus() {
if ("1".equals(SystemProperties.get("sys.ipo.ledon"))) {
ipo_led_on = true;
}
else if ("0".equals(SystemProperties.get("sys.ipo.ledon"))) {
ipo_led_off = true;
}
if (DEBUG) {
Slog.d(TAG, ">>>>>>>getIpoLedStatus ipo_led_on = " + ipo_led_on + ", ipo_led_off = " + ipo_led_off + "<<<<<<<");
}
}
private void updateLedStatus() {
// if LowBatteryWarning happened, we refresh the led state no matter ipo_led is on or off.
if ((ipo_led_off && mIPOBoot) || (LowLevelFlag && mIPOBoot)) {
mBatteryLight.turnOff();
mIPOBoot = false;
ipo_led_off = false;
ipo_led_on = false;
if (DEBUG) {
Slog.d(TAG, ">>>>>>>updateLedStatus LowLevelFlag = " + LowLevelFlag + "<<<<<<<");
}
}
}
}
接下来分析LightsService.java
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.lights;
import com.android.server.SystemService;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.os.Trace;
import android.util.Slog;
/* wj@Revo:add status light setup menu, 20160624 */
import android.os.SystemProperties;
/* End of wj@Revo */
public class LightsService extends SystemService {
static final String TAG = "LightsService";
static final boolean DEBUG = false;
/* wj@Revo:add status light setup menu, 20160624 */
private Context mContext;
/* End of wj@Revo */
final LightImpl mLights[] = new LightImpl[LightsManager.LIGHT_ID_COUNT];
private final class LightImpl extends Light {
private LightImpl(int id) {
mId = id;
}
@Override
public void setBrightness(int brightness) {
setBrightness(brightness, BRIGHTNESS_MODE_USER);
}
@Override
public void setBrightness(int brightness, int brightnessMode) {
synchronized (this) {
int color = brightness & 0x000000ff;
color = 0xff000000 | (color << 16) | (color << 8) | color;
setLightLocked(color, LIGHT_FLASH_NONE, 0, 0, brightnessMode);
}
}
@Override
public void setColor(int color) {
synchronized (this) {
setLightLocked(color, LIGHT_FLASH_NONE, 0, 0, 0);
}
}
@Override
public void setFlashing(int color, int mode, int onMS, int offMS) {
synchronized (this) {
setLightLocked(color, mode, onMS, offMS, BRIGHTNESS_MODE_USER);
}
}
@Override
public void pulse() {
pulse(0x00ffffff, 7);
}
@Override
public void pulse(int color, int onMS) {
synchronized (this) {
if (mColor == 0 && !mFlashing) {
setLightLocked(color, LIGHT_FLASH_HARDWARE, onMS, 1000, BRIGHTNESS_MODE_USER);
mColor = 0;
mH.sendMessageDelayed(Message.obtain(mH, 1, this), onMS);
}
}
}
@Override
public void turnOff() {
synchronized (this) {
setLightLocked(0, LIGHT_FLASH_NONE, 0, 0, 0);
}
}
private void stopFlashing() {
synchronized (this) {
setLightLocked(mColor, LIGHT_FLASH_NONE, 0, 0, BRIGHTNESS_MODE_USER);
}
}
private void setLightLocked(int color, int mode, int onMS, int offMS, int brightnessMode) {
if(mContext != null && mContext.getResources().getBoolean(
com.android.internal.R.bool.config_settings_status_light_support)){
if (SystemProperties.getBoolean("persist.sys.status_light", true) == false) {
if (mId == LightsManager.LIGHT_ID_BATTERY || mId == LightsManager.LIGHT_ID_NOTIFICATIONS || mId == LightsManager.LIGHT_ID_ATTENTION) {
setLight_native(mNativePointer, mId, 0, LIGHT_FLASH_NONE, 0, 0, 0);
return;
}
}
if (color != mColor || mode != mMode || onMS != mOnMS || offMS != mOffMS
|| SystemProperties.getBoolean("persist.sys.status_light", true)) {
if (DEBUG) Slog.v(TAG, "setLight #" + mId + ": color=#"
+ Integer.toHexString(color));
mColor = color;
mMode = mode;
mOnMS = onMS;
mOffMS = offMS;
Trace.traceBegin(Trace.TRACE_TAG_POWER, "setLight(" + mId + ", 0x"
+ Integer.toHexString(color) + ")");
try {
setLight_native(mNativePointer, mId, color, mode, onMS, offMS, brightnessMode);//通过JNI调用底层驱动
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
}
} else if (color != mColor || mode != mMode || onMS != mOnMS || offMS != mOffMS) {
if (DEBUG) Slog.v(TAG, "setLight #" + mId + ": color=#"
+ Integer.toHexString(color));
mColor = color;
mMode = mode;
mOnMS = onMS;
mOffMS = offMS;
Trace.traceBegin(Trace.TRACE_TAG_POWER, "setLight(" + mId + ", 0x"
+ Integer.toHexString(color) + ")");
try {
setLight_native(mNativePointer, mId, color, mode, onMS, offMS, brightnessMode);//通过JNI调用底层驱动
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
}
}
private int mId;
private int mColor;
private int mMode;
private int mOnMS;
private int mOffMS;
private boolean mFlashing;
}
public LightsService(Context context) {
super(context);
mContext = context;
mNativePointer = init_native();
for (int i = 0; i < LightsManager.LIGHT_ID_COUNT; i++) {
mLights[i] = new LightImpl(i);
}
}
@Override
public void onStart() {
publishLocalService(LightsManager.class, mService);
}
private final LightsManager mService = new LightsManager() {
@Override
public Light getLight(int id) {
if (id < LIGHT_ID_COUNT) {
return mLights[id];
} else {
return null;
}
}
};
@Override
protected void finalize() throws Throwable {
finalize_native(mNativePointer);
super.finalize();
}
private Handler mH = new Handler() {
@Override
public void handleMessage(Message msg) {
LightImpl light = (LightImpl)msg.obj;
light.stopFlashing();
}
};
private static native long init_native();
private static native void finalize_native(long ptr);
static native void setLight_native(long ptr, int light, int color, int mode,
int onMS, int offMS, int brightnessMode);//上层接口掉底层驱动
private long mNativePointer;
}