Skip to content

Commit edfb987

Browse files
committed
Feat: Initial support for split apks
Signed-off-by: tiann <twsxtd@gmail.com>
1 parent 38f3be7 commit edfb987

6 files changed

Lines changed: 73 additions & 7 deletions

File tree

VirtualApp/lib/src/main/java/android/content/pm/PackageParser.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ public class Package {
6363
// Applications requested features
6464
public ArrayList<FeatureInfo> reqFeatures = null;
6565
public int mSharedUserLabel;
66+
67+
public String[] splitNames;
68+
public String codePath;
69+
public String baseCodePath;
70+
public String[] splitCodePaths;
6671
}
6772

6873
public final class Service extends Component<ServiceIntentInfo> {

VirtualApp/lib/src/main/java/com/lody/virtual/server/pm/VAppManagerService.java

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ public synchronized InstallResult installPackage(String path, int flags, boolean
147147
return InstallResult.makeFailure("path = NULL");
148148
}
149149
File packageFile = new File(path);
150-
if (!packageFile.exists() || !packageFile.isFile()) {
150+
if (!packageFile.exists()) {
151151
return InstallResult.makeFailure("Package File is not exist.");
152152
}
153153
VPackage pkg = null;
@@ -191,7 +191,6 @@ public synchronized InstallResult installPackage(String path, int flags, boolean
191191
dependSystem = false;
192192
}
193193

194-
NativeLibraryHelperCompat.copyNativeBinaries(new File(path), libDir);
195194
if (!dependSystem) {
196195
File privatePackageFile = new File(appDir, "base.apk");
197196
File parentFolder = privatePackageFile.getParentFile();
@@ -200,14 +199,36 @@ public synchronized InstallResult installPackage(String path, int flags, boolean
200199
} else if (privatePackageFile.exists() && !privatePackageFile.delete()) {
201200
VLog.w(TAG, "Warning: unable to delete file : " + privatePackageFile.getPath());
202201
}
202+
File baseApkFile = packageFile.isFile() ? packageFile : new File(pkg.baseCodePath);
203203
try {
204-
FileUtils.copyFile(packageFile, privatePackageFile);
204+
FileUtils.copyFile(baseApkFile, privatePackageFile);
205205
} catch (IOException e) {
206206
privatePackageFile.delete();
207207
return InstallResult.makeFailure("Unable to copy the package file.");
208208
}
209+
// copy lib in base apk
210+
NativeLibraryHelperCompat.copyNativeBinaries(baseApkFile, libDir);
211+
209212
packageFile = privatePackageFile;
213+
214+
if (pkg.splitNames != null) {
215+
int length = pkg.splitNames.length;
216+
for (int i = 0; i < length; i++) {
217+
String splitName = pkg.splitNames[i];
218+
File privateSplitFile = new File(appDir, splitName + ".apk");
219+
try {
220+
FileUtils.copyFile(new File(pkg.splitCodePaths[i]), privateSplitFile);
221+
222+
// copy lib in split apk
223+
NativeLibraryHelperCompat.copyNativeBinaries(privateSplitFile, libDir);
224+
} catch (IOException e) {
225+
privateSplitFile.delete();
226+
return InstallResult.makeFailure("Unable to copy split: " + splitName);
227+
}
228+
}
229+
}
210230
}
231+
211232
if (existOne != null) {
212233
PackageCacheManager.remove(pkg.packageName);
213234
}

VirtualApp/lib/src/main/java/com/lody/virtual/server/pm/installer/PackageInstallerSession.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
import com.lody.virtual.helper.utils.FileUtils;
2222
import com.lody.virtual.helper.utils.VLog;
23+
import com.lody.virtual.remote.InstallResult;
24+
import com.lody.virtual.server.pm.VAppManagerService;
2325

2426
import java.io.File;
2527
import java.io.FileDescriptor;
@@ -179,6 +181,10 @@ public void onPackageInstalled(String basePackageName, int returnCode, String ms
179181
dispatchSessionFinished(returnCode, msg, extras);
180182
}
181183
};
184+
185+
InstallResult installResult = VAppManagerService.get().installPackage(stageDir.getPath(), 0);
186+
destroyInternal();
187+
dispatchSessionFinished(installResult.isSuccess ? INSTALL_SUCCEEDED : INSTALL_FAILED_INTERNAL_ERROR, installResult.toString(), null);
182188
}
183189

184190
private void validateInstallLocked() throws PackageManagerException {
@@ -193,14 +199,13 @@ private void validateInstallLocked() throws PackageManagerException {
193199
final String targetName = "base.apk";
194200
final File targetFile = new File(mResolvedStageDir, targetName);
195201
if (!addedFile.equals(targetFile)) {
196-
// addedFile.renameTo(targetFile);
197-
mResolvedStagedFiles.add(targetFile);
202+
mResolvedStagedFiles.add(addedFile);
198203
} else {
199204
mResolvedBaseFile = targetFile;
200205
}
201206
}
202207
}
203-
if (mResolvedBaseFile == null) {
208+
if (mResolvedBaseFile == null && mResolvedStagedFiles.isEmpty()) {
204209
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
205210
"Full install must include a base package");
206211
}

VirtualApp/lib/src/main/java/com/lody/virtual/server/pm/installer/VPackageInstallerService.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import com.lody.virtual.server.IPackageInstaller;
3030
import com.lody.virtual.server.pm.VAppManagerService;
3131

32+
import java.io.File;
3233
import java.io.IOException;
3334
import java.security.SecureRandom;
3435
import java.util.ArrayList;
@@ -115,7 +116,8 @@ private int createSessionInternal(SessionParams params, String installerPackageN
115116
"Too many active sessions for UID " + callingUid);
116117
}
117118
sessionId = allocateSessionIdLocked();
118-
session = new PackageInstallerSession(mInternalCallback, mContext, mInstallHandler.getLooper(), installerPackageName, sessionId, userId, callingUid, params, VEnvironment.getPackageInstallerStageDir());
119+
File sessionDir = new File(VEnvironment.getPackageInstallerStageDir(), "vmd-" + sessionId);
120+
session = new PackageInstallerSession(mInternalCallback, mContext, mInstallHandler.getLooper(), installerPackageName, sessionId, userId, callingUid, params, sessionDir);
119121
}
120122
synchronized (mSessions) {
121123
mSessions.put(sessionId, session);

VirtualApp/lib/src/main/java/com/lody/virtual/server/pm/parser/PackageParserEx.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,15 @@ private static VPackage buildPackageCache(PackageParser.Package p) {
224224
cache.mAppMetaData = p.mAppMetaData;
225225
cache.configPreferences = p.configPreferences;
226226
cache.reqFeatures = p.reqFeatures;
227+
228+
// for split apks
229+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
230+
cache.splitNames = p.splitNames;
231+
cache.codePath = p.codePath;
232+
cache.baseCodePath = p.baseCodePath;
233+
cache.splitCodePaths = p.splitCodePaths;
234+
}
235+
227236
addOwner(cache);
228237
return cache;
229238
}

VirtualApp/lib/src/main/java/com/lody/virtual/server/pm/parser/VPackage.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,20 @@ public VPackage[] newArray(int size) {
6565
public ArrayList<FeatureInfo> reqFeatures = null;
6666
public Object mExtras;
6767

68+
public String[] splitNames;
69+
70+
/**
71+
* Path where this package was found on disk. For monolithic packages
72+
* this is path to single base APK file; for cluster packages this is
73+
* path to the cluster directory.
74+
*/
75+
public String codePath;
76+
77+
/** Path of base APK */
78+
public String baseCodePath;
79+
/** Paths of any split APKs, ordered by parsed splitName */
80+
public String[] splitCodePaths;
81+
6882
public VPackage() {
6983
}
7084

@@ -117,6 +131,11 @@ protected VPackage(Parcel in) {
117131
this.mSharedUserLabel = in.readInt();
118132
this.configPreferences = in.createTypedArrayList(ConfigurationInfo.CREATOR);
119133
this.reqFeatures = in.createTypedArrayList(FeatureInfo.CREATOR);
134+
135+
this.splitNames = in.createStringArray();
136+
this.codePath = in.readString();
137+
this.baseCodePath = in.readString();
138+
this.splitCodePaths = in.createStringArray();
120139
}
121140

122141
@Override
@@ -223,6 +242,11 @@ public void writeToParcel(Parcel dest, int flags) {
223242
dest.writeInt(this.mSharedUserLabel);
224243
dest.writeTypedList(this.configPreferences);
225244
dest.writeTypedList(this.reqFeatures);
245+
246+
dest.writeStringArray(this.splitNames);
247+
dest.writeString(this.codePath);
248+
dest.writeString(this.baseCodePath);
249+
dest.writeStringArray(this.splitCodePaths);
226250
}
227251

228252
public static class ActivityIntentInfo extends IntentInfo {

0 commit comments

Comments
 (0)