xref: /aosp_15_r20/system/incremental_delivery/libdataloader/ManagedDataLoader.cpp (revision 9190c2a8bd3622b7aa9bd7bfe4b3aec77820f478)
1*9190c2a8SAndroid Build Coastguard Worker /*
2*9190c2a8SAndroid Build Coastguard Worker  * Copyright (C) 2019 The Android Open Source Project
3*9190c2a8SAndroid Build Coastguard Worker  *
4*9190c2a8SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*9190c2a8SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*9190c2a8SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*9190c2a8SAndroid Build Coastguard Worker  *
8*9190c2a8SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*9190c2a8SAndroid Build Coastguard Worker  *
10*9190c2a8SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*9190c2a8SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*9190c2a8SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*9190c2a8SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*9190c2a8SAndroid Build Coastguard Worker  * limitations under the License.
15*9190c2a8SAndroid Build Coastguard Worker  */
16*9190c2a8SAndroid Build Coastguard Worker #define LOG_TAG "dataloader-manageddataloader"
17*9190c2a8SAndroid Build Coastguard Worker 
18*9190c2a8SAndroid Build Coastguard Worker #include "ManagedDataLoader.h"
19*9190c2a8SAndroid Build Coastguard Worker 
20*9190c2a8SAndroid Build Coastguard Worker #include <android-base/logging.h>
21*9190c2a8SAndroid Build Coastguard Worker 
22*9190c2a8SAndroid Build Coastguard Worker #include "JNIHelpers.h"
23*9190c2a8SAndroid Build Coastguard Worker 
24*9190c2a8SAndroid Build Coastguard Worker namespace android::dataloader {
25*9190c2a8SAndroid Build Coastguard Worker 
26*9190c2a8SAndroid Build Coastguard Worker namespace {
27*9190c2a8SAndroid Build Coastguard Worker 
28*9190c2a8SAndroid Build Coastguard Worker struct JniIds {
29*9190c2a8SAndroid Build Coastguard Worker     jclass dataLoaderParams;
30*9190c2a8SAndroid Build Coastguard Worker     jmethodID dataLoaderParamsConstruct;
31*9190c2a8SAndroid Build Coastguard Worker 
32*9190c2a8SAndroid Build Coastguard Worker     jclass fileSystemConnector;
33*9190c2a8SAndroid Build Coastguard Worker     jmethodID fileSystemConnectorConstruct;
34*9190c2a8SAndroid Build Coastguard Worker 
35*9190c2a8SAndroid Build Coastguard Worker     jmethodID dataLoaderServiceOnCreateDataLoader;
36*9190c2a8SAndroid Build Coastguard Worker 
37*9190c2a8SAndroid Build Coastguard Worker     jmethodID dataLoaderOnCreate;
38*9190c2a8SAndroid Build Coastguard Worker     jmethodID dataLoaderOnPrepareImage;
39*9190c2a8SAndroid Build Coastguard Worker 
40*9190c2a8SAndroid Build Coastguard Worker     jclass installationFile;
41*9190c2a8SAndroid Build Coastguard Worker     jmethodID installationFileCtor;
42*9190c2a8SAndroid Build Coastguard Worker 
43*9190c2a8SAndroid Build Coastguard Worker     jclass arrayList;
44*9190c2a8SAndroid Build Coastguard Worker     jmethodID arrayListCtor;
45*9190c2a8SAndroid Build Coastguard Worker     jmethodID arrayListAdd;
46*9190c2a8SAndroid Build Coastguard Worker 
JniIdsandroid::dataloader::__anon08990d530111::JniIds47*9190c2a8SAndroid Build Coastguard Worker     JniIds(JNIEnv* env) {
48*9190c2a8SAndroid Build Coastguard Worker         dataLoaderParams = (jclass)env->NewGlobalRef(
49*9190c2a8SAndroid Build Coastguard Worker                 FindClassOrDie(env, "android/content/pm/DataLoaderParams"));
50*9190c2a8SAndroid Build Coastguard Worker         dataLoaderParamsConstruct =
51*9190c2a8SAndroid Build Coastguard Worker                 GetMethodIDOrDie(env, dataLoaderParams, "<init>",
52*9190c2a8SAndroid Build Coastguard Worker                                  "(Landroid/content/pm/DataLoaderParamsParcel;)V");
53*9190c2a8SAndroid Build Coastguard Worker 
54*9190c2a8SAndroid Build Coastguard Worker         fileSystemConnector = (jclass)env->NewGlobalRef(
55*9190c2a8SAndroid Build Coastguard Worker                 FindClassOrDie(env,
56*9190c2a8SAndroid Build Coastguard Worker                                "android/service/dataloader/DataLoaderService$FileSystemConnector"));
57*9190c2a8SAndroid Build Coastguard Worker         fileSystemConnectorConstruct = GetMethodIDOrDie(env, fileSystemConnector, "<init>", "(J)V");
58*9190c2a8SAndroid Build Coastguard Worker 
59*9190c2a8SAndroid Build Coastguard Worker         auto dataLoaderService =
60*9190c2a8SAndroid Build Coastguard Worker                 FindClassOrDie(env, "android/service/dataloader/DataLoaderService");
61*9190c2a8SAndroid Build Coastguard Worker         dataLoaderServiceOnCreateDataLoader =
62*9190c2a8SAndroid Build Coastguard Worker                 GetMethodIDOrDie(env, dataLoaderService, "onCreateDataLoader",
63*9190c2a8SAndroid Build Coastguard Worker                                  "(Landroid/content/pm/DataLoaderParams;)Landroid/service/"
64*9190c2a8SAndroid Build Coastguard Worker                                  "dataloader/DataLoaderService$DataLoader;");
65*9190c2a8SAndroid Build Coastguard Worker 
66*9190c2a8SAndroid Build Coastguard Worker         auto dataLoader =
67*9190c2a8SAndroid Build Coastguard Worker                 FindClassOrDie(env, "android/service/dataloader/DataLoaderService$DataLoader");
68*9190c2a8SAndroid Build Coastguard Worker         dataLoaderOnCreate =
69*9190c2a8SAndroid Build Coastguard Worker                 GetMethodIDOrDie(env, dataLoader, "onCreate",
70*9190c2a8SAndroid Build Coastguard Worker                                  "(Landroid/content/pm/DataLoaderParams;Landroid/service/"
71*9190c2a8SAndroid Build Coastguard Worker                                  "dataloader/DataLoaderService$FileSystemConnector;)Z");
72*9190c2a8SAndroid Build Coastguard Worker         dataLoaderOnPrepareImage =
73*9190c2a8SAndroid Build Coastguard Worker                 GetMethodIDOrDie(env, dataLoader, "onPrepareImage",
74*9190c2a8SAndroid Build Coastguard Worker                                  "(Ljava/util/Collection;Ljava/util/Collection;)Z");
75*9190c2a8SAndroid Build Coastguard Worker 
76*9190c2a8SAndroid Build Coastguard Worker         arrayList = (jclass)env->NewGlobalRef(FindClassOrDie(env, "java/util/ArrayList"));
77*9190c2a8SAndroid Build Coastguard Worker         arrayListCtor = GetMethodIDOrDie(env, arrayList, "<init>", "(I)V");
78*9190c2a8SAndroid Build Coastguard Worker         arrayListAdd = GetMethodIDOrDie(env, arrayList, "add", "(Ljava/lang/Object;)Z");
79*9190c2a8SAndroid Build Coastguard Worker 
80*9190c2a8SAndroid Build Coastguard Worker         installationFile = (jclass)env->NewGlobalRef(
81*9190c2a8SAndroid Build Coastguard Worker                 FindClassOrDie(env, "android/content/pm/InstallationFile"));
82*9190c2a8SAndroid Build Coastguard Worker         installationFileCtor =
83*9190c2a8SAndroid Build Coastguard Worker                 GetMethodIDOrDie(env, installationFile, "<init>", "(ILjava/lang/String;J[B[B)V");
84*9190c2a8SAndroid Build Coastguard Worker     }
85*9190c2a8SAndroid Build Coastguard Worker };
86*9190c2a8SAndroid Build Coastguard Worker 
jniIds(JNIEnv * env)87*9190c2a8SAndroid Build Coastguard Worker const JniIds& jniIds(JNIEnv* env) {
88*9190c2a8SAndroid Build Coastguard Worker     static const JniIds ids(env);
89*9190c2a8SAndroid Build Coastguard Worker     return ids;
90*9190c2a8SAndroid Build Coastguard Worker }
91*9190c2a8SAndroid Build Coastguard Worker 
92*9190c2a8SAndroid Build Coastguard Worker } // namespace
93*9190c2a8SAndroid Build Coastguard Worker 
ManagedDataLoader(JavaVM * jvm,jobject dataLoader)94*9190c2a8SAndroid Build Coastguard Worker ManagedDataLoader::ManagedDataLoader(JavaVM* jvm, jobject dataLoader)
95*9190c2a8SAndroid Build Coastguard Worker       : mJvm(jvm), mDataLoader(dataLoader) {
96*9190c2a8SAndroid Build Coastguard Worker     CHECK(mJvm);
97*9190c2a8SAndroid Build Coastguard Worker 
98*9190c2a8SAndroid Build Coastguard Worker     LegacyDataLoader::onStart = [](auto) -> bool { return true; };
99*9190c2a8SAndroid Build Coastguard Worker     LegacyDataLoader::onStop = [](auto) {};
100*9190c2a8SAndroid Build Coastguard Worker     LegacyDataLoader::onDestroy = [](LegacyDataLoader* self) {
101*9190c2a8SAndroid Build Coastguard Worker         auto me = static_cast<ManagedDataLoader*>(self);
102*9190c2a8SAndroid Build Coastguard Worker         me->onDestroy();
103*9190c2a8SAndroid Build Coastguard Worker         delete me;
104*9190c2a8SAndroid Build Coastguard Worker     };
105*9190c2a8SAndroid Build Coastguard Worker     LegacyDataLoader::onPrepareImage = [](auto* self, const auto addedFiles[],
106*9190c2a8SAndroid Build Coastguard Worker                                           int addedFilesCount) -> bool {
107*9190c2a8SAndroid Build Coastguard Worker         return static_cast<ManagedDataLoader*>(self)->onPrepareImage(
108*9190c2a8SAndroid Build Coastguard Worker                 DataLoaderInstallationFiles(addedFiles, addedFilesCount));
109*9190c2a8SAndroid Build Coastguard Worker     };
110*9190c2a8SAndroid Build Coastguard Worker     LegacyDataLoader::onPendingReads = [](auto, auto, auto) {};
111*9190c2a8SAndroid Build Coastguard Worker     LegacyDataLoader::onPageReads = [](auto, auto, auto) {};
112*9190c2a8SAndroid Build Coastguard Worker }
113*9190c2a8SAndroid Build Coastguard Worker 
create(JavaVM * jvm,android::dataloader::FilesystemConnectorPtr ifs,android::dataloader::StatusListenerPtr listener,android::dataloader::ServiceConnectorPtr service,android::dataloader::ServiceParamsPtr params)114*9190c2a8SAndroid Build Coastguard Worker LegacyDataLoader* ManagedDataLoader::create(JavaVM* jvm,
115*9190c2a8SAndroid Build Coastguard Worker                                             android::dataloader::FilesystemConnectorPtr ifs,
116*9190c2a8SAndroid Build Coastguard Worker                                             android::dataloader::StatusListenerPtr listener,
117*9190c2a8SAndroid Build Coastguard Worker                                             android::dataloader::ServiceConnectorPtr service,
118*9190c2a8SAndroid Build Coastguard Worker                                             android::dataloader::ServiceParamsPtr params) {
119*9190c2a8SAndroid Build Coastguard Worker     JNIEnv* env = GetJNIEnvironment(jvm);
120*9190c2a8SAndroid Build Coastguard Worker     const auto& jni = jniIds(env);
121*9190c2a8SAndroid Build Coastguard Worker 
122*9190c2a8SAndroid Build Coastguard Worker     jobject dlp = env->NewObject(jni.dataLoaderParams, jni.dataLoaderParamsConstruct, params);
123*9190c2a8SAndroid Build Coastguard Worker     jobject ifsc =
124*9190c2a8SAndroid Build Coastguard Worker             env->NewObject(jni.fileSystemConnector, jni.fileSystemConnectorConstruct, (jlong)ifs);
125*9190c2a8SAndroid Build Coastguard Worker 
126*9190c2a8SAndroid Build Coastguard Worker     auto dataLoader = env->CallObjectMethod(service, jni.dataLoaderServiceOnCreateDataLoader, dlp);
127*9190c2a8SAndroid Build Coastguard Worker     if (!dataLoader) {
128*9190c2a8SAndroid Build Coastguard Worker         LOG(ERROR) << "Failed to create Java DataLoader.";
129*9190c2a8SAndroid Build Coastguard Worker         return nullptr;
130*9190c2a8SAndroid Build Coastguard Worker     }
131*9190c2a8SAndroid Build Coastguard Worker     if (env->ExceptionCheck()) {
132*9190c2a8SAndroid Build Coastguard Worker         return nullptr;
133*9190c2a8SAndroid Build Coastguard Worker     }
134*9190c2a8SAndroid Build Coastguard Worker     if (!env->CallBooleanMethod(dataLoader, jni.dataLoaderOnCreate, dlp, ifsc)) {
135*9190c2a8SAndroid Build Coastguard Worker         return nullptr;
136*9190c2a8SAndroid Build Coastguard Worker     }
137*9190c2a8SAndroid Build Coastguard Worker 
138*9190c2a8SAndroid Build Coastguard Worker     return new ManagedDataLoader(jvm, env->NewGlobalRef(dataLoader));
139*9190c2a8SAndroid Build Coastguard Worker }
140*9190c2a8SAndroid Build Coastguard Worker 
onDestroy()141*9190c2a8SAndroid Build Coastguard Worker void ManagedDataLoader::onDestroy() {
142*9190c2a8SAndroid Build Coastguard Worker     CHECK(mDataLoader);
143*9190c2a8SAndroid Build Coastguard Worker 
144*9190c2a8SAndroid Build Coastguard Worker     JNIEnv* env = GetJNIEnvironment(mJvm);
145*9190c2a8SAndroid Build Coastguard Worker 
146*9190c2a8SAndroid Build Coastguard Worker     env->DeleteGlobalRef(mDataLoader);
147*9190c2a8SAndroid Build Coastguard Worker     mDataLoader = nullptr;
148*9190c2a8SAndroid Build Coastguard Worker }
149*9190c2a8SAndroid Build Coastguard Worker 
toJavaArrayList(JNIEnv * env,const JniIds & jni,const DataLoaderInstallationFiles & files)150*9190c2a8SAndroid Build Coastguard Worker static jobject toJavaArrayList(JNIEnv* env, const JniIds& jni,
151*9190c2a8SAndroid Build Coastguard Worker                                const DataLoaderInstallationFiles& files) {
152*9190c2a8SAndroid Build Coastguard Worker     jobject arrayList =
153*9190c2a8SAndroid Build Coastguard Worker             env->NewObject(jni.arrayList, jni.arrayListCtor, static_cast<jint>(files.size()));
154*9190c2a8SAndroid Build Coastguard Worker     for (const auto& file : files) {
155*9190c2a8SAndroid Build Coastguard Worker         const auto location(file.location);
156*9190c2a8SAndroid Build Coastguard Worker         const auto size(file.size);
157*9190c2a8SAndroid Build Coastguard Worker 
158*9190c2a8SAndroid Build Coastguard Worker         jstring name = env->NewStringUTF(file.name);
159*9190c2a8SAndroid Build Coastguard Worker         jbyteArray metadata = env->NewByteArray(file.metadata.size);
160*9190c2a8SAndroid Build Coastguard Worker         if (metadata != nullptr) {
161*9190c2a8SAndroid Build Coastguard Worker             env->SetByteArrayRegion(metadata, 0, file.metadata.size,
162*9190c2a8SAndroid Build Coastguard Worker                                     (const jbyte*)file.metadata.data);
163*9190c2a8SAndroid Build Coastguard Worker         }
164*9190c2a8SAndroid Build Coastguard Worker 
165*9190c2a8SAndroid Build Coastguard Worker         jobject jfile = env->NewObject(jni.installationFile, jni.installationFileCtor, location,
166*9190c2a8SAndroid Build Coastguard Worker                                        name, size, metadata, nullptr);
167*9190c2a8SAndroid Build Coastguard Worker         env->CallBooleanMethod(arrayList, jni.arrayListAdd, jfile);
168*9190c2a8SAndroid Build Coastguard Worker     }
169*9190c2a8SAndroid Build Coastguard Worker     return arrayList;
170*9190c2a8SAndroid Build Coastguard Worker }
171*9190c2a8SAndroid Build Coastguard Worker 
onPrepareImage(DataLoaderInstallationFiles addedFiles)172*9190c2a8SAndroid Build Coastguard Worker bool ManagedDataLoader::onPrepareImage(DataLoaderInstallationFiles addedFiles) {
173*9190c2a8SAndroid Build Coastguard Worker     CHECK(mDataLoader);
174*9190c2a8SAndroid Build Coastguard Worker 
175*9190c2a8SAndroid Build Coastguard Worker     auto env = GetOrAttachJNIEnvironment(mJvm);
176*9190c2a8SAndroid Build Coastguard Worker     const auto& jni = jniIds(env);
177*9190c2a8SAndroid Build Coastguard Worker 
178*9190c2a8SAndroid Build Coastguard Worker     jobject jaddedFiles = toJavaArrayList(env, jni, addedFiles);
179*9190c2a8SAndroid Build Coastguard Worker     return env->CallBooleanMethod(mDataLoader, jni.dataLoaderOnPrepareImage, jaddedFiles, nullptr);
180*9190c2a8SAndroid Build Coastguard Worker }
181*9190c2a8SAndroid Build Coastguard Worker 
ManagedDataLoaderFactory()182*9190c2a8SAndroid Build Coastguard Worker ManagedDataLoaderFactory::ManagedDataLoaderFactory() {
183*9190c2a8SAndroid Build Coastguard Worker     ::DataLoaderFactory::onCreate =
184*9190c2a8SAndroid Build Coastguard Worker             [](::DataLoaderFactory* self, const ::DataLoaderParams* ndkParams,
185*9190c2a8SAndroid Build Coastguard Worker                ::DataLoaderFilesystemConnectorPtr fsConnector,
186*9190c2a8SAndroid Build Coastguard Worker                ::DataLoaderStatusListenerPtr statusListener, ::DataLoaderServiceVmPtr vm,
187*9190c2a8SAndroid Build Coastguard Worker                ::DataLoaderServiceConnectorPtr serviceConnector,
188*9190c2a8SAndroid Build Coastguard Worker                ::DataLoaderServiceParamsPtr serviceParams) -> ::DataLoader* {
189*9190c2a8SAndroid Build Coastguard Worker         return reinterpret_cast<::DataLoader*>(
190*9190c2a8SAndroid Build Coastguard Worker                 ManagedDataLoader::create(vm, static_cast<FilesystemConnector*>(fsConnector),
191*9190c2a8SAndroid Build Coastguard Worker                                           static_cast<StatusListener*>(statusListener),
192*9190c2a8SAndroid Build Coastguard Worker                                           serviceConnector, serviceParams));
193*9190c2a8SAndroid Build Coastguard Worker     };
194*9190c2a8SAndroid Build Coastguard Worker }
195*9190c2a8SAndroid Build Coastguard Worker 
196*9190c2a8SAndroid Build Coastguard Worker } // namespace android::dataloader
197