1 /*
2 * Copyright (C) 2022 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 #include <dlfcn.h>
18
19 #include <optional>
20
21 #define LOG_TAG "OverlayManagerImpl"
22
23 #include "android-base/no_destructor.h"
24 #include "androidfw/ResourceTypes.h"
25 #include "core_jni_helpers.h"
26 #include "jni.h"
27
28 namespace android {
29
30 static struct fabricated_overlay_internal_offsets_t {
31 jclass classObject;
32 jfieldID packageName;
33 jfieldID overlayName;
34 jfieldID targetPackageName;
35 jfieldID targetOverlayable;
36 jfieldID entries;
37 } gFabricatedOverlayInternalOffsets;
38
39 static struct fabricated_overlay_internal_entry_offsets_t {
40 jclass classObject;
41 jfieldID resourceName;
42 jfieldID dataType;
43 jfieldID data;
44 jfieldID stringData;
45 jfieldID binaryData;
46 jfieldID configuration;
47 jfieldID binaryDataOffset;
48 jfieldID binaryDataSize;
49 jfieldID isNinePatch;
50 } gFabricatedOverlayInternalEntryOffsets;
51
52 static struct parcel_file_descriptor_offsets_t {
53 jclass classObject;
54 jmethodID getFd;
55 } gParcelFileDescriptorOffsets;
56
57 static struct List_offsets_t {
58 jclass classObject;
59 jmethodID size;
60 jmethodID get;
61 } gListOffsets;
62
63 static struct fabricated_overlay_info_offsets_t {
64 jclass classObject;
65 jmethodID constructor;
66 jfieldID packageName;
67 jfieldID overlayName;
68 jfieldID targetPackageName;
69 jfieldID targetOverlayable;
70 jfieldID path;
71 } gFabricatedOverlayInfoOffsets;
72
73 namespace self_targeting {
74
75 constexpr const char kIOException[] = "java/io/IOException";
76 constexpr const char IllegalArgumentException[] = "java/lang/IllegalArgumentException";
77
78 class DynamicLibraryLoader {
79 public:
DynamicLibraryLoader(JNIEnv * env)80 explicit DynamicLibraryLoader(JNIEnv* env) {
81 /* For SelfTargeting, there are 2 types of files to be handled. One is frro and the other is
82 * idmap. For creating frro/idmap files and reading frro files, it needs libandroid_runtime
83 * to do a shared link to libidmap2. However, libidmap2 contains the codes generated from
84 * google protocol buffer. When libandroid_runtime does a shared link to libidmap2, it will
85 * impact the memory for system_server and zygote(a.k.a. all applications).
86 *
87 * Not all applications need to either create/read frro files or create idmap files all the
88 * time. When the apps apply the SelfTargeting overlay effect, it only needs libandroifw
89 * that is loaded. To use dlopen(libidmap2.so) is to make sure that applications don't
90 * impact themselves' memory by loading libidmap2 until they need to create/read frro files
91 * or create idmap files.
92 */
93 handle_ = dlopen("libidmap2.so", RTLD_NOW);
94 if (handle_ == nullptr) {
95 jniThrowNullPointerException(env);
96 return;
97 }
98
99 createIdmapFileFuncPtr_ =
100 reinterpret_cast<CreateIdmapFileFunc>(dlsym(handle_, "CreateIdmapFile"));
101 if (createIdmapFileFuncPtr_ == nullptr) {
102 jniThrowNullPointerException(env, "The symbol CreateIdmapFile is not found.");
103 return;
104 }
105 getFabricatedOverlayInfoFuncPtr_ = reinterpret_cast<GetFabricatedOverlayInfoFunc>(
106 dlsym(handle_, "GetFabricatedOverlayInfo"));
107 if (getFabricatedOverlayInfoFuncPtr_ == nullptr) {
108 jniThrowNullPointerException(env, "The symbol GetFabricatedOverlayInfo is not found.");
109 return;
110 }
111 createFrroFile_ = reinterpret_cast<CreateFrroFileFunc>(dlsym(handle_, "CreateFrroFile"));
112 if (createFrroFile_ == nullptr) {
113 jniThrowNullPointerException(env, "The symbol CreateFrroFile is not found.");
114 return;
115 }
116 }
117
callCreateFrroFile(std::string & out_error,const std::string & packageName,const std::string & overlayName,const std::string & targetPackageName,const std::optional<std::string> & targetOverlayable,const std::vector<FabricatedOverlayEntryParameters> & entries_params,const std::string & frro_file_path)118 bool callCreateFrroFile(std::string& out_error, const std::string& packageName,
119 const std::string& overlayName, const std::string& targetPackageName,
120 const std::optional<std::string>& targetOverlayable,
121 const std::vector<FabricatedOverlayEntryParameters>& entries_params,
122 const std::string& frro_file_path) {
123 return createFrroFile_(out_error, packageName, overlayName, targetPackageName,
124 targetOverlayable, entries_params, frro_file_path);
125 }
126
callCreateIdmapFile(std::string & out_error,const std::string & targetPath,const std::string & overlayPath,const std::string & idmapPath,const std::string & overlayName,const bool isSystem,const bool isVendor,const bool isProduct,const bool isTargetSignature,const bool isOdm,const bool isOem)127 bool callCreateIdmapFile(std::string& out_error, const std::string& targetPath,
128 const std::string& overlayPath, const std::string& idmapPath,
129 const std::string& overlayName, const bool isSystem,
130 const bool isVendor, const bool isProduct,
131 const bool isTargetSignature, const bool isOdm, const bool isOem) {
132 return createIdmapFileFuncPtr_(out_error, targetPath, overlayPath, idmapPath, overlayName,
133 isSystem, isVendor, isProduct, isTargetSignature, isOdm,
134 isOem);
135 }
136
callGetFabricatedOverlayInfo(std::string & out_error,const std::string & overlay_path,OverlayManifestInfo & out_overlay_manifest_info)137 bool callGetFabricatedOverlayInfo(std::string& out_error, const std::string& overlay_path,
138 OverlayManifestInfo& out_overlay_manifest_info) {
139 return getFabricatedOverlayInfoFuncPtr_(out_error, overlay_path, out_overlay_manifest_info);
140 }
141
operator bool() const142 explicit operator bool() const {
143 return handle_ != nullptr && createFrroFile_ != nullptr &&
144 createIdmapFileFuncPtr_ != nullptr && getFabricatedOverlayInfoFuncPtr_ != nullptr;
145 }
146
147 DynamicLibraryLoader(const DynamicLibraryLoader&) = delete;
148
149 DynamicLibraryLoader& operator=(const DynamicLibraryLoader&) = delete;
150
~DynamicLibraryLoader()151 ~DynamicLibraryLoader() {
152 if (handle_ != nullptr) {
153 dlclose(handle_);
154 }
155 }
156
157 private:
158 typedef bool (*CreateFrroFileFunc)(
159 std::string& out_error, const std::string& packageName, const std::string& overlayName,
160 const std::string& targetPackageName,
161 const std::optional<std::string>& targetOverlayable,
162 const std::vector<FabricatedOverlayEntryParameters>& entries_params,
163 const std::string& frro_file_path);
164
165 typedef bool (*CreateIdmapFileFunc)(std::string& out_error, const std::string& targetPath,
166 const std::string& overlayPath,
167 const std::string& idmapPath,
168 const std::string& overlayName, const jboolean isSystem,
169 const jboolean isVendor, const jboolean isProduct,
170 const jboolean isSameWithTargetSignature,
171 const jboolean isOdm, const jboolean isOem);
172
173 typedef bool (*GetFabricatedOverlayInfoFunc)(std::string& out_error,
174 const std::string& overlay_path,
175 OverlayManifestInfo& out_overlay_manifest_info);
176
177 void* handle_;
178 CreateFrroFileFunc createFrroFile_;
179 CreateIdmapFileFunc createIdmapFileFuncPtr_;
180 GetFabricatedOverlayInfoFunc getFabricatedOverlayInfoFuncPtr_;
181 };
182
EnsureDynamicLibraryLoader(JNIEnv * env)183 static DynamicLibraryLoader& EnsureDynamicLibraryLoader(JNIEnv* env) {
184 static android::base::NoDestructor<DynamicLibraryLoader> loader(env);
185 return *loader;
186 }
187
getNullableString(JNIEnv * env,jobject object,jfieldID field)188 static std::optional<std::string> getNullableString(JNIEnv* env, jobject object, jfieldID field) {
189 auto javaString = reinterpret_cast<jstring>(env->GetObjectField(object, field));
190 if (javaString == nullptr) {
191 return std::nullopt;
192 }
193
194 const ScopedUtfChars result(env, javaString);
195 if (result.c_str() == nullptr) {
196 return std::nullopt;
197 }
198
199 return std::optional<std::string>{result.c_str()};
200 }
201
getNullableFileDescriptor(JNIEnv * env,jobject object,jfieldID field)202 static std::optional<android::base::borrowed_fd> getNullableFileDescriptor(JNIEnv* env,
203 jobject object,
204 jfieldID field) {
205 auto binaryData = env->GetObjectField(object, field);
206 if (binaryData == nullptr) {
207 return std::nullopt;
208 }
209
210 return env->CallIntMethod(binaryData, gParcelFileDescriptorOffsets.getFd);
211 }
212
CreateFrroFile(JNIEnv * env,jclass,jstring jsFrroFilePath,jobject overlay)213 static void CreateFrroFile(JNIEnv* env, jclass /*clazz*/, jstring jsFrroFilePath, jobject overlay) {
214 DynamicLibraryLoader& dlLoader = EnsureDynamicLibraryLoader(env);
215 if (!dlLoader) {
216 jniThrowNullPointerException(env, "libidmap2 is not loaded");
217 return;
218 }
219
220 if (overlay == nullptr) {
221 jniThrowNullPointerException(env, "overlay is null");
222 return;
223 }
224 auto jsPackageName =
225 (jstring)env->GetObjectField(overlay, gFabricatedOverlayInternalOffsets.packageName);
226 const ScopedUtfChars packageName(env, jsPackageName);
227 if (packageName.c_str() == nullptr) {
228 jniThrowNullPointerException(env, "packageName is null");
229 return;
230 }
231 auto jsOverlayName =
232 (jstring)env->GetObjectField(overlay, gFabricatedOverlayInternalOffsets.overlayName);
233 const ScopedUtfChars overlayName(env, jsOverlayName);
234 if (overlayName.c_str() == nullptr) {
235 jniThrowNullPointerException(env, "overlayName is null");
236 return;
237 }
238 auto jsTargetPackageName =
239 (jstring)env->GetObjectField(overlay,
240 gFabricatedOverlayInternalOffsets.targetPackageName);
241 const ScopedUtfChars targetPackageName(env, jsTargetPackageName);
242 if (targetPackageName.c_str() == nullptr) {
243 jniThrowNullPointerException(env, "targetPackageName is null");
244 return;
245 }
246 auto overlayable =
247 getNullableString(env, overlay, gFabricatedOverlayInternalOffsets.targetOverlayable);
248 const ScopedUtfChars frroFilePath(env, jsFrroFilePath);
249 if (frroFilePath.c_str() == nullptr) {
250 jniThrowNullPointerException(env, "frroFilePath is null");
251 return;
252 }
253 jobject entries = env->GetObjectField(overlay, gFabricatedOverlayInternalOffsets.entries);
254 if (entries == nullptr) {
255 jniThrowNullPointerException(env, "overlay entries is null");
256 return;
257 }
258 const jint size = env->CallIntMethod(entries, gListOffsets.size);
259 ALOGV("frroFilePath = %s, packageName = %s, overlayName = %s, targetPackageName = %s,"
260 " targetOverlayable = %s, size = %d",
261 frroFilePath.c_str(), packageName.c_str(), overlayName.c_str(), targetPackageName.c_str(),
262 overlayable.value_or(std::string()).c_str(), size);
263
264 std::vector<FabricatedOverlayEntryParameters> entries_params;
265 for (jint i = 0; i < size; i++) {
266 jobject entry = env->CallObjectMethod(entries, gListOffsets.get, i);
267 auto jsResourceName = reinterpret_cast<jstring>(
268 env->GetObjectField(entry, gFabricatedOverlayInternalEntryOffsets.resourceName));
269 const ScopedUtfChars resourceName(env, jsResourceName);
270 const jint dataType =
271 env->GetIntField(entry, gFabricatedOverlayInternalEntryOffsets.dataType);
272
273 // In Java, the data type is int but the maximum value of data Type is less than 0xff.
274 if (dataType >= static_cast<jint>(UCHAR_MAX)) {
275 jniThrowException(env, IllegalArgumentException, "Unsupported data type");
276 return;
277 }
278
279 const auto data = env->GetIntField(entry, gFabricatedOverlayInternalEntryOffsets.data);
280 auto configuration =
281 getNullableString(env, entry, gFabricatedOverlayInternalEntryOffsets.configuration);
282 auto string_data =
283 getNullableString(env, entry, gFabricatedOverlayInternalEntryOffsets.stringData);
284 auto binary_data =
285 getNullableFileDescriptor(env, entry,
286 gFabricatedOverlayInternalEntryOffsets.binaryData);
287
288 const auto data_offset =
289 env->GetLongField(entry, gFabricatedOverlayInternalEntryOffsets.binaryDataOffset);
290 const auto data_size =
291 env->GetLongField(entry, gFabricatedOverlayInternalEntryOffsets.binaryDataSize);
292 const auto nine_patch =
293 env->GetBooleanField(entry, gFabricatedOverlayInternalEntryOffsets.isNinePatch);
294 entries_params.push_back(
295 FabricatedOverlayEntryParameters{resourceName.c_str(), (DataType)dataType,
296 (DataValue)data,
297 string_data.value_or(std::string()), binary_data,
298 static_cast<off64_t>(data_offset),
299 static_cast<size_t>(data_size),
300 configuration.value_or(std::string()),
301 static_cast<bool>(nine_patch)});
302 ALOGV("resourceName = %s, dataType = 0x%08x, data = 0x%08x, dataString = %s,"
303 " binaryData = %d, configuration = %s",
304 resourceName.c_str(), dataType, data, string_data.value_or(std::string()).c_str(),
305 binary_data.has_value(), configuration.value_or(std::string()).c_str());
306 }
307
308 std::string err_result;
309 if (!dlLoader.callCreateFrroFile(err_result, packageName.c_str(), overlayName.c_str(),
310 targetPackageName.c_str(), overlayable, entries_params,
311 frroFilePath.c_str())) {
312 jniThrowException(env, IllegalArgumentException, err_result.c_str());
313 return;
314 }
315 }
316
CreateIdmapFile(JNIEnv * env,jclass,jstring jsTargetPath,jstring jsOverlayPath,jstring jsIdmapPath,jstring jsOverlayName,jboolean isSystem,jboolean isVendor,jboolean isProduct,jboolean isTargetSignature,jboolean isOdm,jboolean isOem)317 static void CreateIdmapFile(JNIEnv* env, jclass /* clazz */, jstring jsTargetPath,
318 jstring jsOverlayPath, jstring jsIdmapPath, jstring jsOverlayName,
319 jboolean isSystem, jboolean isVendor, jboolean isProduct,
320 jboolean isTargetSignature, jboolean isOdm, jboolean isOem) {
321 DynamicLibraryLoader& dlLoader = EnsureDynamicLibraryLoader(env);
322 if (!dlLoader) {
323 jniThrowNullPointerException(env, "libidmap2 is not loaded");
324 return;
325 }
326
327 const ScopedUtfChars targetPath(env, jsTargetPath);
328 if (targetPath.c_str() == nullptr) {
329 jniThrowNullPointerException(env, "targetPath is null");
330 return;
331 }
332 const ScopedUtfChars overlayPath(env, jsOverlayPath);
333 if (overlayPath.c_str() == nullptr) {
334 jniThrowNullPointerException(env, "overlayPath is null");
335 return;
336 }
337 const ScopedUtfChars idmapPath(env, jsIdmapPath);
338 if (idmapPath.c_str() == nullptr) {
339 jniThrowNullPointerException(env, "idmapPath is null");
340 return;
341 }
342 const ScopedUtfChars overlayName(env, jsOverlayName);
343 if (overlayName.c_str() == nullptr) {
344 jniThrowNullPointerException(env, "overlayName is null");
345 return;
346 }
347 ALOGV("target_path = %s, overlay_path = %s, idmap_path = %s, overlay_name = %s",
348 targetPath.c_str(), overlayPath.c_str(), idmapPath.c_str(), overlayName.c_str());
349
350 std::string err_result;
351 if (!dlLoader.callCreateIdmapFile(err_result, targetPath.c_str(), overlayPath.c_str(),
352 idmapPath.c_str(), overlayName.c_str(),
353 (isSystem == JNI_TRUE), (isVendor == JNI_TRUE),
354 (isProduct == JNI_TRUE), (isTargetSignature == JNI_TRUE),
355 (isOdm == JNI_TRUE), (isOem == JNI_TRUE))) {
356 jniThrowException(env, kIOException, err_result.c_str());
357 return;
358 }
359 }
360
GetFabricatedOverlayInfo(JNIEnv * env,jclass,jstring jsOverlayPath)361 static jobject GetFabricatedOverlayInfo(JNIEnv* env, jclass /* clazz */, jstring jsOverlayPath) {
362 const ScopedUtfChars overlay_path(env, jsOverlayPath);
363 if (overlay_path.c_str() == nullptr) {
364 jniThrowNullPointerException(env, "overlay_path is null");
365 return nullptr;
366 }
367 ALOGV("overlay_path = %s", overlay_path.c_str());
368
369 DynamicLibraryLoader& dlLoader = EnsureDynamicLibraryLoader(env);
370 if (!dlLoader) {
371 return nullptr;
372 }
373
374 std::string err_result;
375 OverlayManifestInfo overlay_manifest_info;
376 if (!dlLoader.callGetFabricatedOverlayInfo(err_result, overlay_path.c_str(),
377 overlay_manifest_info) != 0) {
378 jniThrowException(env, kIOException, err_result.c_str());
379 return nullptr;
380 }
381 jobject info = env->NewObject(gFabricatedOverlayInfoOffsets.classObject,
382 gFabricatedOverlayInfoOffsets.constructor);
383 jstring jsOverName = env->NewStringUTF(overlay_manifest_info.name.c_str());
384 jstring jsPackageName = env->NewStringUTF(overlay_manifest_info.package_name.c_str());
385 jstring jsTargetPackage = env->NewStringUTF(overlay_manifest_info.target_package.c_str());
386 jstring jsTargetOverlayable = env->NewStringUTF(overlay_manifest_info.target_name.c_str());
387 env->SetObjectField(info, gFabricatedOverlayInfoOffsets.overlayName, jsOverName);
388 env->SetObjectField(info, gFabricatedOverlayInfoOffsets.packageName, jsPackageName);
389 env->SetObjectField(info, gFabricatedOverlayInfoOffsets.targetPackageName, jsTargetPackage);
390 env->SetObjectField(info, gFabricatedOverlayInfoOffsets.targetOverlayable, jsTargetOverlayable);
391 env->SetObjectField(info, gFabricatedOverlayInfoOffsets.path, jsOverlayPath);
392 return info;
393 }
394
395 } // namespace self_targeting
396
397 // JNI registration.
398 static const JNINativeMethod gOverlayManagerMethods[] = {
399 {"createFrroFile", "(Ljava/lang/String;Landroid/os/FabricatedOverlayInternal;)V",
400 reinterpret_cast<void*>(self_targeting::CreateFrroFile)},
401 {"createIdmapFile",
402 "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZZZZZ)V",
403 reinterpret_cast<void*>(self_targeting::CreateIdmapFile)},
404 {"getFabricatedOverlayInfo", "(Ljava/lang/String;)Landroid/os/FabricatedOverlayInfo;",
405 reinterpret_cast<void*>(self_targeting::GetFabricatedOverlayInfo)},
406 };
407
register_com_android_internal_content_om_OverlayManagerImpl(JNIEnv * env)408 int register_com_android_internal_content_om_OverlayManagerImpl(JNIEnv* env) {
409 jclass ListClass = FindClassOrDie(env, "java/util/List");
410 gListOffsets.classObject = MakeGlobalRefOrDie(env, ListClass);
411 gListOffsets.size = GetMethodIDOrDie(env, gListOffsets.classObject, "size", "()I");
412 gListOffsets.get =
413 GetMethodIDOrDie(env, gListOffsets.classObject, "get", "(I)Ljava/lang/Object;");
414
415 jclass fabricatedOverlayInternalClass =
416 FindClassOrDie(env, "android/os/FabricatedOverlayInternal");
417 gFabricatedOverlayInternalOffsets.classObject =
418 MakeGlobalRefOrDie(env, fabricatedOverlayInternalClass);
419 gFabricatedOverlayInternalOffsets.packageName =
420 GetFieldIDOrDie(env, gFabricatedOverlayInternalOffsets.classObject, "packageName",
421 "Ljava/lang/String;");
422 gFabricatedOverlayInternalOffsets.overlayName =
423 GetFieldIDOrDie(env, gFabricatedOverlayInternalOffsets.classObject, "overlayName",
424 "Ljava/lang/String;");
425 gFabricatedOverlayInternalOffsets.targetPackageName =
426 GetFieldIDOrDie(env, gFabricatedOverlayInternalOffsets.classObject, "targetPackageName",
427 "Ljava/lang/String;");
428 gFabricatedOverlayInternalOffsets.targetOverlayable =
429 GetFieldIDOrDie(env, gFabricatedOverlayInternalOffsets.classObject, "targetOverlayable",
430 "Ljava/lang/String;");
431 gFabricatedOverlayInternalOffsets.entries =
432 GetFieldIDOrDie(env, gFabricatedOverlayInternalOffsets.classObject, "entries",
433 "Ljava/util/List;");
434
435 jclass fabricatedOverlayInternalEntryClass =
436 FindClassOrDie(env, "android/os/FabricatedOverlayInternalEntry");
437 gFabricatedOverlayInternalEntryOffsets.classObject =
438 MakeGlobalRefOrDie(env, fabricatedOverlayInternalEntryClass);
439 gFabricatedOverlayInternalEntryOffsets.resourceName =
440 GetFieldIDOrDie(env, gFabricatedOverlayInternalEntryOffsets.classObject, "resourceName",
441 "Ljava/lang/String;");
442 gFabricatedOverlayInternalEntryOffsets.dataType =
443 GetFieldIDOrDie(env, gFabricatedOverlayInternalEntryOffsets.classObject, "dataType",
444 "I");
445 gFabricatedOverlayInternalEntryOffsets.data =
446 GetFieldIDOrDie(env, gFabricatedOverlayInternalEntryOffsets.classObject, "data", "I");
447 gFabricatedOverlayInternalEntryOffsets.stringData =
448 GetFieldIDOrDie(env, gFabricatedOverlayInternalEntryOffsets.classObject, "stringData",
449 "Ljava/lang/String;");
450 gFabricatedOverlayInternalEntryOffsets.binaryData =
451 GetFieldIDOrDie(env, gFabricatedOverlayInternalEntryOffsets.classObject, "binaryData",
452 "Landroid/os/ParcelFileDescriptor;");
453 gFabricatedOverlayInternalEntryOffsets.configuration =
454 GetFieldIDOrDie(env, gFabricatedOverlayInternalEntryOffsets.classObject,
455 "configuration", "Ljava/lang/String;");
456 gFabricatedOverlayInternalEntryOffsets.binaryDataOffset =
457 GetFieldIDOrDie(env, gFabricatedOverlayInternalEntryOffsets.classObject,
458 "binaryDataOffset", "J");
459 gFabricatedOverlayInternalEntryOffsets.binaryDataSize =
460 GetFieldIDOrDie(env, gFabricatedOverlayInternalEntryOffsets.classObject,
461 "binaryDataSize", "J");
462 gFabricatedOverlayInternalEntryOffsets.isNinePatch =
463 GetFieldIDOrDie(env, gFabricatedOverlayInternalEntryOffsets.classObject, "isNinePatch",
464 "Z");
465
466 jclass parcelFileDescriptorClass =
467 android::FindClassOrDie(env, "android/os/ParcelFileDescriptor");
468 gParcelFileDescriptorOffsets.classObject = MakeGlobalRefOrDie(env, parcelFileDescriptorClass);
469 gParcelFileDescriptorOffsets.getFd =
470 GetMethodIDOrDie(env, gParcelFileDescriptorOffsets.classObject, "getFd", "()I");
471
472 jclass fabricatedOverlayInfoClass = FindClassOrDie(env, "android/os/FabricatedOverlayInfo");
473 gFabricatedOverlayInfoOffsets.classObject = MakeGlobalRefOrDie(env, fabricatedOverlayInfoClass);
474 gFabricatedOverlayInfoOffsets.constructor =
475 GetMethodIDOrDie(env, gFabricatedOverlayInfoOffsets.classObject, "<init>", "()V");
476 gFabricatedOverlayInfoOffsets.packageName =
477 GetFieldIDOrDie(env, gFabricatedOverlayInfoOffsets.classObject, "packageName",
478 "Ljava/lang/String;");
479 gFabricatedOverlayInfoOffsets.overlayName =
480 GetFieldIDOrDie(env, gFabricatedOverlayInfoOffsets.classObject, "overlayName",
481 "Ljava/lang/String;");
482 gFabricatedOverlayInfoOffsets.targetPackageName =
483 GetFieldIDOrDie(env, gFabricatedOverlayInfoOffsets.classObject, "targetPackageName",
484 "Ljava/lang/String;");
485 gFabricatedOverlayInfoOffsets.targetOverlayable =
486 GetFieldIDOrDie(env, gFabricatedOverlayInfoOffsets.classObject, "targetOverlayable",
487 "Ljava/lang/String;");
488 gFabricatedOverlayInfoOffsets.path =
489 GetFieldIDOrDie(env, gFabricatedOverlayInfoOffsets.classObject, "path",
490 "Ljava/lang/String;");
491
492 return RegisterMethodsOrDie(env, "com/android/internal/content/om/OverlayManagerImpl",
493 gOverlayManagerMethods, NELEM(gOverlayManagerMethods));
494 }
495
496 } // namespace android
497