当前位置:   article > 正文

屏幕亮度调节—基于Android_6.0(代码源于Google)_高通 public void setbrightness(float brightness, int

高通 public void setbrightness(float brightness, int brightnessmode)

屏幕亮度调节

对于屏幕亮度调节 framework层已经有很多文章,再次主要分析一下hal层。

####1、Framework层主要文件BrightnessController.java
#####1.1、文件位置
frameworks/base/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java

#####1.2、主思路代码追踪

 public void onChanged(ToggleSlider view, boolean tracking, boolean automatic, int value,
            boolean stopTracking) {
        updateIcon(mAutomatic);
        if (mExternalChange) return;

        if (!mAutomatic) {
            final int val = value + mMinimumBacklight;
            if (stopTracking) {
                MetricsLogger.action(mContext, MetricsEvent.ACTION_BRIGHTNESS, val);
            }
            setBrightness(val);
            if (!tracking) {
                AsyncTask.execute(new Runnable() {
                        public void run() {
                            Settings.System.putIntForUser(mContext.getContentResolver(),
                                    Settings.System.SCREEN_BRIGHTNESS, val,
                                    UserHandle.USER_CURRENT);
                        }
                    });
            }
        } else {
            final float adj = value / (BRIGHTNESS_ADJ_RESOLUTION / 2f) - 1;
            if (stopTracking) {
                MetricsLogger.action(mContext, MetricsEvent.ACTION_BRIGHTNESS_AUTO, value);
            }
            setBrightnessAdj(adj);
            if (!tracking) {
                AsyncTask.execute(new Runnable() {
                    public void run() {
                        Settings.System.putFloatForUser(mContext.getContentResolver(),
                                Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, adj,
                                UserHandle.USER_CURRENT);
                    }
                });
            }
        }

        for (BrightnessStateChangeCallback cb : mChangeCallbacks) {
            cb.onBrightnessLevelChanged();
        }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

当它获取到 设置的 brightness 的值之后,主要调用函数 setbrightness() 函数。通过该服务调用底层与设备打交道的C/C++代码,setLightBrightnes原型如下:

####2、跳转到 LightsService.java

#####2.1、文件位置
frameworks/base/services/core/java/com/android/server/lights/LightsService.java

#####2.2、主要代码分析

 public void setBrightness(int brightness, int brightnessMode) {
            synchronized (this) {
                int color = brightness & 0x000000ff;
                color = 0xff000000 | (color << 16) | (color << 8) | color;
                setLightLocked(color, LIGHT_FLASH_NONE, 0, 0, brightnessMode);
                }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

亮度值在此进行了修改,即亮度值的格式变成:FFRRGGBB,FF是没有的,RR、GG、BB分别是256色的红绿蓝,并且红绿蓝的值都是一样的亮度值。

####3、硬件调用 接口com_android_server_lights_LightsService.cpp

#####3.1、文件位置
frameworks/base/services/core/jni/com_android_server_lights_LightsService.cpp

#####3.2、主要代码分析

static jlong init_native(JNIEnv* /* env */, jobject /* clazz */)
{
    int err;
    hw_module_t* module;
    Devices* devices;
    
    devices = (Devices*)malloc(sizeof(Devices));

    err = hw_get_module(LIGHTS_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
    if (err == 0) {
        devices->lights[LIGHT_INDEX_BACKLIGHT]
                = get_device(module, LIGHT_ID_BACKLIGHT);
        devices->lights[LIGHT_INDEX_KEYBOARD]
                = get_device(module, LIGHT_ID_KEYBOARD);
        devices->lights[LIGHT_INDEX_BUTTONS]
                = get_device(module, LIGHT_ID_BUTTONS);
        devices->lights[LIGHT_INDEX_BATTERY]
                = get_device(module, LIGHT_ID_BATTERY);
        devices->lights[LIGHT_INDEX_NOTIFICATIONS]
                = get_device(module, LIGHT_ID_NOTIFICATIONS);
        devices->lights[LIGHT_INDEX_ATTENTION]
                = get_device(module, LIGHT_ID_ATTENTION);
        devices->lights[LIGHT_INDEX_BLUETOOTH]
                = get_device(module, LIGHT_ID_BLUETOOTH);
        devices->lights[LIGHT_INDEX_WIFI]
                = get_device(module, LIGHT_ID_WIFI);
    } else {
        memset(devices, 0, sizeof(Devices));
    }

    return (jlong)devices;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

用hw_get_module获取ID为LIGHTS_HARDWARE_MODULE_ID的硬件模块,该模块含有6个不同类型的亮度控制。

####4、hardware.c 实现 hw_get_module()函数
#####4.1、文件位置
hardware/libhardware/hardware.c

#####4.2、主要代码分析
static const char variant_keys[] = {
“ro.hardware”, /
This goes first so that it can pick up a different
file on the emulator. */
“ro.product.board”,
“ro.board.platform”,
“ro.arch”
};

  /* Loop through the configuration variants looking for a module */
    for (i=0 ; i<HAL_VARIANT_KEYS_COUNT; i++) {
        if (property_get(variant_keys[i], prop, NULL) == 0) {
            continue;
        }
        if (hw_module_exists(path, sizeof(path), name, prop) == 0) {
            goto found;
        }
    }

    /* Nothing found, try the default */
    if (hw_module_exists(path, sizeof(path), name, "default") == 0) {
        goto found;
    }

    return -ENOENT;

found:
    /* load the module, if this fails, we're doomed, and we should not try
     * to load a different variant. */
    return load(class_id, path, module);
}````````

property_get(variant_keys[i], prop, NULL) 会按如下顺序去获取如下变量所对应的值,然后返回给prop:

"ro.hardware",  /* This goes first so that it can pick up a different

                       file on the emulator. */

    "ro.product.board",

    "ro.board.platform",

"ro.arch"

它们对应的变量为:

"ro.product.board=$TARGET_BOOTLOADER_BOARD_NAME"

"ro.board.platform=$TARGET_BOARD_PLATFORM"


如vendor/htc/dream-open/BoardConfig.mk里定义的TARGET_BOARD_PLATFORM := msm7k,则prop返回” msm7k ”,所以path = /system/lib/hw/lights. msm7k.so,也就是说要获取的硬件模块为lights. msm7k.so。

(此处可自己定义,不一定需要在BoardConfig.mk中  比如在 :device/项目名/项目名 / device.mk  中 

```


PRODUCT_PACKAGES += \
	logFileManager

#add lights HAL for adjust backlight
PRODUCT_PACKAGES += lights.abc(项目名或板子名字)
PRODUCT_PROPERTY_OVERRIDES += ro.hardware.lights=abc(项目名或板子名字)

# SIM Toolkit
PRODUCT_PACKAGES += \
    Stk

```


    比如vendor/htc/dream-open/BoardConfig.mk里定义的TARGET_BOARD_PLATFORM := msm7k  ,则prop返回” msm7k ”,所以path = /system/lib/hw/lights. msm7k.so,也就是说要获取的硬件模块为lights. msm7k.so。 


####5、硬件原型 lights.c  及 android.mk文件
#####5.1、文件位置

/hardware/qcom/display/项目名/liblight/Android.mk  





```

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

# HAL module implemenation, not prelinked and stored in
# hw/<COPYPIX_HARDWARE_MODULE_ID>.<ro.board.platform>.so

LOCAL_SRC_FILES := lights.c

LOCAL_MODULE_RELATIVE_PATH := hw

LOCAL_MODULE_TAGS := optional

LOCAL_SHARED_LIBRARIES := liblog

LOCAL_MODULE := lights.(项目名)

include $(BUILD_SHARED_LIBRARY)
```

hardware/qcom/display/项目名/liblight/lights.c

```
/*
 * Copyright (C) 2014 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.
 */

#define LOG_TAG "lights"

#include <cutils/log.h>

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>

#include <sys/ioctl.h>
#include <sys/types.h>

#include <hardware/lights.h>
#include <hardware/hardware.h>

#define ALOG_ONCE(mask, op, ...)			\
	do {					\
		{		\
			ALOGE(__VA_ARGS__);	\
			mask |= op;		\
		}				\
	} while (0);
#define OP_WRITE_OPEN		(1 << 0)
#define OP_BRIGHTNESS_PATH	(1 << 1)
#define OP_BRIGHTNESS_VALUE	(1 << 2)
#define OP_BRIGHTNESS_WRITE	(1 << 3)
#define OP_MAX_BRIGHTNESS_PATH	(1 << 4)
#define OP_MAX_BRIGHTNESS_OPEN	(1 << 5)
#define OP_MAX_BRIGHTNESS_READ	(1 << 6)

struct dragon_lights {
	struct light_device_t base;

	pthread_mutex_t lock;
	char const *sysfs_path;

	int max_brightness;

	unsigned long logged_failures;
};

static char const * kBacklightPath =
	"/sys/class/backlight/pwm-backlight.0";  (注意此位置不同的设备可能有不同的设备节点)


static struct dragon_lights *to_dragon_lights(struct light_device_t *dev)
{
	return (struct dragon_lights *)dev;
}

static int write_brightness(struct dragon_lights *lights, int brightness)
{
	char buffer[20], path[PATH_MAX];
	int fd, bytes, amt, ret = 0;


	ALOGI("LIGHTS write_brightness %d", brightness);

	bytes = snprintf(path, sizeof(path), "%s/brightness",
			 lights->sysfs_path);
	if (bytes < 0 || (size_t)bytes >= sizeof(path)) {
		ALOG_ONCE(lights->logged_failures, OP_BRIGHTNESS_PATH,
			  "failed to create brightness path %d\n", bytes);
		return -EINVAL;
	}

	fd = open(path, O_RDWR);
	if (fd < 0) {
		ALOG_ONCE(lights->logged_failures, OP_WRITE_OPEN,
			  "write_int failed to open %s/%d\n", path, errno);
		return -errno;
	}

	bytes = snprintf(buffer, sizeof(buffer), "%d\n", brightness);
	if (bytes < 0 || (size_t)bytes >= sizeof(buffer)) {
		ALOG_ONCE(lights->logged_failures, OP_BRIGHTNESS_VALUE,
			  "failed to create brightness value %d/%d\n",
			  brightness, bytes);
		ret = -EINVAL;
		goto out;
	}
	amt = write(fd, buffer, bytes);
	if (amt != bytes) {
		ALOG_ONCE(lights->logged_failures, OP_BRIGHTNESS_WRITE,
			  "failed to write brightness value %d/%d\n", amt,
			  bytes);
		ret = amt == -1 ? -errno : -EINVAL;
		goto out;
	}

out:
	close(fd);
	return ret;
}

static int read_max_brightness(struct dragon_lights *lights, int *value)
{
	char buffer[20], path[PATH_MAX];
	int ret = 0, fd, bytes;

	bytes = snprintf(path, sizeof(path), "%s/max_brightness",
			 lights->sysfs_path);
	if (bytes < 0 || (size_t)bytes >= sizeof(path)) {
		ALOG_ONCE(lights->logged_failures, OP_MAX_BRIGHTNESS_PATH,
			  "failed to create max_brightness path %d\n", bytes);
		return -EINVAL;
	}

	fd = open(path, O_RDONLY);
	if (fd < 0) {
		ALOG_ONCE(lights->logged_failures, OP_MAX_BRIGHTNESS_OPEN,
			  "failed to open max_brightness %s/%d\n", path, errno);
		return -errno;
	}

	bytes = read(fd, buffer, sizeof(buffer));
	if (bytes <= 0) {
		ALOG_ONCE(lights->logged_failures, OP_MAX_BRIGHTNESS_READ,
			  "failed to read max_brightness %s/%d\n", path, errno);
		ret = -errno;
		goto out;
	}

	*value = atoi(buffer);

out:
	close(fd);
	return ret;
}

static int rgb_to_brightness(struct light_state_t const *state)
{
	int color = state->color & 0x00ffffff;
	return ((77 * ((color >> 16) & 0x00ff))
			+ (150 * ((color >> 8) & 0x00ff)) +
			(29 * (color & 0x00ff))) >> 8;
}

static int set_light_backlight(struct light_device_t *dev,
			       struct light_state_t const *state)
{
	struct dragon_lights *lights = to_dragon_lights(dev);
	int err, brightness_idx;
	int brightness = rgb_to_brightness(state);

	if(brightness < 0){
		brightness = 0;
	}

	if(brightness >255){
		brightness = 255;
	}


	pthread_mutex_lock(&lights->lock);
	err = write_brightness(lights, brightness);
	pthread_mutex_unlock(&lights->lock);

	return err;
}

static int close_lights(struct hw_device_t *dev)
{
	struct dragon_lights *lights = (struct dragon_lights *)dev;
	if (lights)
		free(lights);
	return 0;
}

static int open_lights(const struct hw_module_t *module, char const *name,
		       struct hw_device_t **device)
{
	struct dragon_lights *lights;
	int ret;

	// Only support backlight at the moment
	if (strcmp(LIGHT_ID_BACKLIGHT, name))
		return -EINVAL;

	lights = malloc(sizeof(*lights));
	if (lights == NULL) {
		ALOGE("failed to allocate lights memory");
		return -ENOMEM;
	}
	memset(lights, 0, sizeof(*lights));

	pthread_mutex_init(&lights->lock, NULL);

	lights->sysfs_path = kBacklightPath;

	ret = read_max_brightness(lights, &lights->max_brightness);
	if (ret) {
		close_lights((struct hw_device_t *)lights);
		return ret;
	}

	lights->base.common.tag = HARDWARE_DEVICE_TAG;
	lights->base.common.version = 0;
	lights->base.common.module = (struct hw_module_t *)module;
	lights->base.common.close = close_lights;
	lights->base.set_light = set_light_backlight;

	*device = (struct hw_device_t *)lights;
	return 0;
}

static struct hw_module_methods_t lights_methods = {
	.open =  open_lights,
};

struct hw_module_t HAL_MODULE_INFO_SYM = {
	.tag = HARDWARE_MODULE_TAG,
	.version_major = 1,
	.version_minor = 0,
	.id = LIGHTS_HARDWARE_MODULE_ID,
	.name = "jindory lights module",
	.author = "thundersoft",
	.methods = &lights_methods,
};

```


文件参考:

1、 android 设置系统屏幕亮度 
http://blog.csdn.net/zhuangxujun/article/details/8601392#comments
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/642925
推荐阅读
相关标签
  

闽ICP备14008679号