MTK 6.0 充电Led灯分析
2017-04-17 本文已影响544人
Exception_Cui
最近客户对Led这块增加了很多定制。所以修改定制完成之后做了总结,顺便分析下流程
1. 启动BatteryService
电池的信息,电压,温度,充电状态等等,都是由BatteryService来提供的。BatteryService是跑在system_process当中,在系统初始化的时候启动,如下 在SystemServer.java中可以看到启动BatteryService的代码
电池的信息,电压,温度,充电状态等等.这些值都是通过节点获取的
/sys/class/power_supply/ac/online //AC 电源连接状态 交流电 即电源插座
/sys/class/power_supply/usb/online //USB电源连接状态
/sys/class/power_supply/battery/status //充电状态
/sys/class/power_supply/battery/health //电池状态
/sys/class/power_supply/battery/present //使用状态
/sys/class/power_supply/battery/capacity //电池 level
/sys/class/power_supply/battery/batt_vol //电池电压
/sys/class/power_supply/battery/batt_temp //电池温度
/sys/class/power_supply/battery/technology //电池技术
/**
* 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);
}
BattryService.java
构造函数做初始化
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
//这个真的骚, java 和c++ 直接通过binder 进行通讯
//想研究的可以看看这个大牛 https://blog.csdn.net/zvivi521/article/details/14520883
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) { //检测电池充电的方式
mPlugType = BatteryManager.BATTERY_PLUGGED_AC;
} else if (mBatteryProps.chargerUsbOnline) {
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 (DEBUG) {
Slog.d(TAG, "Processing new values: "
+ "chargerAcOnline=" + mBatteryProps.chargerAcOnline
+ ", chargerUsbOnline=" + mBatteryProps.chargerUsbOnline
+ ", chargerWirelessOnline=" + mBatteryProps.chargerWirelessOnline
+ ", batteryStatus=" + mBatteryProps.batteryStatus
+ ", batteryHealth=" + mBatteryProps.batteryHealth
+ ", batteryPresent=" + mBatteryProps.batteryPresent
+ ", batteryLevel=" + mBatteryProps.batteryLevel
+ ", batteryTechnology=" + mBatteryProps.batteryTechnology
+ ", batteryVoltage=" + mBatteryProps.batteryVoltage
+ ", batteryTemperature=" + mBatteryProps.batteryTemperature
+ ", mBatteryLevelCritical=" + mBatteryLevelCritical
+ ", mPlugType=" + mPlugType);
}
if (mLastBatteryVoltage != mBatteryProps.batteryVoltage) {
Log.d(TAG, "mBatteryVoltage=" + mBatteryProps.batteryVoltage + ", batteryLevel=" + mBatteryProps.batteryLevel_smb);
}
// Update the battery LED
mLed.updateLightsLocked(); //更新LED 状态
// 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) { //检测电池电量,是否切换到低电模式、、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
// mLed.updateLightsLocked();
// 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;
}
}
sendIntentLocked() 将电池状态发送出去, 应用监听广播即可获取电池状态
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);
if (DEBUG) {
Slog.d(TAG, "Sending ACTION_BATTERY_CHANGED. level:" + mBatteryProps.batteryLevel +
", scale:" + BATTERY_SCALE + ", status:" + mBatteryProps.batteryStatus +
", health:" + mBatteryProps.batteryHealth + ", present:" + mBatteryProps.batteryPresent +
", voltage: " + mBatteryProps.batteryVoltage +
", temperature: " + mBatteryProps.batteryTemperature +
", technology: " + mBatteryProps.batteryTechnology +
", AC powered:" + mBatteryProps.chargerAcOnline + ", USB powered:" + mBatteryProps.chargerUsbOnline +
", Wireless powered:" + mBatteryProps.chargerWirelessOnline +
", icon:" + icon + ", invalid charger:" + mInvalidCharger +
", status_smb:" + mBatteryProps.batteryStatus_smb + ", present_smb:" +
mBatteryProps.batteryPresent_smb + ",level_smb:" + mBatteryProps.batteryLevel_smb);
}
mHandler.post(new Runnable() {
@Override
public void run() {
ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.USER_ALL);
}
});
updateLightsLocked() led灯最主要方法
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);//mBatteryLight,通过LightsManager获取是那种灯,还有优先级,优先级就分为电池和通知
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);//优先级最高,mBatteryLowARGB设置充电Led等的颜色。
} else {
LowLevelFlag = true;
updateLedStatus(); //更新Led 状态
/*chc Flashing red change normally on yellow*/
// Flash red when battery is low and not charging
// mBatteryLight.setFlashing(mBatteryLowARGB, Light.LIGHT_FLASH_TIMED,
// mBatteryLedOn, mBatteryLedOff); //低电led模式,闪烁,
mBatteryLight.setFlashing(0xFFFFFF00, Light.LIGHT_FLASH_TIMED,
0, 0); //chc edit to yellow
}
} 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); //设置Led颜色。config.xml可以控制
} else {
updateLedStatus();
// Solid orange when charging and halfway full
mBatteryLight.setColor(mBatteryMediumARGB);
}
} 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 + "<<<<<<<");
}
}
}
}
接下来分析下(6.0)Led应用层设置。
manager = (NotificationManager) this
.getSystemService(NOTIFICATION_SERVICE);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
notification=mBuilder.build();
notification.ledARGB = 0xFFFFFF00;
notification.icon=R.drawable.ic_launcher;
notification.ledOnMS = 200;
notification.ledOffMS = 400;
notification.flags = Notification.FLAG_SHOW_LIGHTS;
manager.notify(0, notification);
应用层是通过notification进行控制led灯的
NotificationManager.java
public void notify(String tag, int id, Notification notification)
{
int[] idOut = new int[1];
INotificationManager service = getService();
String pkg = mContext.getPackageName();
if (notification.sound != null) {
notification.sound = notification.sound.getCanonicalUri();
if (StrictMode.vmFileUriExposureEnabled()) {
notification.sound.checkFileUriExposed("Notification.sound");
}
}
fixLegacySmallIcon(notification, pkg);
if (mContext.getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) { //判断目标SDK版本 6.0必须有icon
if (notification.getSmallIcon() == null) {
throw new IllegalArgumentException("Invalid notification (no valid small icon): "
+ notification);
}
}
if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
Notification stripped = notification.clone();
Builder.stripForDelivery(stripped);
try {
service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
stripped, idOut, UserHandle.myUserId());
if (id != idOut[0]) {
Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]);
}
} catch (RemoteException e) {
}
}
NotificationManagerService.java
@Override
public void enqueueNotificationWithTag(String pkg, String opPkg, String tag, int id,
Notification notification, int[] idOut, int userId) throws RemoteException {
enqueueNotificationInternal(pkg, opPkg, Binder.getCallingUid(),
Binder.getCallingPid(), tag, id, notification, idOut, userId);
}
void enqueueNotificationInternal(final String pkg, final String opPkg, final int callingUid,
final int callingPid, final String tag, final int id, final Notification notification,
int[] idOut, int incomingUserId) {
....在这里对mNotificationList通知消息队列各条通知的优先级,声音进行了相关操
//然后调用
buzzBeepBlinkLocked(r)
....
buzzBeepBlinkLocked(r){
if ((notification.flags & Notification.FLAG_SHOW_LIGHTS) != 0 && aboveThreshold) {
mLights.add(record.getKey());
updateLightsLocked(); //led灯主要操作
if (mUseAttentionLight) {
mAttentionLight.pulse();
}
blink = true;
} else if (wasShowLights) {
updateLightsLocked();
}
}
// lock on mNotificationList
void updateLightsLocked()
{
// handle notification lights
NotificationRecord ledNotification = null;
while (ledNotification == null && !mLights.isEmpty()) {
final String owner = mLights.get(mLights.size() - 1);
ledNotification = mNotificationsByKey.get(owner);
if (ledNotification == null) {
Slog.wtfStack(TAG, "LED Notification does not exist: " + owner);
mLights.remove(owner);
}
}
// Don't flash while we are in a call or screen is on
// if (mLedNotification == null || mInCall || mScreenOn) {
/// M: Add DM/PPL lock related.
//Cuihangchao removed incall state for zed3
if (ledNotification == null /*|| mInCall || mScreenOn */|| mDmLock || mPplLock) { //判断led等什么时候关闭。打电话中,屏幕关闭时候等
mNotificationLight.turnOff();
mStatusBar.notificationLightOff();
Log.d("Cuihangchao","color0");
} else {
Log.d("Cuihangchao","color1");
final Notification ledno = ledNotification.sbn.getNotification();
int ledARGB = ledno.ledARGB;
int ledOnMS = ledno.ledOnMS;
int ledOffMS = ledno.ledOffMS;
if ((ledno.defaults & Notification.DEFAULT_LIGHTS) != 0) {
Log.d("Cuihangchao","color2");
// ledARGB = mDefaultNotificationColor;
ledOnMS = mDefaultNotificationLedOn;
ledOffMS = mDefaultNotificationLedOff;
}
if (mNotificationPulseEnabled) {
Log.d("Cuihangchao","color4="+ledARGB);
// pulse repeatedly
mNotificationLight.setFlashing(ledARGB, Light.LIGHT_FLASH_TIMED,
ledOnMS, ledOffMS); //此处设置led灯
}
// let SystemUI make an independent decision
//mStatusBar.notificationLightPulse(ledARGB, ledOnMS, ledOffMS);
}
}
LightsService.java(设置屏幕亮度,键盘背光相关都在里面)
private void setLightLocked(int color, int mode, int onMS, int offMS, int brightnessMode) {
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);
}
}
}
com_android_server_lights_LightsService.cpp
static void setLight_native(JNIEnv* /* env */, jobject /* clazz */, jlong ptr,
jint light, jint colorARGB, jint flashMode, jint onMS, jint offMS, jint brightnessMode)
{
Devices* devices = (Devices*)ptr;
light_state_t state;
if (light < 0 || light >= LIGHT_COUNT || devices->lights[light] == NULL) {
return ;
}
memset(&state, 0, sizeof(light_state_t));
state.color = colorARGB;
state.flashMode = flashMode;
state.flashOnMS = onMS;
state.flashOffMS = offMS;
state.brightnessMode = brightnessMode;
{
ALOGD_IF_SLOW(50, "Excessive delay setting light");
devices->lights[light]->set_light(devices->lights[light], &state); //通过lights 节点 进行设置
}
}
最后通过hardware检测此节点进行相应设置等颜色的,相关代码
lights.c(vendor/Mediatek/Proprietary/Hardware/Liblights)
以上文件都在Frameworks下面就不一 一的贴路径了
此文到此结束,如发现有错误,请指正