package com.lody.virtual.client.hook.patchs.am; import android.content.ComponentName; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.res.Resources; import android.content.res.TypedArray; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.util.TypedValue; import com.lody.virtual.IOHook; import com.lody.virtual.client.core.VirtualCore; import com.lody.virtual.client.env.Constants; import com.lody.virtual.client.hook.base.Hook; import com.lody.virtual.client.ipc.ActivityClientRecord; import com.lody.virtual.client.ipc.VActivityManager; import com.lody.virtual.client.stub.ChooserActivity; import com.lody.virtual.helper.utils.ArrayUtils; import com.lody.virtual.helper.utils.ComponentUtils; import com.lody.virtual.os.VUserHandle; import com.lody.virtual.server.interfaces.IAppRequestListener; import java.io.File; import java.lang.reflect.Method; /** * @author Lody */ /* package */ class StartActivity extends Hook { private static final String SCHEME_FILE = "file"; private static final String SCHEME_PACKAGE = "package"; @Override public String getName() { return "startActivity"; } @Override public Object call(Object who, Method method, Object... args) throws Throwable { int intentIndex = ArrayUtils.indexOfFirst(args, Intent.class); int resultToIndex = ArrayUtils.indexOfObject(args, IBinder.class, 2); String resolvedType = (String) args[intentIndex + 1]; Intent intent = (Intent) args[intentIndex]; intent.setDataAndType(intent.getData(), resolvedType); IBinder resultTo = resultToIndex >= 0 ? (IBinder) args[resultToIndex] : null; int userId = VUserHandle.myUserId(); if (ComponentUtils.isStubComponent(intent)) { return method.invoke(who, args); } if (Intent.ACTION_INSTALL_PACKAGE.equals(intent.getAction()) || (Intent.ACTION_VIEW.equals(intent.getAction()) && "application/vnd.android.package-archive".equals(intent.getType()))) { if (handleInstallRequest(intent)) { return 0; } } else if ((Intent.ACTION_UNINSTALL_PACKAGE.equals(intent.getAction()) || Intent.ACTION_DELETE.equals(intent.getAction())) && "package".equals(intent.getScheme())) { if (handleUninstallRequest(intent)) { return 0; } } String resultWho = null; int requestCode = 0; Bundle options = ArrayUtils.getFirst(args, Bundle.class); if (resultTo != null) { resultWho = (String) args[resultToIndex + 1]; requestCode = (int) args[resultToIndex + 2]; } // chooser if (ChooserActivity.check(intent)) { intent.setComponent(new ComponentName(getHostContext(), ChooserActivity.class)); intent.putExtra(Constants.EXTRA_USER_HANDLE, userId); intent.putExtra(ChooserActivity.EXTRA_DATA, options); intent.putExtra(ChooserActivity.EXTRA_WHO, resultWho); intent.putExtra(ChooserActivity.EXTRA_REQUEST_CODE, requestCode); return method.invoke(who, args); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { args[intentIndex - 1] = getHostPkg(); } ActivityInfo activityInfo = VirtualCore.get().resolveActivityInfo(intent, userId); if (activityInfo == null) { return method.invoke(who, args); } int res = VActivityManager.get().startActivity(intent, activityInfo, resultTo, options, resultWho, requestCode, VUserHandle.myUserId()); if (res != 0 && resultTo != null && requestCode > 0) { VActivityManager.get().sendActivityResult(resultTo, resultWho, requestCode); } if (resultTo != null) { ActivityClientRecord r = VActivityManager.get().getActivityRecord(resultTo); if (r != null && r.activity != null) { try { TypedValue out = new TypedValue(); Resources.Theme theme = r.activity.getResources().newTheme(); theme.applyStyle(activityInfo.getThemeResource(), true); if (theme.resolveAttribute(android.R.attr.windowAnimationStyle, out, true)) { TypedArray array = theme.obtainStyledAttributes(out.data, new int[]{ android.R.attr.activityOpenEnterAnimation, android.R.attr.activityOpenExitAnimation }); r.activity.overridePendingTransition(array.getResourceId(0, 0), array.getResourceId(1, 0)); array.recycle(); } } catch (Throwable e) { // Ignore } } } return res; } private boolean handleInstallRequest(Intent intent) { IAppRequestListener listener = VirtualCore.get().getAppRequestListener(); if (listener != null) { Uri packageUri = intent.getData(); if (SCHEME_FILE.equals(packageUri.getScheme())) { File sourceFile = new File(packageUri.getPath()); try { listener.onRequestInstall(IOHook.getRedirectedPath(sourceFile.getPath())); return true; } catch (RemoteException e) { e.printStackTrace(); } } } return false; } private boolean handleUninstallRequest(Intent intent) { IAppRequestListener listener = VirtualCore.get().getAppRequestListener(); if (listener != null) { Uri packageUri = intent.getData(); if (SCHEME_PACKAGE.equals(packageUri.getScheme())) { String pkg = packageUri.getSchemeSpecificPart(); try { listener.onRequestUninstall(pkg); return true; } catch (RemoteException e) { e.printStackTrace(); } } } return false; } }