平台

 RK3399 + Android 9.0

概述

 众所周知, Android 平台的上层亮度值的设置值范围为[0, 255], 在9.0之前, 亮度调节一直是线性变化, 在9.0开始, 它变成了曲线变化, 如下图:

         图1-实际亮度值: 11

         图2-实际亮度值: 15

         图3-实际亮度值: 33

         图4-实际亮度值: 105

         图5-实际亮度值: 255

 其中图3最直观体现与线性变化的区别, 进度条在50%以上, 那么实际亮度值应该接近122.

进度条 亮度值
130 11
242 15
541 33
843 105
1023 255

流程

 亮度调节有两个常见的入口: 设置 和 状态栏.

  • 设置

packages/Settings/AndroidManifest.xml

 <activityandroid:name="Settings$DisplaySettingsActivity"android:label="@string/display_settings"android:icon="@drawable/ic_homepage_display"android:taskAffinity="com.android.settings"android:parentActivityName="Settings"><intent-filter android:priority="1"><action android:name="com.android.settings.DISPLAY_SETTINGS" /><action android:name="android.settings.DISPLAY_SETTINGS" /><category android:name="android.intent.category.DEFAULT" /></intent-filter><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.DEFAULT" /><category android:name="android.intent.category.VOICE_LAUNCH" /><category android:name="com.android.settings.SHORTCUT" /></intent-filter><intent-filter android:priority="7"><action android:name="com.android.settings.action.SETTINGS" /></intent-filter><meta-data android:name="com.android.settings.category"android:value="com.android.settings.category.ia.homepage" /><meta-data android:name="com.android.settings.FRAGMENT_CLASS"android:value="com.android.settings.DisplaySettings" /><meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"android:value="true" /><meta-data android:name="com.android.settings.summary"android:resource="@string/display_dashboard_summary"/></activity><!-- Keep compatibility with old shortcuts. --><activity-alias android:name="DisplaySettings"android:label="@string/display_settings"android:exported="true"android:targetActivity="Settings$DisplaySettingsActivity"><meta-data android:name="com.android.settings.FRAGMENT_CLASS"android:value="com.android.settings.DisplaySettings" /></activity-alias>

packages/apps/Settings/src/com/android/settings/DisplaySettings.java

public class DisplaySettings extends DashboardFragment {private static final String TAG = "DisplaySettings";public static final String KEY_DISPLAY_SIZE = "display_settings_screen_zoom";private static final String KEY_SCREEN_TIMEOUT = "screen_timeout";private static final String KEY_AMBIENT_DISPLAY = "ambient_display";private static final String KEY_AUTO_BRIGHTNESS = "auto_brightness_entry";private static final String KEY_NIGHT_DISPLAY = "night_display";private static final String KET_HDMI_SETTINGS = "hdmi_settings";@Overridepublic int getMetricsCategory() {return MetricsEvent.DISPLAY;}@Overrideprotected String getLogTag() {return TAG;}@Overrideprotected int getPreferenceScreenResId() {return R.xml.display_settings;}//...
}

packages/apps/Settings/res/xml/display_settings.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 The Android Open Source ProjectLicensed 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 athttp://www.apache.org/licenses/LICENSE-2.0Unless required by applicable law or agreed to in writing, softwaredistributed 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 andlimitations under the License.
--><PreferenceScreenxmlns:android="http://schemas.android.com/apk/res/android"xmlns:settings="http://schemas.android.com/apk/res-auto"android:key="display_settings_screen"android:title="@string/display_settings"settings:keywords="@string/keywords_display"settings:initialExpandedChildrenCount="4"><com.android.settingslib.RestrictedPreferenceandroid:key="brightness"android:title="@string/brightness"settings:keywords="@string/keywords_display_brightness_level"settings:useAdminDisabledSummary="true"settings:userRestriction="no_config_brightness"><intent android:action="com.android.intent.action.SHOW_BRIGHTNESS_DIALOG" /></com.android.settingslib.RestrictedPreference>....

 当点击亮度设置后, 会打开亮度调节窗口:
com.android.intent.action.SHOW_BRIGHTNESS_DIALOG
 参照下面状态栏部分

frameworks/base/packages/SystemUI/AndroidManifest.xml

        <activityandroid:name=".settings.BrightnessDialog"android:label="@string/quick_settings_brightness_dialog_title"android:theme="@*android:style/Theme.DeviceDefault.QuickSettings.Dialog"android:finishOnCloseSystemDialogs="true"android:launchMode="singleInstance"android:excludeFromRecents="true"android:exported="true"><intent-filter><action android:name="com.android.intent.action.SHOW_BRIGHTNESS_DIALOG" /><category android:name="android.intent.category.DEFAULT" /></intent-filter></activity>
  • 状态栏

frameworks/base/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java

/** Copyright (C) 2013 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.systemui.settings;import android.app.Activity;
import android.os.Bundle;
import android.view.ContextThemeWrapper;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.R;/** A dialog that provides controls for adjusting the screen brightness. */
public class BrightnessDialog extends Activity {private BrightnessController mBrightnessController;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);final Window window = getWindow();window.setGravity(Gravity.TOP);window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);window.requestFeature(Window.FEATURE_NO_TITLE);// Use a dialog theme as the activity theme, but inflate the content as// the QS content.ContextThemeWrapper themedContext = new ContextThemeWrapper(this,com.android.internal.R.style.Theme_DeviceDefault_QuickSettings);View v = LayoutInflater.from(themedContext).inflate(R.layout.quick_settings_brightness_dialog, null);setContentView(v);final ImageView icon = findViewById(R.id.brightness_icon);final ToggleSliderView slider = findViewById(R.id.brightness_slider);mBrightnessController = new BrightnessController(this, icon, slider);}@Overrideprotected void onStart() {super.onStart();mBrightnessController.registerCallbacks();MetricsLogger.visible(this, MetricsEvent.BRIGHTNESS_DIALOG);}@Overrideprotected void onStop() {super.onStop();MetricsLogger.hidden(this, MetricsEvent.BRIGHTNESS_DIALOG);mBrightnessController.unregisterCallbacks();}@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN|| keyCode == KeyEvent.KEYCODE_VOLUME_UP|| keyCode == KeyEvent.KEYCODE_VOLUME_MUTE) {finish();}return super.onKeyDown(keyCode, event);}
}

 UI部分主要就一个ToggleSliderView, 主要的一些逻辑操作都放在BrightnessController中, 进度条变化后的回调函数:

frameworks/base/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java

    @Overridepublic void onChanged(ToggleSlider toggleSlider, boolean tracking, boolean automatic,int value, boolean stopTracking) {updateIcon(mAutomatic);if (mExternalChange) return;if (mSliderAnimator != null) {mSliderAnimator.cancel();}final int min;final int max;final int metric;final String setting;if (mIsVrModeEnabled) {metric = MetricsEvent.ACTION_BRIGHTNESS_FOR_VR;min = mMinimumBacklightForVr;max = mMaximumBacklightForVr;setting = Settings.System.SCREEN_BRIGHTNESS_FOR_VR;} else {metric = mAutomatic? MetricsEvent.ACTION_BRIGHTNESS_AUTO: MetricsEvent.ACTION_BRIGHTNESS;min = mMinimumBacklight;max = mMaximumBacklight;setting = Settings.System.SCREEN_BRIGHTNESS;}final int val = convertGammaToLinear(value, min, max);if (stopTracking) {MetricsLogger.action(mContext, metric, val);}setBrightness(val);if (!tracking) {AsyncTask.execute(new Runnable() {public void run() {Settings.System.putIntForUser(mContext.getContentResolver(),setting, val, UserHandle.USER_CURRENT);}});}for (BrightnessStateChangeCallback cb : mChangeCallbacks) {cb.onBrightnessLevelChanged();}}

 转换曲线: convertGammaToLinear(value, min, max); 和 convertLinearToGamma(int val, int min, int max)

frameworks/base/packages/SettingsLib/src/com/android/settingslib/display/BrightnessUtils.java

/** Copyright (C) 2018 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.settingslib.display;import android.util.MathUtils;public class BrightnessUtils {public static final int GAMMA_SPACE_MAX = 1023;public static final boolean ENABLE_GAMMA = false;// Hybrid Log Gamma constant valuesprivate static final float R = 0.5f;private static final float A = 0.17883277f;private static final float B = 0.28466892f;private static final float C = 0.55991073f;/*** A function for converting from the gamma space that the slider works in to the* linear space that the setting works in.** The gamma space effectively provides us a way to make linear changes to the slider that* result in linear changes in perception. If we made changes to the slider in the linear space* then we'd see an approximately logarithmic change in perception (c.f. Fechner's Law).** Internally, this implements the Hybrid Log Gamma electro-optical transfer function, which is* a slight improvement to the typical gamma transfer function for displays whose max* brightness exceeds the 120 nit reference point, but doesn't set a specific reference* brightness like the PQ function does.** Note that this transfer function is only valid if the display's backlight value is a linear* control. If it's calibrated to be something non-linear, then a different transfer function* should be used.** @param val The slider value.* @param min The minimum acceptable value for the setting.* @param max The maximum acceptable value for the setting.* @return The corresponding setting value.*/public static final int convertGammaToLinear(int val, int min, int max) {final float normalizedVal = MathUtils.norm(0, GAMMA_SPACE_MAX, val);final float ret;if (normalizedVal <= R) {ret = MathUtils.sq(normalizedVal / R);} else {ret = MathUtils.exp((normalizedVal - C) / A) + B;}// HLG is normalized to the range [0, 12], so we need to re-normalize to the range [0, 1]// in order to derive the correct setting value.return Math.round(MathUtils.lerp(min, max, ret / 12));}/*** A function for converting from the linear space that the setting works in to the* gamma space that the slider works in.** The gamma space effectively provides us a way to make linear changes to the slider that* result in linear changes in perception. If we made changes to the slider in the linear space* then we'd see an approximately logarithmic change in perception (c.f. Fechner's Law).** Internally, this implements the Hybrid Log Gamma opto-electronic transfer function, which is* a slight improvement to the typical gamma transfer function for displays whose max* brightness exceeds the 120 nit reference point, but doesn't set a specific reference* brightness like the PQ function does.** Note that this transfer function is only valid if the display's backlight value is a linear* control. If it's calibrated to be something non-linear, then a different transfer function* should be used.** @param val The brightness setting value.* @param min The minimum acceptable value for the setting.* @param max The maximum acceptable value for the setting.* @return The corresponding slider value*/public static final int convertLinearToGamma(int val, int min, int max) {// For some reason, HLG normalizes to the range [0, 12] rather than [0, 1]final float normalizedVal = MathUtils.norm(min, max, val) * 12;final float ret;if (normalizedVal <= 1f) {ret = MathUtils.sqrt(normalizedVal) * R;} else {ret = A * MathUtils.log(normalizedVal - B) + C;}return Math.round(MathUtils.lerp(0, GAMMA_SPACE_MAX, ret));}
}

  • 设置/写入:
    进度条进度 -> convertGammaToLinear -> Settings.System.put

  • 读取
    Settings.System.get -> convertLinearToGamma -> 设置进度条进度

去除曲线功能

 增加ENABLE_GAMMA控制

frameworks/base/packages/SettingsLib/src/com/android/settingslib/display/BrightnessUtils.java

@@ -21,6 +21,7 @@ import android.util.MathUtils;public class BrightnessUtils {public static final int GAMMA_SPACE_MAX = 1023;
+    public static final boolean ENABLE_GAMMA = false;// Hybrid Log Gamma constant valuesprivate static final float R = 0.5f;
@@ -51,6 +52,11 @@ public class BrightnessUtils {* @return The corresponding setting value.*/public static final int convertGammaToLinear(int val, int min, int max) {+        if(!ENABLE_GAMMA){+            float ratio = (float)val / GAMMA_SPACE_MAX;
+            return min + (int)(ratio * (max - min));
+        }
+        final float normalizedVal = MathUtils.norm(0, GAMMA_SPACE_MAX, val);final float ret;if (normalizedVal <= R) {@@ -87,6 +93,11 @@ public class BrightnessUtils {* @return The corresponding slider value*/public static final int convertLinearToGamma(int val, int min, int max) {+        if(!ENABLE_GAMMA){+            float ratio = (float)(val - min)/ (max - min);
+            return (int)(ratio * GAMMA_SPACE_MAX);
+        }
+

 编译相关模块, 如: SettingsLib, Settings, SystemUI, 重新make install clean 和 make

扩展

  • 编译失败:
    mmm frameworks/base/packages/SystemUI/ -j2
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=9
TARGET_PRODUCT=rk3399
TARGET_BUILD_VARIANT=userdebug
TARGET_BUILD_TYPE=release
TARGET_ARCH=arm64
TARGET_ARCH_VARIANT=armv8-a
TARGET_CPU_VARIANT=cortex-a53
TARGET_2ND_ARCH=arm
TARGET_2ND_ARCH_VARIANT=armv7-a-neon
TARGET_2ND_CPU_VARIANT=cortex-a15
HOST_ARCH=x86_64
HOST_2ND_ARCH=x86
HOST_OS=linux
HOST_OS_EXTRA=Linux-4.4.0-142-generic-x86_64-Ubuntu-16.04.6-LTS
HOST_CROSS_OS=windows
HOST_CROSS_ARCH=x86
HOST_CROSS_2ND_ARCH=x86_64
HOST_BUILD_TYPE=release
BUILD_ID=PI
OUT_DIR=out
============================================
ninja: no work to do.
ninja: no work to do.
out/build-rk3399-_frameworks_base_packages_SystemUI_Android.mk-cleanspec.ninja is missing, regenerating...
out/build-rk3399-_frameworks_base_packages_SystemUI_Android.mk.ninja is missing, regenerating...
ninja: error: 'out/target/common/obj/JAVA_LIBRARIES/metrics-helper-lib_intermediates/classes-header.jar', needed by 'out/target/common/obj/APPS/SystemUISharedLibTests_intermediates/classes-full-debug.jar', missing and no known rule to make it
14:37:27 ninja failed with: exit status 1#### failed to build some targets (59 seconds) ####

原因: 单编有依赖, 改用 mmma

  • 注意加上LOG打印, 以验证修改生效

Android 9.0 亮度调节的变化(伽马曲线)相关推荐

  1. android 7.0 短信监控,Android 7.0 监听网络变化的示例代码

    Android7.0前,Android系统前网络切换时,会发广播,业务只要监听广播即可. public class NetChangeReceiver extends BroadcastReceive ...

  2. android护目镜软件,亮度调节护目镜

    还在为看手机伤眼睛而担忧吗?快来使用亮度调节护目镜吧!亮度调节护目镜app软件中包含了护眼模式,开启护眼模式后,不管是夜间.阅读还是游戏.影音都能有效的保护你的眼睛,还会有疲劳提醒,为你的眼睛健康着想 ...

  3. android 9.0背光调节流程

    1.背光服务框架 如下图是背光框架层图 2.UML时序图 这里主要标出的是各个服务或者框架层之间连接的api,中间会省略一些调用流程. 如下图,PowerManagerService会监听Settin ...

  4. android系统屏幕亮度调节

    在$SDK/frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java中修改,PhoneWi ...

  5. Android 5.0有哪些变化

    Android 5.0 Changes 译自 http://developer.android.com/intl/zh-cn/about/versions/android-5.0-changes.ht ...

  6. android5.0+art模式,Android 5.0有哪些变化

    Android 5.0 Changes 前排渣翻译预警,如果你能提供更好更专业的翻译或者提出修改意见就好了-- 另外本篇只对Android 5.0特性作了说明,至于对应的API方面的变化,参考下一篇: ...

  7. Android 7.0真实上手体验

    Android 7.0真实上手体验 Android 7.0的首个开发者预览版发布了,支持的设备只有Nexus6.Nexus 5X.Nexus 6P.Nexus 9.Nexus Player.Pixel ...

  8. Android 3.0细节曝光:Google程序更耀眼

    来源:腾讯科技   发布者:腾讯科技 Phandroid 网站今天披露了Android 3.0(Gingerbread)的一些细节.新系统仍在开发之中,不过有些 Google 员工已经在自己的 Nex ...

  9. android 5.0 新功能,Android 5.0新特性有哪些?安卓5.0新功能汇总

    Android 5.0新特性有哪些?经过一段时间曝光与测试后,期待已久的Android L系统正式发布了,新一代安卓系统正式名称为Android 5.0 Lollipop(棒棒糖).Android 5 ...

最新文章

  1. 【BZOJ4282】慎二的随机数列 乱搞
  2. 【Tools】CSDN中如何添加数学公式
  3. wcf简单的创建和运用
  4. 编译Ruby2.0 问题解决
  5. hadoop退出安全模式Name node is in safe mode
  6. 工厂模式之消除switch/case语句
  7. Express入门 模板引擎hbs 服务端渲染
  8. 二级分类php代码,php smarty 二级分类代码和模版循环例子
  9. python log模块
  10. 凯撒密码中有数字怎么办_古典密码
  11. 构建一个可行的BI系统的造价是多少,实施周期?具备条件基础是什么? 数据量有要求么
  12. Android笔记-Felix
  13. [Day 7]JS FA、用户交互、JS动画的实现(二)
  14. vue导入excel进度条_vue中使用excel导入导出
  15. 验证哥德巴赫猜想:任何一个大于等于6的偶数均可表示为两个素数的和。如6=3+3,8=3+5,,18=5+13。试编写程序,要求将输入的一个偶数表示成两个素数之和。 输入输出样例如下:
  16. Kubernetes全栈架构师(资源调度下)--学习笔记
  17. 实时传输协议:RTP、RTCP、RTSP介绍
  18. 视觉slam14讲学习(一)之se3上的定位表示:轨迹显示与轨迹误差
  19. 在CDH集群安装Flink
  20. 系统特征根_20160204

热门文章

  1. 做ppt课件直播时如何解决ppt表格内容无法加载问题
  2. matlab求三圆相交面积,matlab求n个相交圆的面积
  3. 字符指针变量和字符数组的比较
  4. Java,Python和大数据,哪个发展前景最好
  5. 苹果系统(MacOS)无法下载Android SDK或下载缓慢解决办法
  6. 淘宝/天猫搜索店铺列表 API 返回值说明
  7. Linux网桥配置及应用
  8. 学习笔记——RSA加密签名
  9. 稳定性系列文章1-如何评价系统稳定性?
  10. python可以实现手机定位吗_用Python实现通讯定位功能——PYBOARD V702评测