平台

 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. MobileNetV2-YoloV3
  2. 【刘文彬】区块链3.0:拥抱EOS
  3. 【CV】54篇最新CV领域综述论文速递!涵盖14个方向:目标检测/图像分割/医学影像/人脸识别等方向...
  4. 分辨出谁在浏览Youtube、土豆
  5. spring boot actuator 入门荔枝
  6. [dp]最长单调递增子序列LIS
  7. linux man使用方法 和centos安装中文man包
  8. 折半枚举(双向搜索)
  9. EIGRP MD5认证实例
  10. Mac如何关闭开机启动项?
  11. 设置透明主题引起动画失效以及打开其他应用闪现桌面图标的问题
  12. MATLAB 插值+计算离散点曲率
  13. 计算机字号调整,解答如何调整电脑字体大小
  14. db2 日期英式写法_英文日期写法 英文日期格式正确写法
  15. 九、51单片机之直流电机驱动
  16. 关闭mac开机当的一声的终极方法
  17. 关于C语言中“x++”和“++x”的问题
  18. Matlab绘图常用设置及函数
  19. Java 中的 getResource 方法
  20. mysql导入excel

热门文章

  1. 智能车学习(二十三)——浅谈心得体会
  2. C++游戏系列2:角色装备武器
  3. 直播、P2P、共享经济,这些互联网风口催生的创业大潮
  4. idea抽风了_Run和Debug变成了灰色的不可用了---springCloud工作笔记170
  5. raspberry 3B 编译 NCNN
  6. 完整安卓客户端服务器项目,【三级项目】TCP网络通信的服务器端及安卓端的实现...
  7. 传统机器学习模型解说01:一元线性回归模型
  8. 机器学习——神经网络(Neural Network)
  9. JAVA FEL表达式的使用
  10. 计算机考试属于相对性评价还是绝对性评价,相对性评价和绝对性评价