本文主要讲述android 9.0系统对背光的处理,文章分为三点讲述:

1.背光的初始化

2.手动背光调节

3.自动背光调节

一.初始化

1.1 服务的启动(DisplayManagerService)

SystemServer是Android进入Launcher前的最后准备。由其名称就可以看出,它提供了众多由JAVA语言编写的“系统服务”。

一旦我们在init.rc中为Zygote指定了启动参数--start-system-server,那么Zygote Init就会调用startSystemServer来进入SystemServer。

/**

* The main entry point from zygote.

*/

public static void main(String[] args) {

new SystemServer().run();

}

private void run() {

try {

......

// Initialize the system context.

createSystemContext();

// Create the system service manager.

mSystemServiceManager = new SystemServiceManager(mSystemContext);

mSystemServiceManager.setStartInfo(mRuntimeRestart,

mRuntimeStartElapsedTime, mRuntimeStartUptime);

LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);

// Prepare the thread pool for init tasks that can be parallelized

//SystemServerInitThreadPool.get();

} finally {

traceEnd(); // InitBeforeStartServices

}

// Start services.

try {

traceBeginAndSlog("StartServices");

startBootstrapServices();

startCoreServices();

startOtherServices();

SystemServerInitThreadPool.shutdown();

} catch (Throwable ex) {

Slog.e("System", "******************************************");

Slog.e("System", "************ Failure starting system services", ex);

throw ex;

} finally {

traceEnd();

}

.......

// Loop forever.

Looper.loop();

throw new RuntimeException("Main thread loop unexpectedly exited");

}

大部分的服务的起点都在systemserver,背光的服务也不例外。首先创建SystemServiceManager,并将该对象放入一个静态类LocalServices中,这样在systemserver进程中可以直接调用各种静态类中的服务了。然后会调用startBootstrapServices方法,在startBootstrapServices()中启动DisplayManagerService。

private void startBootstrapServices() {

......

// Power manager needs to be started early because other services need it.

// Native daemons may be watching for it to be registered so it must be ready

// to handle incoming binder calls immediately (including being able to verify

// the permissions for those calls).

traceBeginAndSlog("StartPowerManager");

mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);

traceEnd();

......

// Display manager is needed to provide display metrics before package manager

// starts up.

traceBeginAndSlog("StartDisplayManager");

mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);

traceEnd();

......

}

进入SystemServiceManager的startService

public void startService(@NonNull final SystemService service) {

// Register it.

mServices.add(service);

// Start it.

long time = SystemClock.elapsedRealtime();

try {

service.onStart();

} catch (RuntimeException ex) {

throw new RuntimeException("Failed to start service " + service.getClass().getName()

+ ": onStart threw an exception", ex);

}

warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");

}

进入DisplayManagerService的构造方法中,可以看出只是构造一个包含handler的环境

public DisplayManagerService(Context context) {

this(context, new Injector());

}

@VisibleForTesting

DisplayManagerService(Context context, Injector injector) {

super(context);

mInjector = injector;

mContext = context;

mHandler = new DisplayManagerHandler(DisplayThread.get().getLooper());

mUiHandler = UiThread.getHandler();

mDisplayAdapterListener = new DisplayAdapterListener();

mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false);

Resources resources = mContext.getResources();

mDefaultDisplayDefaultColorMode = mContext.getResources().getInteger(

com.android.internal.R.integer.config_defaultDisplayDefaultColorMode);

float[] lux = getFloatArray(resources.obtainTypedArray(

com.android.internal.R.array.config_minimumBrightnessCurveLux));

float[] nits = getFloatArray(resources.obtainTypedArray(

com.android.internal.R.array.config_minimumBrightnessCurveNits));

mMinimumBrightnessCurve = new Curve(lux, nits);

mMinimumBrightnessSpline = Spline.createSpline(lux, nits);

PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);

mGlobalDisplayBrightness = pm.getDefaultScreenBrightnessSetting();

mCurrentUserId = UserHandle.USER_SYSTEM;

}

将该服务添加到SystemServiceManager的内部列表中后,就会服务的onStart方法:

public void onStart() {

// We need to pre-load the persistent data store so it's ready before the default display

// adapter is up so that we have it's configuration. We could load it lazily, but since

// we're going to have to read it in eventually we may as well do it here rather than after

// we've waited for the display to register itself with us.

synchronized(mSyncRoot) {

mPersistentDataStore.loadIfNeeded();

loadStableDisplayValuesLocked();

}

mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS);

publishBinderService(Context.DISPLAY_SERVICE, new BinderService(),

true /*allowIsolated*/);

publishLocalService(DisplayManagerInternal.class, new LocalService());

publishLocalService(DisplayTransformManager.class, new DisplayTransformManager());

}

在DisplayManagerService的onStart方法中,创建了一个LocalService,并将其加入到LocalServices的列表中。LocalService是DisplayManagerInternal的子类,这个DisplayManagerInternal其实是个接口类,LocalService负责实现这几个接口。

1.2 构造服务和环境

系统服务启动成功会调用systemReady()函数。在PowerManagerService中

public void systemReady(IAppOpsService appOps) {

synchronized (mLock) {

mSystemReady = true;

mAppOps = appOps;

mDreamManager = getLocalService(DreamManagerInternal.class);

mDisplayManagerInternal = getLocalService(DisplayManagerInternal.class);

mPolicy = getLocalService(WindowManagerPolicy.class);

mBatteryManagerInternal = getLocalService(BatteryManagerInternal.class);

PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);

mScreenBrightnessSettingMinimum = pm.getMinimumScreenBrightnessSetting();

mScreenBrightnessSettingMaximum = pm.getMaximumScreenBrightnessSetting();

mScreenBrightnessSettingDefault = pm.getDefaultScreenBrightnessSetting();

SensorManager sensorManager = new SystemSensorManager(mContext, mHandler.getLooper());

// The notifier runs on the system server's main looper so as not to interfere

// with the animations and other critical functions of the power manager.

mBatteryStats = BatteryStatsService.getService();

mNotifier = new Notifier(Looper.getMainLooper(), mContext, mBatteryStats,

createSuspendBlockerLocked("PowerManagerService.Broadcasts"), mPolicy);

mWirelessChargerDetector = new WirelessChargerDetector(sensorManager,

createSuspendBlockerLocked("PowerManagerService.WirelessChargerDetector"),

mHandler);

mSettingsObserver = new SettingsObserver(mHandler);

mLightsManager = getLocalService(LightsManager.class);

mAttentionLight = mLightsManager.getLight(LightsManager.LIGHT_ID_ATTENTION);

// Initialize display power management.

mDisplayManagerInternal.initPowerManagement(

mDisplayPowerCallbacks, mHandler, sensorManager);

try {

final ForegroundProfileObserver observer = new ForegroundProfileObserver();

ActivityManager.getService().registerUserSwitchObserver(observer, TAG);

} catch (RemoteException e) {

// Shouldn't happen since in-process.

}

// Go.

readConfigurationLocked();

updateSettingsLocked();

mDirty |= DIRTY_BATTERY_STATE;

updatePowerStateLocked();

}

......

// Register for settings changes.

......

resolver.registerContentObserver(Settings.System.getUriFor(

Settings.System.SCREEN_BRIGHTNESS_MODE),

false, mSettingsObserver, UserHandle.USER_ALL);

resolver.registerContentObserver(Settings.System.getUriFor(

Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ),

false, mSettingsObserver, UserHandle.USER_ALL);

......

}

可以看出在systemReady方法中会获取sensormanager,和lightservice等,最重要的是调用initPowerManagement,从上面的分析可以知道mDisplayManagerInternal其实就是DisplayManagerService.LocalService,其initPowerManagerment方法中创建了DisplayPowerController。

public void initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler,

SensorManager sensorManager) {

synchronized (mSyncRoot) {

DisplayBlanker blanker = new DisplayBlanker() {

@Override

public void requestDisplayState(int state, int brightness) {

// The order of operations is important for legacy reasons.

if (state == Display.STATE_OFF) {

requestGlobalDisplayStateInternal(state, brightness);

}

callbacks.onDisplayStateChange(state);

if (state != Display.STATE_OFF) {

requestGlobalDisplayStateInternal(state, brightness);

}

}

};

mDisplayPowerController = new DisplayPowerController(

mContext, callbacks, handler, sensorManager, blanker);

}

mHandler.sendEmptyMessage(MSG_LOAD_BRIGHTNESS_CONFIGURATION);

}

在DisplayPowerController的构造函数中最重要的是创建一个AutomaticBrightnessController,这个类主要功能是计算自动背光的值,计算好以后配合一个动画类用来实现背光的平稳过度和一个DisplayPowerState类用来控制显示开关和背光和一个light服务用来直接调用底层native方法控制背光。

/**

* Creates the display power controller.

*/

public DisplayPowerController(Context context,

DisplayPowerCallbacks callbacks, Handler handler,

SensorManager sensorManager, DisplayBlanker blanker) {

mHandler = new DisplayControllerHandler(handler.getLooper());

mBrightnessTracker = new BrightnessTracker(context, null);

mSettingsObserver = new SettingsObserver(mHandler);

mCallbacks = callbacks;

mBatteryStats = BatteryStatsService.getService();

mSensorManager = sensorManager;

mWindowManagerPolicy = LocalServices.getService(WindowManagerPolicy.class);

mBlanker = blanker;

mContext = context;

//获取系统关于背光的一些基础参数

final Resources resources = context.getResources();

final int screenBrightnessSettingMinimum = clampAbsoluteBrightness(resources.getInteger(

com.android.internal.R.integer.config_screenBrightnessSettingMinimum));

mScreenBrightnessDozeConfig = clampAbsoluteBrightness(resources.getInteger(

com.android.internal.R.integer.config_screenBrightnessDoze));

mScreenBrightnessDimConfig = clampAbsoluteBrightness(resources.getInteger(

com.android.internal.R.integer.config_screenBrightnessDim));

mScreenBrightnessRangeMinimum =

Math.min(screenBrightnessSettingMinimum, mScreenBrightnessDimConfig);

mScreenBrightnessRangeMaximum = clampAbsoluteBrightness(resources.getInteger(

com.android.internal.R.integer.config_screenBrightnessSettingMaximum));

mScreenBrightnessDefault = clampAbsoluteBrightness(resources.getInteger(

com.android.internal.R.integer.config_screenBrightnessSettingDefault));

mScreenBrightnessForVrRangeMinimum = clampAbsoluteBrightness(resources.getInteger(

com.android.internal.R.integer.config_screenBrightnessForVrSettingMinimum));

mScreenBrightnessForVrRangeMaximum = clampAbsoluteBrightness(resources.getInteger(

com.android.internal.R.integer.config_screenBrightnessForVrSettingMaximum));

mScreenBrightnessForVrDefault = clampAbsoluteBrightness(resources.getInteger(

com.android.internal.R.integer.config_screenBrightnessForVrSettingDefault));

//此处很重要,系统如有背光传感器,则要配置其为true,表明可以使用背光

mUseSoftwareAutoBrightnessConfig = resources.getBoolean(

com.android.internal.R.bool.config_automatic_brightness_available);

mAllowAutoBrightnessWhileDozingConfig = resources.getBoolean(

com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing);

mBrightnessRampRateFast = resources.getInteger(

com.android.internal.R.integer.config_brightness_ramp_rate_fast);

mBrightnessRampRateSlow = resources.getInteger(

com.android.internal.R.integer.config_brightness_ramp_rate_slow);

mSkipScreenOnBrightnessRamp = resources.getBoolean(

com.android.internal.R.bool.config_skipScreenOnBrightnessRamp);

if (mUseSoftwareAutoBrightnessConfig) {

final float dozeScaleFactor = resources.getFraction(

com.android.internal.R.fraction.config_screenAutoBrightnessDozeScaleFactor,

1, 1);

int[] brightLevels = resources.getIntArray(

com.android.internal.R.array.config_dynamicHysteresisBrightLevels);

int[] darkLevels = resources.getIntArray(

com.android.internal.R.array.config_dynamicHysteresisDarkLevels);

int[] luxHysteresisLevels = resources.getIntArray(

com.android.internal.R.array.config_dynamicHysteresisLuxLevels);

HysteresisLevels hysteresisLevels = new HysteresisLevels(

brightLevels, darkLevels, luxHysteresisLevels);

long brighteningLightDebounce = resources.getInteger(

com.android.internal.R.integer.config_autoBrightnessBrighteningLightDebounce);

long darkeningLightDebounce = resources.getInteger(

com.android.internal.R.integer.config_autoBrightnessDarkeningLightDebounce);

boolean autoBrightnessResetAmbientLuxAfterWarmUp = resources.getBoolean(

com.android.internal.R.bool.config_autoBrightnessResetAmbientLuxAfterWarmUp);

int lightSensorWarmUpTimeConfig = resources.getInteger(

com.android.internal.R.integer.config_lightSensorWarmupTime);

int lightSensorRate = resources.getInteger(

com.android.internal.R.integer.config_autoBrightnessLightSensorRate);

int initialLightSensorRate = resources.getInteger(

com.android.internal.R.integer.config_autoBrightnessInitialLightSensorRate);

if (initialLightSensorRate == -1) {

initialLightSensorRate = lightSensorRate;

} else if (initialLightSensorRate > lightSensorRate) {

Slog.w(TAG, "Expected config_autoBrightnessInitialLightSensorRate ("

+ initialLightSensorRate + ") to be less than or equal to "

+ "config_autoBrightnessLightSensorRate (" + lightSensorRate + ").");

}

mBrightnessMapper = BrightnessMappingStrategy.create(resources);

if (mBrightnessMapper != null) {

//创建AutomaticBrightnessController

mAutomaticBrightnessController = new AutomaticBrightnessController(this,

handler.getLooper(), sensorManager, mBrightnessMapper,

lightSensorWarmUpTimeConfig, mScreenBrightnessRangeMinimum,

mScreenBrightnessRangeMaximum, dozeScaleFactor, lightSensorRate,

initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce,

autoBrightnessResetAmbientLuxAfterWarmUp, hysteresisLevels);

} else {

mUseSoftwareAutoBrightnessConfig = false;

}

}

mColorFadeEnabled = !ActivityManager.isLowRamDeviceStatic();

mColorFadeFadesConfig = resources.getBoolean(

com.android.internal.R.bool.config_animateScreenLights);

mDisplayBlanksAfterDozeConfig = resources.getBoolean(

com.android.internal.R.bool.config_displayBlanksAfterDoze);

mBrightnessBucketsInDozeConfig = resources.getBoolean(

com.android.internal.R.bool.config_displayBrightnessBucketsInDoze);

if (!DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) {

mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);

if (mProximitySensor != null) {

mProximityThreshold = Math.min(mProximitySensor.getMaximumRange(),

TYPICAL_PROXIMITY_THRESHOLD);

}

}

mCurrentScreenBrightnessSetting = getScreenBrightnessSetting();

mScreenBrightnessForVr = getScreenBrightnessForVrSetting();

mAutoBrightnessAdjustment = getAutoBrightnessAdjustmentSetting();

mTemporaryScreenBrightness = -1;

mPendingScreenBrightnessSetting = -1;

mTemporaryAutoBrightnessAdjustment = Float.NaN;

mPendingAutoBrightnessAdjustment = Float.NaN;

}

1.3 开机背光的控制

在PowerManagerService的systemReady()中,会调用updatePowerStateLocked()

private void updatePowerStateLocked() {

if (!mSystemReady || mDirty == 0) {

return;

}

if (!Thread.holdsLock(mLock)) {

Slog.wtf(TAG, "Power manager lock was not held when calling updatePowerStateLocked");

}

Trace.traceBegin(Trace.TRACE_TAG_POWER, "updatePowerState");

try {

// Phase 0: Basic state updates.

updateIsPoweredLocked(mDirty);

updateStayOnLocked(mDirty);

updateScreenBrightnessBoostLocked(mDirty);

// Phase 1: Update wakefulness.

// Loop because the wake lock and user activity computations are influenced

// by changes in wakefulness.

final long now = SystemClock.uptimeMillis();

int dirtyPhase2 = 0;

for (;;) {

int dirtyPhase1 = mDirty;

dirtyPhase2 |= dirtyPhase1;

mDirty = 0;

updateWakeLockSummaryLocked(dirtyPhase1);

updateUserActivitySummaryLocked(now, dirtyPhase1);

if (!updateWakefulnessLocked(dirtyPhase1)) {

break;

}

}

// Phase 2: Lock profiles that became inactive/not kept awake.

updateProfilesLocked(now);

// Phase 3: Update display power state.

final boolean displayBecameReady = updateDisplayPowerStateLocked(dirtyPhase2);

// Phase 4: Update dream state (depends on display ready signal).

updateDreamLocked(dirtyPhase2, displayBecameReady);

// Phase 5: Send notifications, if needed.

finishWakefulnessChangeIfNeededLocked();

// Phase 6: Update suspend blocker.

// Because we might release the last suspend blocker here, we need to make sure

// we finished everything else first!

updateSuspendBlockerLocked();

} finally {

Trace.traceEnd(Trace.TRACE_TAG_POWER);

}

}

updatePowerStateLocked()中调用updateDisplayPowerStateLocked()

private boolean updateDisplayPowerStateLocked(int dirty) {

final boolean oldDisplayReady = mDisplayReady;

if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS

| DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED

| DIRTY_SETTINGS | DIRTY_SCREEN_BRIGHTNESS_BOOST | DIRTY_VR_MODE_CHANGED |

DIRTY_QUIESCENT)) != 0) {

mDisplayPowerRequest.policy = getDesiredScreenPolicyLocked();

// Determine appropriate screen brightness and auto-brightness adjustments.

final boolean autoBrightness;

final int screenBrightnessOverride;

if (!mBootCompleted) {

// Keep the brightness steady during boot. This requires the

// bootloader brightness and the default brightness to be identical.

autoBrightness = false;

screenBrightnessOverride = mScreenBrightnessSettingDefault;

} else if (isValidBrightness(mScreenBrightnessOverrideFromWindowManager)) {

autoBrightness = false;

screenBrightnessOverride = mScreenBrightnessOverrideFromWindowManager;

} else {

autoBrightness = (mScreenBrightnessModeSetting ==

Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);

screenBrightnessOverride = -1;

}

// Update display power request.

mDisplayPowerRequest.screenBrightnessOverride = screenBrightnessOverride;

mDisplayPowerRequest.useAutoBrightness = autoBrightness;

mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();

mDisplayPowerRequest.boostScreenBrightness = shouldBoostScreenBrightness();

updatePowerRequestFromBatterySaverPolicy(mDisplayPowerRequest);

if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE) {

mDisplayPowerRequest.dozeScreenState = mDozeScreenStateOverrideFromDreamManager;

if ((mWakeLockSummary & WAKE_LOCK_DRAW) != 0

&& !mDrawWakeLockOverrideFromSidekick) {

if (mDisplayPowerRequest.dozeScreenState == Display.STATE_DOZE_SUSPEND) {

mDisplayPowerRequest.dozeScreenState = Display.STATE_DOZE;

}

if (mDisplayPowerRequest.dozeScreenState == Display.STATE_ON_SUSPEND) {

mDisplayPowerRequest.dozeScreenState = Display.STATE_ON;

}

}

mDisplayPowerRequest.dozeScreenBrightness =

mDozeScreenBrightnessOverrideFromDreamManager;

} else {

mDisplayPowerRequest.dozeScreenState = Display.STATE_UNKNOWN;

mDisplayPowerRequest.dozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT;

}

mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest,

mRequestWaitForNegativeProximity);

mRequestWaitForNegativeProximity = false;

if ((dirty & DIRTY_QUIESCENT) != 0) {

sQuiescent = false;

}

if (DEBUG_SPEW) {

Slog.d(TAG, "updateDisplayPowerStateLocked: mDisplayReady=" + mDisplayReady

+ ", policy=" + mDisplayPowerRequest.policy

+ ", mWakefulness=" + mWakefulness

+ ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary)

+ ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)

+ ", mBootCompleted=" + mBootCompleted

+ ", screenBrightnessOverride=" + screenBrightnessOverride

+ ", useAutoBrightness=" + autoBrightness

+ ", mScreenBrightnessBoostInProgress=" + mScreenBrightnessBoostInProgress

+ ", mIsVrModeEnabled= " + mIsVrModeEnabled

+ ", sQuiescent=" + sQuiescent);

}

}

return mDisplayReady && !oldDisplayReady;

}

调用DisplayManagerService.LocalService的requestPowerState的方法:

@Override

public boolean requestPowerState(DisplayPowerRequest request,

boolean waitForNegativeProximity) {

synchronized (mSyncRoot) {

return mDisplayPowerController.requestPowerState(request,

waitForNegativeProximity);

}

}

然后DisplayPowerController的requestPowerState被调用

public boolean requestPowerState(DisplayPowerRequest request,

boolean waitForNegativeProximity) {

if (DEBUG) {

Slog.d(TAG, "requestPowerState: "

+ request + ", waitForNegativeProximity=" + waitForNegativeProximity);

}

synchronized (mLock) {

boolean changed = false;

if (waitForNegativeProximity

&& !mPendingWaitForNegativeProximityLocked) {

mPendingWaitForNegativeProximityLocked = true;

changed = true;

}

if (mPendingRequestLocked == null) {

mPendingRequestLocked = new DisplayPowerRequest(request);

changed = true;

} else if (!mPendingRequestLocked.equals(request)) {

mPendingRequestLocked.copyFrom(request);

changed = true;

}

if (changed) {

mDisplayReadyLocked = false;

}

if (changed && !mPendingRequestChangedLocked) {

mPendingRequestChangedLocked = true;

sendUpdatePowerStateLocked();

}

return mDisplayReadyLocked;

}

}

然后sendUpdatePowerStateLocked()被触发

private void sendUpdatePowerStateLocked() {

if (!mPendingUpdatePowerStateLocked) {

mPendingUpdatePowerStateLocked = true;

Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE);

mHandler.sendMessage(msg);

}

}

@Override

public void handleMessage(Message msg) {

switch (msg.what) {

case MSG_UPDATE_POWER_STATE:

updatePowerState();

break;

updatePowerState方法很重要,在背光策略里面会经常提到。在updatepowerstate中首先通过initialize方法初始化控制背光的环境,即创建相应的类包括动画控制类等;然后通过configure方法配置是否打开关闭自动背光,也就是要不要打开光感;最后通过animateScreenBrightness来将得到的brightness值配置到底层。

初始化时序图如下图所示:

SequenceDiagram1.png

android 背光控制,Android P背光策略分析(一)相关推荐

  1. android lcd 背光控制流程

    此文章是网上看到的,在MTK平台基础上的背光控制流程的分析.个人觉得写得比较详细,于是截取部分内容转载出来. 不过话说在前头,对于lcd而言,决定显示效果的有几个因素:pwm,gama(屏幕灰度),饱 ...

  2. android背光系统,Android 的背光控制

    Android 背光的控制: 屏幕背光设置 packages/apps/Settings/src/com/android/settings/BrightnessPreference.java 背光设置 ...

  3. android修改自动背光,android 背光控制

    echo 23 > /sys/devices/platform/atmel_lcdfb.0/backlight/backlight/brightness android 源代码 http://b ...

  4. android关闭屏幕背光,Android 的背光控制

    echo 23 > /sys/devices/platform/atmel_lcdfb.0/backlight/backlight/brightness http://android.git.k ...

  5. Android应用开发(21)屏幕背光控制

    Android应用开发学习笔记--目录索引 最近各手机厂商都在宣传万级调光,宣传数字越来越大,但是到底背光调节平滑度体验如何呢? 如最近realme 11 pro+ (MTK平台天玑7050),宣传2 ...

  6. android 自动背光闪烁,Android 背光流程小结

    android背光控制小结,从上到下: ----android---- DisplayPowerController.java--> DisplayPowerState.java:SCREEN_ ...

  7. android 触摸事件 控制,Android笔记:触摸事件的分析与总结----TouchEvent处理机制

    其他相关博文: Android中的事件类型分为按键事件和屏幕触摸事件.TouchEvent是屏幕触摸事件的基础事件,要深入了解屏幕触摸事件的处理机制,就必须掌握TouchEvent在整个触摸事件中的转 ...

  8. Android系统 屏幕最低背光亮度值/最高背光亮度值 调试

    通过 adb 确认合适的 最低背光亮度值/最高背光亮度值 参数 , 并使用万用表量测 背光IC的反馈电阻输出电压确认,具体计算方式根据 背光IC 贴的反馈电阻来计算.(可以找硬件协助 一般是 1.35 ...

  9. Android底层控制系统设置的命令集合

    1.关机    poweroff -f 2.设置系统时间    date -s yyyyMMdd.HHmmss 3.LCD背光开关    echo enable/disable > sys/cl ...

最新文章

  1. Protobuf序列化的原理-字符如何转化为编码
  2. 1.java的基础和数据类型
  3. C语言逆序字符串(递归实现)
  4. Java8中 Date和LocalDateTime的相互转换
  5. GL-关于intercopany 和intracompany 的个人理解
  6. mysql binlog 恢复
  7. 2022最新阿里Java面经,转疯了
  8. 微信开发者模式demo
  9. IDEA绝对好用的十大插件,不接受反驳
  10. 同时删除多个 PDF 中间几页
  11. CSS -- 实现DIV层背景颜色渐变 (兼容IE 火狐 谷歌浏览器)
  12. 物尽其用,数码相机兼职摄像头!
  13. 川土微电子|国产隔离电源数字隔离芯片CA-IS36XX
  14. 服务器虚拟化和网络虚拟化关系,数据中心网络如何应对服务器虚拟化?
  15. 《爆款文案》写文案只需要四个步骤
  16. K8S云原生环境渗透学习
  17. 【Python 第1篇】如何用Python实现简单的文字输出功能
  18. presto sql 求占比--开窗函数解法
  19. 微信分享会根据分享的不同,为原始链接拼接如下参数
  20. Unity3d游戏引擎Windy系列教程:地形的创建

热门文章

  1. XUI 熟练使用之(三) -----------启动页( SimpleGuideBanner的使用)
  2. mariadb galera 故障恢复
  3. 氧化锌@聚丙烯腈(ZnO@PAN)静电纺丝纳米纤维膜材料|金属有机框架材料ZIF-8@聚丙烯腈(ZIF-8@PAN)纳米纤维膜材料
  4. 可截断素数(Truncatable primes)
  5. hdu2191 买大米 多重背包 模板题
  6. 【爬虫笔记】关于Beautiful Soup 4
  7. Winform中pictureBox控件SizeMode属性
  8. 图片压缩-speedpdf免费无损在线压缩图片
  9. VS中报错C4996 怎么办?
  10. 什么是对象、什么是面对对象?