MTK 6.0 充电Led灯分析

作者: Exception_Cui | 来源:发表于2017-04-17 13:07 被阅读544次

    最近客户对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下面就不一 一的贴路径了
    此文到此结束,如发现有错误,请指正

    相关文章

      网友评论

      本文标题:MTK 6.0 充电Led灯分析

      本文链接:https://www.haomeiwen.com/subject/mnctzttx.html