1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "light"
18
19 #include <android-base/file.h>
20 #include <hardware/lights.h>
21 #include <log/log.h>
22
23 #include "LightExt.h"
24
25 namespace hardware {
26 namespace google {
27 namespace light {
28 namespace V1_1 {
29 namespace implementation {
30 using ::android::hardware::light::V2_0::Brightness;
31
32 #define HBM_OFF "0"
33 #define HBM_ON "1"
34 #define HBM_SV "2"
35
applyHBM()36 Return<Status> LightExt::applyHBM() {
37 if (!mHasHbmNode) return Status::UNKNOWN;
38
39 /* skip if no change */
40 if (mRegHBM == mCurHBM && mRegHBMSV == mCurHBMSV) return Status::SUCCESS;
41
42 // off
43 // <--------
44 // 0,0 --------> 0,1
45 // | ^ sv ^ |
46 // hbm| | off nop| |nop
47 // V | sv | V
48 // 1,0 --------> 1,1
49 // <--------
50 // hbm
51
52 // Transition from (mCurHBM, mCurHBMSV) --> (mRegHBM, mRegHBMSV)
53 const char *action = NULL;
54
55 if (!mRegHBM && !mRegHBMSV) {
56 // to state (0,0)
57 action = HBM_OFF;
58 } else if (mRegHBMSV) {
59 // to state (0,1) or (1,1).
60 if (!mCurHBMSV)
61 action = HBM_SV;
62 } else {
63 // to state (1,0)
64 action = HBM_ON;
65 }
66
67 if (action) {
68 if (!android::base::WriteStringToFile(action, kHighBrightnessModeNode)) {
69 ALOGE("write %s to HBM sysfs file failed!", action);
70 return Status::UNKNOWN;
71 }
72
73 ALOGD("write %s to HBM sysfs file succeeded", action);
74 }
75
76 mCurHBM = mRegHBM;
77 mCurHBMSV = mRegHBMSV;
78
79 return Status::SUCCESS;
80 }
81
82 // Methods from ::android::hardware::light::V2_0::ILight follow.
setLight(Type type,const LightState & state)83 Return<Status> LightExt::setLight(Type type, const LightState& state) {
84 if (type == Type::BACKLIGHT) {
85 if (state.brightnessMode == Brightness::LOW_PERSISTENCE) {
86 mRegHBM = false;
87 mRegHBMSV = false;
88 applyHBM();
89 mVRMode = true;
90 } else {
91 // VR has higher priority than HBM. We cannot update HBM status
92 // when VR is enabled. Disable VR before apply HBM mode
93 Status status = mLight->setLight(type, state);
94 mVRMode = false;
95 applyHBM();
96 return status;
97 }
98 }
99 return mLight->setLight(type, state);
100 }
101
102 // Methods from ::hardware::google::light::V1_0::ILight follow.
setHbm(bool on)103 Return<Status> LightExt::setHbm(bool on) {
104 /* save the request state */
105 mRegHBM = on;
106
107 if (mVRMode) return Status::UNKNOWN;
108
109 Status status = applyHBM();
110
111 if (status != Status::SUCCESS)
112 mRegHBM = mCurHBM;
113
114 return status;
115 }
116
117 // Methods from ::hardware::google::light::V1_1::ILight follow.
setHbmSv(bool on)118 Return<Status> LightExt::setHbmSv(bool on) {
119 /* save the request state */
120 mRegHBMSV = on;
121
122 if (mVRMode) return Status::UNKNOWN;
123
124 Status status = applyHBM();
125
126 if (status != Status::SUCCESS)
127 mRegHBMSV = mCurHBMSV;
128
129 return status;
130 }
131
getHbmSv()132 Return<bool> LightExt::getHbmSv() {
133 return mCurHBMSV;
134 }
135
136 } // namespace implementation
137 } // namespace V1_1
138 } // namespace light
139 } // namespace google
140 } // namespace hardware
141