package android.taobao.atlas.runtime.newcomponent.activity; import android.app.Activity; import android.app.Instrumentation; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ResolveInfo; import android.taobao.atlas.runtime.ActivityTaskMgr; import android.taobao.atlas.runtime.InstrumentationHook; import android.taobao.atlas.runtime.RuntimeVariables; import android.taobao.atlas.runtime.newcomponent.AdditionalPackageManager; import android.taobao.atlas.runtime.newcomponent.BridgeUtil; import android.taobao.atlas.runtime.newcomponent.service.ServiceBridge; import android.taobao.atlas.util.StringUtils; import java.lang.ref.WeakReference; import java.lang.reflect.Field; import java.util.List; /** * Created by guanjie on 2017/4/12. */ public class ActivityBridge { public static Instrumentation.ActivityResult execStartActivity(Intent intent, final InstrumentationHook.ExecStartActivityCallback startActivityRunnable) { List<ResolveInfo> infos = AdditionalPackageManager.getInstance().queryIntentActivities(intent); if (infos != null && infos.get(0).activityInfo != null) { String delegateComponentName = BridgeUtil.getBridgeName(BridgeUtil.TYPE_ACTIVITYBRIDGE,infos.get(0).activityInfo.processName); Intent wrappIntent = wrapperOriginalIntent(intent,delegateComponentName); if(infos.get(0).activityInfo.processName.equals(RuntimeVariables.getProcessName(RuntimeVariables.androidApplication))) { handleActivityStack(infos.get(0).activityInfo,wrappIntent); return startActivityRunnable.execStartActivity(wrappIntent); }else{ ServiceBridge.handleActivityStack(wrappIntent,infos.get(0).activityInfo,new OnIntentPreparedObserver(){ @Override public void onPrepared(final Intent intent) { startActivityRunnable.execStartActivity(intent); } }); return null; } }else{ return startActivityRunnable.execStartActivity(intent); } } public static void processActivityIntentIfNeed(Object activityclientrecord) { try { Class ActivityClientRecord_Class = Class.forName("android.app.ActivityThread$ActivityClientRecord"); Field intent_Field = ActivityClientRecord_Class.getDeclaredField("intent"); intent_Field.setAccessible(true); Intent intent = (Intent) intent_Field.get(activityclientrecord); if (intent.getComponent() != null && intent.getComponent().getClassName().startsWith(String.format("%s%s",BridgeUtil.COMPONENT_PACKAGE,BridgeUtil.PROXY_PREFIX))){ Field activityInfo_Field = ActivityClientRecord_Class.getDeclaredField("activityInfo"); activityInfo_Field.setAccessible(true); Intent originalIntent = unWrapperOriginalIntent(intent); ActivityInfo info = AdditionalPackageManager.getInstance().getNewComponentInfo(originalIntent.getComponent(),ActivityInfo.class); activityInfo_Field.set(activityclientrecord, info); intent_Field.set(activityclientrecord,originalIntent); } } catch (Throwable e) { e.printStackTrace(); } } public static void handleActivityStack(ActivityInfo info, Intent intent) { // Handle launchMode with singleTop, and flag with FLAG_ACTIVITY_SINGLE_TOP int launchMode = info.launchMode; int flag = intent.getFlags(); String launchActivityName = info.name; String prevActivityName = null; List<WeakReference<Activity>> activityList = ActivityTaskMgr.getInstance().getActivityList(); if (activityList.size() > 0) { Activity lastActivity = activityList.get(activityList.size() - 1).get(); prevActivityName = lastActivity.getClass().getName(); } if (StringUtils.equals(prevActivityName, launchActivityName) && (launchMode == ActivityInfo.LAUNCH_SINGLE_TOP || (flag & Intent.FLAG_ACTIVITY_SINGLE_TOP) == Intent.FLAG_ACTIVITY_SINGLE_TOP)) { intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); } else if (launchMode == ActivityInfo.LAUNCH_SINGLE_TASK || launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || (flag & Intent.FLAG_ACTIVITY_CLEAR_TOP) == Intent.FLAG_ACTIVITY_CLEAR_TOP) { int i; boolean isExist = false; for (i = 0; i < activityList.size(); i++) { WeakReference<Activity> ref = activityList.get(i); if (ref!=null && ref.get()!=null && ref.get().getClass().getName().equals(launchActivityName)) { isExist = true; break; } } if (isExist) { for (WeakReference<Activity> act : activityList.subList(i + 1, activityList.size())) { if(act!=null && act.get()!=null) { act.get().finish(); } } activityList.subList(i + 1, activityList.size()).clear(); intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); } } } private static Intent wrapperOriginalIntent(Intent origin,String delegatActivityname){ Intent wrappIntent = new Intent(); wrappIntent.addFlags(origin.getFlags()); wrappIntent.setClassName(origin.getComponent().getPackageName(),delegatActivityname); wrappIntent.putExtra("originalIntent",origin); return wrappIntent; } private static Intent unWrapperOriginalIntent(Intent wrapper){ return wrapper.getParcelableExtra("originalIntent"); } public interface OnIntentPreparedObserver{ public void onPrepared(Intent intent); } }