1 /*
2 * Copyright (C) 2020 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_NDEBUG 0
18 #define LOG_TAG "NativePowerManagerTest"
19
20 #include "jni.h"
21 #include "ParcelHelper.h"
22
23 #include <android_util_Binder.h>
24 #include <binder/IServiceManager.h>
25 #include <nativehelper/JNIHelp.h>
26 #include <utils/Log.h>
27
28 #include <android/os/IPowerManager.h>
29 #include <android/WorkSource.h>
30 #include <android/PowerSaveState.h>
31 #include <android/BatterySaverPolicyConfig.h>
32 #include <android-base/stringprintf.h>
33 #include <android-base/strings.h>
34
35 using namespace android::os;
36 using android::base::StringPrintf;
37
38 namespace android {
39
40 static struct BatterySaverPolicyConfigFieldId {
41 jfieldID adjustBrightnessFactor;
42 jfieldID advertiseIsEnabled;
43 jfieldID deferFullBackup;
44 jfieldID deferKeyValueBackup;
45 jfieldID deviceSpecificSettings;
46 jfieldID disableAnimation;
47 jfieldID disableAod;
48 jfieldID disableLaunchBoost;
49 jfieldID disableOptionalSensors;
50 jfieldID disableVibration;
51 jfieldID enableAdjustBrightness;
52 jfieldID enableDataSaver;
53 jfieldID enableFirewall;
54 jfieldID enableNightMode;
55 jfieldID enableQuickDoze;
56 jfieldID forceAllAppsStandby;
57 jfieldID forceBackgroundCheck;
58 jfieldID locationMode;
59 jfieldID soundTriggerMode;
60 } gBSPCFieldIds;
61
nativeObtainPowerSaveStateParcel(JNIEnv * env,jobject,jboolean batterySaverEnabled,jboolean globalBatterySaverEnabled,jint locationMode,jint soundTriggerMode,jfloat brightnessFactor)62 static jobject nativeObtainPowerSaveStateParcel(JNIEnv* env, jobject /* obj */,
63 jboolean batterySaverEnabled, jboolean globalBatterySaverEnabled,
64 jint locationMode, jint soundTriggerMode, jfloat brightnessFactor) {
65 PowerSaveState ps = PowerSaveState(static_cast<bool>(batterySaverEnabled),
66 static_cast<bool>(globalBatterySaverEnabled),
67 static_cast<LocationMode>(locationMode),
68 static_cast<SoundTriggerMode>(soundTriggerMode),
69 static_cast<float>(brightnessFactor));
70 jobject psParcel = nativeObtainParcel(env);
71 Parcel* parcel = nativeGetParcelData(env, psParcel);
72 status_t err = ps.writeToParcel(parcel);
73 if (err != OK) {
74 jniThrowException(env, "java/lang/IllegalArgumentException",
75 StringPrintf("WorkSource writeToParcel failed %d", err).c_str());
76 }
77 parcel->setDataPosition(0);
78 return psParcel;
79 }
80
nativeUnparcelAndVerifyPowerSaveState(JNIEnv * env,jobject,jobject psParcel,jboolean batterySaverEnabled,jboolean globalBatterySaverEnabled,jint locationMode,jint soundTriggerMode,jfloat brightnessFactor)81 static void nativeUnparcelAndVerifyPowerSaveState(JNIEnv* env, jobject /* obj */, jobject psParcel,
82 jboolean batterySaverEnabled, jboolean globalBatterySaverEnabled,
83 jint locationMode, jint soundTriggerMode, jfloat brightnessFactor) {
84 PowerSaveState ps = {};
85 Parcel* parcel = nativeGetParcelData(env, psParcel);
86 status_t err = ps.readFromParcel(parcel);
87 if (err != OK) {
88 ALOGE("WorkSource writeToParcel failed %d", err);
89 }
90 // Now we have a native PowerSaveState object, verify it.
91 PowerSaveState psOrig = PowerSaveState(static_cast<bool>(batterySaverEnabled),
92 static_cast<bool>(globalBatterySaverEnabled),
93 static_cast<LocationMode>(locationMode),
94 static_cast<SoundTriggerMode>(soundTriggerMode),
95 static_cast<float>(brightnessFactor));
96 if (ps == psOrig) {
97 return;
98 } else {
99 jniThrowException(env, "java/lang/IllegalArgumentException",
100 "PowerSaveState not equal with origin");
101 }
102 }
103
nativeObtainBSPConfigParcel(JNIEnv * env,jobject,jobject bsObj,jobjectArray keyArray,jobjectArray valueArray)104 static jobject nativeObtainBSPConfigParcel(JNIEnv* env, jobject /* obj */,
105 jobject bsObj, jobjectArray keyArray, jobjectArray valueArray) {
106 std::vector<std::pair<String16, String16>> deviceSpecificSettings;
107 for (jint i = 0; i < env->GetArrayLength(keyArray); i++) {
108 jstring keyString = (jstring) (env->GetObjectArrayElement(keyArray, i));
109 jstring valueString = (jstring) (env->GetObjectArrayElement(valueArray, i));
110 deviceSpecificSettings.push_back({String16(env->GetStringUTFChars(keyString, 0)),
111 String16(env->GetStringUTFChars(valueString, 0))});
112 }
113
114 BatterySaverPolicyConfig bs = BatterySaverPolicyConfig(
115 env->GetFloatField(bsObj, gBSPCFieldIds.adjustBrightnessFactor),
116 env->GetBooleanField(bsObj, gBSPCFieldIds.advertiseIsEnabled),
117 env->GetBooleanField(bsObj, gBSPCFieldIds.deferFullBackup),
118 env->GetBooleanField(bsObj, gBSPCFieldIds.deferKeyValueBackup),
119 deviceSpecificSettings,
120 env->GetBooleanField(bsObj, gBSPCFieldIds.disableAnimation),
121 env->GetBooleanField(bsObj, gBSPCFieldIds.disableAod),
122 env->GetBooleanField(bsObj, gBSPCFieldIds.disableLaunchBoost),
123 env->GetBooleanField(bsObj, gBSPCFieldIds.disableOptionalSensors),
124 env->GetBooleanField(bsObj, gBSPCFieldIds.disableVibration),
125 env->GetBooleanField(bsObj, gBSPCFieldIds.enableAdjustBrightness),
126 env->GetBooleanField(bsObj, gBSPCFieldIds.enableDataSaver),
127 env->GetBooleanField(bsObj, gBSPCFieldIds.enableFirewall),
128 env->GetBooleanField(bsObj, gBSPCFieldIds.enableNightMode),
129 env->GetBooleanField(bsObj, gBSPCFieldIds.enableQuickDoze),
130 env->GetBooleanField(bsObj, gBSPCFieldIds.forceAllAppsStandby),
131 env->GetBooleanField(bsObj, gBSPCFieldIds.forceBackgroundCheck),
132 static_cast<LocationMode>(env->GetIntField(bsObj, gBSPCFieldIds.locationMode)),
133 static_cast<SoundTriggerMode>(env->GetIntField(bsObj, gBSPCFieldIds.soundTriggerMode)));
134
135 jobject bsParcel = nativeObtainParcel(env);
136 Parcel* parcel = nativeGetParcelData(env, bsParcel);
137 status_t err = bs.writeToParcel(parcel);
138 if (err != OK) {
139 jniThrowException(env, "java/lang/IllegalArgumentException",
140 StringPrintf("WorkSource writeToParcel failed %d", err).c_str());
141 }
142 parcel->setDataPosition(0);
143 return bsParcel;
144 }
145
nativeUnparcelAndVerifyBSPConfig(JNIEnv * env,jobject,jobject bsParcel,jobject bsObj,jobjectArray keyArray,jobjectArray valueArray)146 static void nativeUnparcelAndVerifyBSPConfig(JNIEnv* env, jobject /* obj */,
147 jobject bsParcel, jobject bsObj, jobjectArray keyArray, jobjectArray valueArray) {
148 BatterySaverPolicyConfig bs = {};
149 Parcel* parcel = nativeGetParcelData(env, bsParcel);
150 status_t err = bs.readFromParcel(parcel);
151 if (err != OK) {
152 ALOGE("WorkSource writeToParcel failed %d", err);
153 }
154
155 // Get the device settings from Java
156 std::vector<std::pair<String16, String16>> deviceSpecificSettings;
157 for (jint i = 0; i < env->GetArrayLength(keyArray); i++) {
158 jstring keyString = (jstring) (env->GetObjectArrayElement(keyArray, i));
159 jstring valueString = (jstring) (env->GetObjectArrayElement(valueArray, i));
160 deviceSpecificSettings.push_back({String16(env->GetStringUTFChars(keyString, 0)),
161 String16(env->GetStringUTFChars(valueString, 0))});
162 }
163 // Now we have a native BatterySaverPolicyConfig object, verify it.
164 BatterySaverPolicyConfig bsOrig = BatterySaverPolicyConfig(
165 env->GetFloatField(bsObj, gBSPCFieldIds.adjustBrightnessFactor),
166 env->GetBooleanField(bsObj, gBSPCFieldIds.advertiseIsEnabled),
167 env->GetBooleanField(bsObj, gBSPCFieldIds.deferFullBackup),
168 env->GetBooleanField(bsObj, gBSPCFieldIds.deferKeyValueBackup),
169 deviceSpecificSettings,
170 env->GetBooleanField(bsObj, gBSPCFieldIds.disableAnimation),
171 env->GetBooleanField(bsObj, gBSPCFieldIds.disableAod),
172 env->GetBooleanField(bsObj, gBSPCFieldIds.disableLaunchBoost),
173 env->GetBooleanField(bsObj, gBSPCFieldIds.disableOptionalSensors),
174 env->GetBooleanField(bsObj, gBSPCFieldIds.disableVibration),
175 env->GetBooleanField(bsObj, gBSPCFieldIds.enableAdjustBrightness),
176 env->GetBooleanField(bsObj, gBSPCFieldIds.enableDataSaver),
177 env->GetBooleanField(bsObj, gBSPCFieldIds.enableFirewall),
178 env->GetBooleanField(bsObj, gBSPCFieldIds.enableNightMode),
179 env->GetBooleanField(bsObj, gBSPCFieldIds.enableQuickDoze),
180 env->GetBooleanField(bsObj, gBSPCFieldIds.forceAllAppsStandby),
181 env->GetBooleanField(bsObj, gBSPCFieldIds.forceBackgroundCheck),
182 static_cast<LocationMode>(env->GetIntField(bsObj, gBSPCFieldIds.locationMode)),
183 static_cast<SoundTriggerMode>(env->GetIntField(bsObj, gBSPCFieldIds.soundTriggerMode)));
184
185 if (bs == bsOrig) {
186 return;
187 } else {
188 jniThrowException(env, "java/lang/IllegalArgumentException",
189 "BatterySaverPolicyConfig not equal with origin");
190 }
191 }
192
JNI_OnLoad(JavaVM * vm,void *)193 extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
194 {
195 JNIEnv* env;
196 const JNINativeMethod methodTable[] = {
197 /* name, signature, funcPtr */
198 { "nativeObtainPowerSaveStateParcel", "(ZZIIF)Landroid/os/Parcel;",
199 (void*) nativeObtainPowerSaveStateParcel },
200 { "nativeUnparcelAndVerifyPowerSaveState", "(Landroid/os/Parcel;ZZIIF)V",
201 (void*) nativeUnparcelAndVerifyPowerSaveState },
202 { "nativeObtainBSPConfigParcel",
203 "(Landroid/os/BatterySaverPolicyConfig;"
204 "[Ljava/lang/String;[Ljava/lang/String;)Landroid/os/Parcel;",
205 (void*) nativeObtainBSPConfigParcel },
206 { "nativeUnparcelAndVerifyBSPConfig",
207 "(Landroid/os/Parcel;Landroid/os/BatterySaverPolicyConfig;"
208 "[Ljava/lang/String;[Ljava/lang/String;)V",
209 (void*) nativeUnparcelAndVerifyBSPConfig },
210 };
211
212 if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
213 return JNI_ERR;
214 }
215
216 loadParcelClass(env);
217
218 jclass bspcClazz = FindClassOrDie(env, "android/os/BatterySaverPolicyConfig");
219
220 gBSPCFieldIds.adjustBrightnessFactor =
221 GetFieldIDOrDie(env, bspcClazz, "mAdjustBrightnessFactor", "F");
222 gBSPCFieldIds.advertiseIsEnabled = GetFieldIDOrDie(env, bspcClazz, "mAdvertiseIsEnabled", "Z");
223 gBSPCFieldIds.deferFullBackup = GetFieldIDOrDie(env, bspcClazz, "mDeferFullBackup", "Z");
224 gBSPCFieldIds.deferKeyValueBackup =
225 GetFieldIDOrDie(env, bspcClazz, "mDeferKeyValueBackup", "Z");
226 gBSPCFieldIds.deviceSpecificSettings =
227 GetFieldIDOrDie(env, bspcClazz, "mDeviceSpecificSettings", "Ljava/util/Map;");
228 gBSPCFieldIds.disableAnimation = GetFieldIDOrDie(env, bspcClazz, "mDisableAnimation", "Z");
229 gBSPCFieldIds.disableAod = GetFieldIDOrDie(env, bspcClazz, "mDisableAod", "Z");
230 gBSPCFieldIds.disableLaunchBoost = GetFieldIDOrDie(env, bspcClazz, "mDisableLaunchBoost", "Z");
231 gBSPCFieldIds.disableOptionalSensors =
232 GetFieldIDOrDie(env, bspcClazz, "mDisableOptionalSensors", "Z");
233 gBSPCFieldIds.disableVibration = GetFieldIDOrDie(env, bspcClazz, "mDisableVibration", "Z");
234 gBSPCFieldIds.enableAdjustBrightness =
235 GetFieldIDOrDie(env, bspcClazz, "mEnableAdjustBrightness", "Z");
236 gBSPCFieldIds.enableDataSaver = GetFieldIDOrDie(env, bspcClazz, "mEnableDataSaver", "Z");
237 gBSPCFieldIds.enableFirewall = GetFieldIDOrDie(env, bspcClazz, "mEnableFirewall", "Z");
238 gBSPCFieldIds.enableNightMode = GetFieldIDOrDie(env, bspcClazz, "mEnableNightMode", "Z");
239 gBSPCFieldIds.enableQuickDoze = GetFieldIDOrDie(env, bspcClazz, "mEnableQuickDoze", "Z");
240 gBSPCFieldIds.forceAllAppsStandby =
241 GetFieldIDOrDie(env, bspcClazz, "mForceAllAppsStandby", "Z");
242 gBSPCFieldIds.forceBackgroundCheck =
243 GetFieldIDOrDie(env, bspcClazz, "mForceBackgroundCheck", "Z");
244 gBSPCFieldIds.locationMode = GetFieldIDOrDie(env, bspcClazz, "mLocationMode", "I");
245 gBSPCFieldIds.soundTriggerMode = GetFieldIDOrDie(env, bspcClazz, "mSoundTriggerMode", "I");
246
247 jniRegisterNativeMethods(env, "android/os/PowerManagerTest", methodTable,
248 sizeof(methodTable) / sizeof(JNINativeMethod));
249
250 return JNI_VERSION_1_6;
251 }
252
253 } /* namespace android */
254