Skip to content

Commit 4d844b5

Browse files
author
fortunexiao
committed
1.适配android 13 14
1 parent 122beb3 commit 4d844b5

21 files changed

+389
-45
lines changed

VirtualApp/app/src/aosp/java/io/virtualapp/delegate/MyVirtualInitializer.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
import android.app.Application;
44

55
import com.lody.virtual.client.core.VirtualCore;
6+
import com.lody.virtual.client.hook.proxies.view.AutoFillManagerStub;
7+
import com.lody.virtual.helper.compat.BuildCompat;
8+
import com.lody.virtual.helper.utils.VLog;
69
import com.microsoft.appcenter.AppCenter;
710
import com.microsoft.appcenter.analytics.Analytics;
811
import com.microsoft.appcenter.crashes.Crashes;
@@ -12,6 +15,9 @@
1215
* @date 2019/2/25.
1316
*/
1417
public class MyVirtualInitializer extends BaseVirtualInitializer {
18+
19+
static final String TAG = "MyVirtualInitializer";
20+
1521
public MyVirtualInitializer(Application application, VirtualCore core) {
1622
super(application, core);
1723
}
@@ -34,5 +40,21 @@ public void onVirtualProcess() {
3440

3541
// Override
3642
virtualCore.setCrashHandler(new MyCrashHandler());
43+
44+
45+
if (BuildCompat.isOreo()) {
46+
// Android 13以上的版本在attachBaseContext里注入这个对象会报错,所以挪到这里来
47+
try {
48+
new AutoFillManagerStub().inject();
49+
} catch (Throwable e) {
50+
VLog.w(TAG, "AutoFillManagerStub inject error",e );
51+
}
52+
}
53+
54+
}
55+
56+
@Override
57+
public void onChildProcess() {
58+
super.onChildProcess();
3759
}
3860
}

VirtualApp/lib/src/main/java/android/app/ClientTransactionHandler.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,11 @@ public abstract void handleAttachSplashScreenView(ActivityThread.ActivityClientR
172172
/** Perform activity launch. */
173173
public abstract Activity handleLaunchActivity(ActivityThread.ActivityClientRecord r,
174174
PendingTransactionActions pendingActions, Intent customIntent);
175+
176+
// Android 13
177+
public abstract Activity handleLaunchActivity( ActivityThread.ActivityClientRecord r,
178+
PendingTransactionActions pendingActions, int deviceId, Intent customIntent);
179+
175180
/** Perform activity start. */
176181
public abstract void handleStartActivity(ActivityThread.ActivityClientRecord r,
177182
PendingTransactionActions pendingActions);
@@ -184,6 +189,10 @@ public abstract void handleStartActivity(ActivityThread.ActivityClientRecord r,
184189
// Android 11
185190
public abstract void handleStartActivity(IBinder binder,
186191
PendingTransactionActions pendingActions);
192+
193+
// Android 14
194+
public abstract LoadedApk getPackageInfoNoCheck(ApplicationInfo ai);
195+
187196
/** Get package info. */
188197
public abstract LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
189198
CompatibilityInfo compatInfo);

VirtualApp/lib/src/main/java/android/app/TransactionHandlerProxy.java

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import android.content.pm.ApplicationInfo;
1010
import android.content.res.CompatibilityInfo;
1111
import android.content.res.Configuration;
12+
import android.os.Build;
1213
import android.os.IBinder;
1314
import android.os.Parcelable;
1415
import android.util.Log;
@@ -49,6 +50,11 @@ TransactionExecutor getTransactionExecutor() {
4950
return originalHandler.getTransactionExecutor();
5051
}
5152

53+
/** Get package info. */
54+
public LoadedApk getPackageInfoNoCheck(ApplicationInfo ai) {
55+
return originalHandler.getPackageInfoNoCheck(ai);
56+
}
57+
5258
@Override
5359
void sendMessage(int what, Object obj) {
5460
originalHandler.sendMessage(what, obj);
@@ -194,8 +200,16 @@ public void handleWindowVisibility(IBinder token, boolean show) {
194200
originalHandler.handleWindowVisibility(token, show);
195201
}
196202

203+
204+
public Activity handleLaunchActivity( ActivityThread.ActivityClientRecord r,
205+
PendingTransactionActions pendingActions, Intent customIntent) {
206+
return handleLaunchActivity(r, pendingActions, 0, customIntent);
207+
}
208+
209+
210+
// Android 13
197211
@Override
198-
public Activity handleLaunchActivity(ActivityClientRecord r, PendingTransactionActions pendingActions, Intent customIntent) {
212+
public Activity handleLaunchActivity(ActivityClientRecord r, PendingTransactionActions pendingActions, int deviceId, Intent customIntent) {
199213

200214
Intent stubIntent = mirror.android.app.ActivityThread.ActivityClientRecord.intent.get(r);
201215
StubActivityRecord saveInstance = new StubActivityRecord(stubIntent);
@@ -216,13 +230,13 @@ public Activity handleLaunchActivity(ActivityClientRecord r, PendingTransactionA
216230
VActivityManager.get().processRestarted(info.packageName, info.processName, saveInstance.userId);
217231
// getH().sendMessageAtFrontOfQueue(Message.obtain(msg));
218232
Log.i(TAG, "restart process, return");
219-
return handleLaunchActivity(r, pendingActions, customIntent);
233+
return handleLaunchActivity(r, pendingActions, deviceId, customIntent);
220234
}
221235
if (!VClientImpl.get().isBound()) {
222236
VClientImpl.get().bindApplicationForActivity(info.packageName, info.processName, intent);
223237
// getH().sendMessageAtFrontOfQueue(Message.obtain(msg));
224238
Log.i(TAG, "rebound application, return");
225-
return handleLaunchActivity(r, pendingActions, customIntent);
239+
return handleLaunchActivity(r, pendingActions, deviceId, customIntent);
226240
}
227241
int taskId = IActivityManager.getTaskForActivity.call(
228242
ActivityManagerNative.getDefault.call(),
@@ -240,7 +254,12 @@ public Activity handleLaunchActivity(ActivityClientRecord r, PendingTransactionA
240254
mirror.android.app.ActivityThread.ActivityClientRecord.intent.set(r, intent);
241255
mirror.android.app.ActivityThread.ActivityClientRecord.activityInfo.set(r, info);
242256

243-
return originalHandler.handleLaunchActivity(r, pendingActions, customIntent);
257+
if (Build.VERSION.SDK_INT >= 34) {
258+
return originalHandler.handleLaunchActivity(r, pendingActions, deviceId, customIntent);
259+
} else {
260+
return originalHandler.handleLaunchActivity(r, pendingActions, customIntent);
261+
}
262+
244263
}
245264

246265
@Override
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package android.content.pm;
2+
3+
public class SigningDetails {
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package android.os;
2+
3+
public class UserHandle {
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package android.os.storage;
2+
3+
public class StorageVolume {
4+
}

VirtualApp/lib/src/main/java/com/lody/virtual/client/VClientImpl.java

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -255,19 +255,23 @@ private void bindApplicationNoCheck(String packageName, String processName, Cond
255255
null
256256
);
257257
AppBindData data = new AppBindData();
258+
258259
InstalledAppInfo info = VirtualCore.get().getInstalledAppInfo(packageName, 0);
259260
if (info == null) {
260261
new Exception("App not exist!").printStackTrace();
261262
Process.killProcess(0);
262263
System.exit(0);
263264
}
265+
VLog.d(TAG, "bindApplicationNoCheck getInstalledAppInfo:" + info);
264266
data.appInfo = VPackageManager.get().getApplicationInfo(packageName, 0, getUserId(vuid));
265267
data.processName = processName;
266268
data.appInfo.processName = processName;
267269
data.providers = VPackageManager.get().queryContentProviders(processName, getVUid(), PackageManager.GET_META_DATA);
268270
VLog.i(TAG, String.format("Binding application %s, (%s)", data.appInfo.packageName, data.processName));
269271
mBoundApplication = data;
272+
270273
VirtualRuntime.setupRuntime(data.processName, data.appInfo);
274+
271275
int targetSdkVersion = data.appInfo.targetSdkVersion;
272276
if (targetSdkVersion < Build.VERSION_CODES.GINGERBREAD) {
273277
StrictMode.ThreadPolicy newPolicy = new StrictMode.ThreadPolicy.Builder(StrictMode.getThreadPolicy()).permitNetwork().build();
@@ -282,22 +286,23 @@ private void bindApplicationNoCheck(String packageName, String processName, Cond
282286
NativeEngine.launchEngine();
283287
Object mainThread = VirtualCore.mainThread();
284288
NativeEngine.startDexOverride();
285-
Context context = createPackageContext(data.appInfo.packageName);
289+
290+
Context appContext = createPackageContext(data.appInfo.packageName);
286291
try {
287292
// anti-virus, fuck ESET-NOD32: a variant of Android/AdDisplay.AdLock.AL potentially unwanted
288293
// we can make direct call... use reflect to bypass.
289294
// System.setProperty("java.io.tmpdir", context.getCacheDir().getAbsolutePath());
290295
System.class.getDeclaredMethod("setProperty", String.class, String.class)
291-
.invoke(null, "java.io.tmpdir", context.getCacheDir().getAbsolutePath());
296+
.invoke(null, "java.io.tmpdir", appContext.getCacheDir().getAbsolutePath());
292297
} catch (Throwable ignored) {
293298
VLog.e(TAG, "set tmp dir error:", ignored);
294299
}
295300

296301
File codeCacheDir;
297302
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
298-
codeCacheDir = context.getCodeCacheDir();
303+
codeCacheDir = appContext.getCodeCacheDir();
299304
} else {
300-
codeCacheDir = context.getCacheDir();
305+
codeCacheDir = appContext.getCacheDir();
301306
}
302307
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
303308
if (HardwareRenderer.setupDiskCache != null) {
@@ -318,7 +323,8 @@ private void bindApplicationNoCheck(String packageName, String processName, Cond
318323
}
319324
}
320325
Object boundApp = fixBoundApp(mBoundApplication);
321-
mBoundApplication.info = ContextImpl.mPackageInfo.get(context);
326+
mBoundApplication.info = ContextImpl.mPackageInfo.get(appContext);
327+
322328
mirror.android.app.ActivityThread.AppBindData.info.set(boundApp, data.info);
323329
VMRuntime.setTargetSdkVersion.call(VMRuntime.getRuntime.call(), data.appInfo.targetSdkVersion);
324330

@@ -336,23 +342,37 @@ private void bindApplicationNoCheck(String packageName, String processName, Cond
336342
boolean enableXposed = VirtualCore.get().isXposedEnabled();
337343
if (enableXposed) {
338344
VLog.i(TAG, "Xposed is enabled.");
339-
ClassLoader originClassLoader = context.getClassLoader();
340-
ExposedBridge.initOnce(context, data.appInfo, originClassLoader);
341-
List<InstalledAppInfo> modules = VirtualCore.get().getInstalledApps(0);
342-
for (InstalledAppInfo module : modules) {
343-
ExposedBridge.loadModule(module.apkPath, module.getOdexFile().getParent(), module.libPath,
344-
data.appInfo, originClassLoader);
345+
346+
// 内部报错:java.lang.ClassNotFoundException: Didn't find class "androidx.core.app.CoreComponentFactory" on path: DexPathList[[zip file "/data/user/0/io.va.exposed64/virtual/data/app/com.laolaiwangtech/base.apk"],nativeLibraryDirectories=[/data/user/0/io.va.exposed64/virtual/data/app/com.laolaiwangtech/lib, /data/user/0/io.va.exposed64/virtual/data/app/com.laolaiwangtech/base.apk!/lib/arm64-v8a, /system/lib64, /product_h/lib64, /system_ext/lib64]]
347+
348+
ClassLoader originClassLoader = null;
349+
try {
350+
originClassLoader = appContext.getClassLoader();
351+
} catch (Exception e) {
352+
VLog.w(TAG, "appContext.getClassLoader() error", e);
353+
}
354+
if (originClassLoader !=null) {
355+
ExposedBridge.initOnce(appContext, data.appInfo, originClassLoader);
356+
357+
List<InstalledAppInfo> modules = VirtualCore.get().getInstalledApps(0);
358+
for (InstalledAppInfo module : modules) {
359+
ExposedBridge.loadModule(module.apkPath, module.getOdexFile().getParent(), module.libPath,
360+
data.appInfo, originClassLoader);
361+
}
345362
}
346363
} else {
347364
VLog.w(TAG, "Xposed is disable..");
348365
}
349366

367+
368+
350369
ClassLoader cl = LoadedApk.getClassLoader.call(data.info);
351370
if (BuildCompat.isS()) {
352371
ClassLoader parent = cl.getParent();
353372
Reflect.on(cl).set("parent", new DelegateLastClassLoader("/system/framework/android.test.base.jar", parent));
354373
}
355374

375+
356376
if (Build.VERSION.SDK_INT >= 30)
357377
ApplicationConfig.setDefaultInstance.call(new Object[] { null });
358378
mInitialApplication = LoadedApk.makeApplication.call(data.info, false, null);
@@ -509,7 +529,7 @@ private void setupVirtualStorage(ApplicationInfo info, int userId) {
509529
}
510530

511531
HashSet<String> storageRoots = getMountPoints();
512-
storageRoots.add(Environment.getExternalStorageDirectory().getAbsolutePath());
532+
storageRoots.add(VEnvironment.getExternalStorageDirectory().getAbsolutePath());
513533

514534
Set<String> whiteList = new HashSet<>();
515535
whiteList.add(Environment.DIRECTORY_PODCASTS);
@@ -531,7 +551,7 @@ private void setupVirtualStorage(ApplicationInfo info, int userId) {
531551

532552
// ensure virtual storage white directory exists.
533553
for (String whiteDir : whiteList) {
534-
File originalDir = new File(Environment.getExternalStorageDirectory(), whiteDir);
554+
File originalDir = new File(VEnvironment.getExternalStorageDirectory(), whiteDir);
535555
File virtualDir = new File(vsDir, whiteDir);
536556
if (!originalDir.exists()) {
537557
continue;

VirtualApp/lib/src/main/java/com/lody/virtual/client/core/InvocationStubManager.java

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
package com.lody.virtual.client.core;
22

3+
import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
4+
import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR2;
5+
import static android.os.Build.VERSION_CODES.KITKAT;
6+
import static android.os.Build.VERSION_CODES.LOLLIPOP;
7+
import static android.os.Build.VERSION_CODES.LOLLIPOP_MR1;
8+
import static android.os.Build.VERSION_CODES.M;
9+
import static android.os.Build.VERSION_CODES.N;
10+
311
import android.os.Build;
412

513
import com.lody.virtual.client.hook.base.MethodInvocationProxy;
@@ -62,14 +70,6 @@
6270
import java.util.HashMap;
6371
import java.util.Map;
6472

65-
import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
66-
import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR2;
67-
import static android.os.Build.VERSION_CODES.KITKAT;
68-
import static android.os.Build.VERSION_CODES.LOLLIPOP;
69-
import static android.os.Build.VERSION_CODES.LOLLIPOP_MR1;
70-
import static android.os.Build.VERSION_CODES.M;
71-
import static android.os.Build.VERSION_CODES.N;
72-
7373
/**
7474
* @author Lody
7575
*
@@ -111,6 +111,7 @@ public void init() throws Throwable {
111111
injectInternal();
112112
sInit = true;
113113

114+
114115
}
115116

116117
private void injectInternal() throws Throwable {
@@ -192,9 +193,12 @@ private void injectInternal() throws Throwable {
192193

193194
addInjector(new BatteryStatsStub());
194195
}
195-
if (BuildCompat.isOreo()) {
196-
addInjector(new AutoFillManagerStub());
197-
}
196+
197+
// After Android 13, this will throw java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.ContentResolver android.app.Application.getContentResolver()' on a null object reference
198+
// move in application onCreate
199+
// if (BuildCompat.isOreo()) {
200+
// addInjector(new AutoFillManagerStub());
201+
// }
198202
if (BuildCompat.isQ()) {
199203
addInjector(new ActivityTaskManagerStub());
200204

VirtualApp/lib/src/main/java/com/lody/virtual/client/env/SpecialComponentList.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import android.os.Build;
88

99
import java.util.ArrayList;
10+
import java.util.Collection;
1011
import java.util.HashMap;
1112
import java.util.HashSet;
1213
import java.util.List;
@@ -124,9 +125,18 @@ public static void addBlackAction(String action) {
124125
ACTION_BLACK_LIST.add(action);
125126
}
126127

128+
private static List<String> toList(Object actionsObj) {
129+
List<String> actions = new ArrayList<>();
130+
if (actionsObj instanceof Collection) {
131+
actions.addAll((Collection<String>) actionsObj);
132+
}
133+
return actions;
134+
}
135+
127136
public static void protectIntentFilter(IntentFilter filter) {
128137
if (filter != null) {
129-
List<String> actions = mirror.android.content.IntentFilter.mActions.get(filter);
138+
// 13以后这里返回的是set, 做个兼容
139+
List<String> actions = toList(mirror.android.content.IntentFilter.mActions.get(filter));
130140
ListIterator<String> iterator = actions.listIterator();
131141
while (iterator.hasNext()) {
132142
String action = iterator.next();

0 commit comments

Comments
 (0)