blob: 8f3e888c4175afe45372b162dd609d406eadb2e9 [file] [log] [blame]
Songchun Fan1e4508c2019-12-04 14:58:07 -08001/*
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 */
Alex Buynytskyyfd17ea02019-12-11 10:59:34 -080016#define LOG_TAG "dataloader-manageddataloader"
Songchun Fan1e4508c2019-12-04 14:58:07 -080017
18#include "ManagedDataLoader.h"
19
20#include <android-base/logging.h>
21
22#include "JNIHelpers.h"
23
Alex Buynytskyyfd17ea02019-12-11 10:59:34 -080024namespace android::dataloader {
Songchun Fan1e4508c2019-12-04 14:58:07 -080025
26namespace {
27
28struct JniIds {
Songchun Fan1e4508c2019-12-04 14:58:07 -080029 jclass dataLoaderParams;
Alex Buynytskyy1be31692019-12-17 10:41:14 -080030 jmethodID dataLoaderParamsConstruct;
31
32 jclass fileSystemConnector;
33 jmethodID fileSystemConnectorConstruct;
Songchun Fan1e4508c2019-12-04 14:58:07 -080034
35 jmethodID dataLoaderServiceOnCreateDataLoader;
36
37 jmethodID dataLoaderOnCreate;
Alex Buynytskyy1be31692019-12-17 10:41:14 -080038 jmethodID dataLoaderOnPrepareImage;
Songchun Fan1e4508c2019-12-04 14:58:07 -080039
Alex Buynytskyyebe71e52020-02-10 07:41:22 -080040 jclass installationFile;
41 jmethodID installationFileCtor;
42
43 jclass arrayList;
44 jmethodID arrayListCtor;
45 jmethodID arrayListAdd;
46
Songchun Fan1e4508c2019-12-04 14:58:07 -080047 JniIds(JNIEnv* env) {
Songchun Fan1e4508c2019-12-04 14:58:07 -080048 dataLoaderParams = (jclass)env->NewGlobalRef(
Alex Buynytskyy1be31692019-12-17 10:41:14 -080049 FindClassOrDie(env, "android/content/pm/DataLoaderParams"));
50 dataLoaderParamsConstruct =
51 GetMethodIDOrDie(env, dataLoaderParams, "<init>",
52 "(Landroid/content/pm/DataLoaderParamsParcel;)V");
53
54 fileSystemConnector = (jclass)env->NewGlobalRef(
55 FindClassOrDie(env,
56 "android/service/dataloader/DataLoaderService$FileSystemConnector"));
57 fileSystemConnectorConstruct = GetMethodIDOrDie(env, fileSystemConnector, "<init>", "(J)V");
Songchun Fan1e4508c2019-12-04 14:58:07 -080058
59 auto dataLoaderService =
Alex Buynytskyy1be31692019-12-17 10:41:14 -080060 FindClassOrDie(env, "android/service/dataloader/DataLoaderService");
Songchun Fan1e4508c2019-12-04 14:58:07 -080061 dataLoaderServiceOnCreateDataLoader =
62 GetMethodIDOrDie(env, dataLoaderService, "onCreateDataLoader",
Alex Buynytskyy54f7e132020-02-08 17:53:10 -080063 "(Landroid/content/pm/DataLoaderParams;)Landroid/service/"
64 "dataloader/DataLoaderService$DataLoader;");
Songchun Fan1e4508c2019-12-04 14:58:07 -080065
Alex Buynytskyy1be31692019-12-17 10:41:14 -080066 auto dataLoader =
67 FindClassOrDie(env, "android/service/dataloader/DataLoaderService$DataLoader");
Songchun Fan1e4508c2019-12-04 14:58:07 -080068 dataLoaderOnCreate =
69 GetMethodIDOrDie(env, dataLoader, "onCreate",
Alex Buynytskyy1be31692019-12-17 10:41:14 -080070 "(Landroid/content/pm/DataLoaderParams;Landroid/service/"
71 "dataloader/DataLoaderService$FileSystemConnector;)Z");
72 dataLoaderOnPrepareImage =
73 GetMethodIDOrDie(env, dataLoader, "onPrepareImage",
74 "(Ljava/util/Collection;Ljava/util/Collection;)Z");
Alex Buynytskyyebe71e52020-02-10 07:41:22 -080075
76 arrayList = (jclass)env->NewGlobalRef(FindClassOrDie(env, "java/util/ArrayList"));
77 arrayListCtor = GetMethodIDOrDie(env, arrayList, "<init>", "(I)V");
78 arrayListAdd = GetMethodIDOrDie(env, arrayList, "add", "(Ljava/lang/Object;)Z");
79
80 installationFile = (jclass)env->NewGlobalRef(
81 FindClassOrDie(env, "android/content/pm/InstallationFile"));
82 installationFileCtor =
83 GetMethodIDOrDie(env, installationFile, "<init>", "(ILjava/lang/String;J[B[B)V");
Songchun Fan1e4508c2019-12-04 14:58:07 -080084 }
85};
86
87const JniIds& jniIds(JNIEnv* env) {
88 static const JniIds ids(env);
89 return ids;
90}
91
92} // namespace
93
94ManagedDataLoader::ManagedDataLoader(JavaVM* jvm) : mJvm(jvm) {
95 CHECK(mJvm);
96}
97
Alex Buynytskyyfd17ea02019-12-11 10:59:34 -080098bool ManagedDataLoader::onCreate(const android::dataloader::DataLoaderParams&,
99 android::dataloader::FilesystemConnectorPtr ifs,
100 android::dataloader::StatusListenerPtr listener,
101 android::dataloader::ServiceConnectorPtr service,
102 android::dataloader::ServiceParamsPtr params) {
Songchun Fan1e4508c2019-12-04 14:58:07 -0800103 CHECK(!mDataLoader);
104
105 JNIEnv* env = GetJNIEnvironment(mJvm);
106 const auto& jni = jniIds(env);
107
Alex Buynytskyy1be31692019-12-17 10:41:14 -0800108 jobject dlp = env->NewObject(jni.dataLoaderParams, jni.dataLoaderParamsConstruct, params);
109 jobject ifsc =
110 env->NewObject(jni.fileSystemConnector, jni.fileSystemConnectorConstruct, (jlong)ifs);
Songchun Fan1e4508c2019-12-04 14:58:07 -0800111
Alex Buynytskyy54f7e132020-02-08 17:53:10 -0800112 auto dataLoader = env->CallObjectMethod(service, jni.dataLoaderServiceOnCreateDataLoader, dlp);
Songchun Fan1e4508c2019-12-04 14:58:07 -0800113 if (!dataLoader) {
114 LOG(ERROR) << "Failed to create Java DataLoader.";
115 return false;
116 }
Alex Buynytskyy0958fe72019-12-27 19:02:35 -0800117 if (env->ExceptionCheck()) {
118 return false;
119 }
Songchun Fan1e4508c2019-12-04 14:58:07 -0800120
Songchun Fan1e4508c2019-12-04 14:58:07 -0800121 mDataLoader = env->NewGlobalRef(dataLoader);
Alex Buynytskyy1be31692019-12-17 10:41:14 -0800122 return env->CallBooleanMethod(mDataLoader, jni.dataLoaderOnCreate, dlp, ifsc);
Songchun Fan1e4508c2019-12-04 14:58:07 -0800123}
Songchun Fan1e4508c2019-12-04 14:58:07 -0800124
Songchun Fan1e4508c2019-12-04 14:58:07 -0800125void ManagedDataLoader::onDestroy() {
126 CHECK(mDataLoader);
127
128 JNIEnv* env = GetJNIEnvironment(mJvm);
Songchun Fan1e4508c2019-12-04 14:58:07 -0800129
Songchun Fan1e4508c2019-12-04 14:58:07 -0800130 env->DeleteGlobalRef(mDataLoader);
131 mDataLoader = nullptr;
132}
133
Alex Buynytskyyebe71e52020-02-10 07:41:22 -0800134static jobject toJavaArrayList(JNIEnv* env, const JniIds& jni,
135 const DataLoaderInstallationFiles& files) {
136 jobject arrayList =
137 env->NewObject(jni.arrayList, jni.arrayListCtor, static_cast<jint>(files.size()));
138 for (const auto& file : files) {
139 const auto location(file.location);
140 const auto size(file.size);
141
142 jstring name = env->NewStringUTF(file.name);
143 jbyteArray metadata = env->NewByteArray(file.metadata.size);
144 if (metadata != nullptr) {
145 env->SetByteArrayRegion(metadata, 0, file.metadata.size,
146 (const jbyte*)file.metadata.data);
147 }
148
149 jobject jfile = env->NewObject(jni.installationFile, jni.installationFileCtor, location,
150 name, size, metadata, nullptr);
151 env->CallBooleanMethod(arrayList, jni.arrayListAdd, jfile);
152 }
153 return arrayList;
154}
155
Songchun Fan3ffdbd52020-02-26 13:05:29 -0800156bool ManagedDataLoader::onPrepareImage(DataLoaderInstallationFiles addedFiles) {
Songchun Fan1e4508c2019-12-04 14:58:07 -0800157 CHECK(mDataLoader);
158
159 auto env = GetOrAttachJNIEnvironment(mJvm);
160 const auto& jni = jniIds(env);
161
Alex Buynytskyyebe71e52020-02-10 07:41:22 -0800162 jobject jaddedFiles = toJavaArrayList(env, jni, addedFiles);
163 return env->CallBooleanMethod(mDataLoader, jni.dataLoaderOnPrepareImage, jaddedFiles, nullptr);
Songchun Fan1e4508c2019-12-04 14:58:07 -0800164}
165
Alex Buynytskyyfd17ea02019-12-11 10:59:34 -0800166} // namespace android::dataloader