Android 6.0(M) BatteryService浅析及充电呼吸灯流程浅析 MTK

参考博文:
http://www.cnblogs.com/flyme/archive/2011/07/27/2118541.html
http://blog.csdn.net/kc58236582/article/details/45647181

  1. 启动BatteryService
    电池的信息,电压,温度,充电状态等等,都是由BatteryService来提供的。BatteryService是跑在system_process当中,在系统初始化的时候启动,如下
    在SystemServer.java (frameworks/base/services/java/com/android/server/SystemServer.java)中可以看到启动BatteryService的代码:
/**
     * 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);
    }
  1. BattryService (frameworks/base/services/core/java/com/android/server/BatteryService.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");
        }
    }
  1. onstart函数将电池监听注册到底层去。
   /**
      * 将电池监听注册到底层去
      */
    @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;
}

欢迎关注我的微信公众号
欢迎关注我的公众号[Gee丶kk]一起探讨技术

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值