Search in sources :

Example 6 with BundleImpl

use of android.taobao.atlas.framework.BundleImpl in project atlas by alibaba.

the class InstrumentationHook method HandleResourceNotFound.

private void HandleResourceNotFound(Activity activity, Bundle icicle, Exception e) {
    if (activity != null && !ErrorActivityRecords.contains(activity.getClass().getName())) {
        //fix #8224429
        ErrorActivityRecords.add(activity.getClass().getName());
        try {
            activity.finish();
        } catch (Throwable e2) {
        }
        return;
    }
    String exceptionString = null;
    try {
        Resources resource = null;
        if (AtlasHacks.ContextThemeWrapper_mResources != null) {
            resource = AtlasHacks.ContextThemeWrapper_mResources.get(activity);
        } else {
            resource = activity.getResources();
        }
        List<String> paths = getAssetPathFromResources(resource);
        List<String> pathsRuntime = getAssetPathFromResources(RuntimeVariables.delegateResources);
        String pathsOfHis = DelegateResources.getCurrentAssetpathStr(resource.getAssets());
        String bundleName = AtlasBundleInfoManager.instance().getBundleForComponet(activity.getLocalClassName());
        BundleImpl b = (BundleImpl) Framework.getBundle(bundleName);
        exceptionString += "Paths: " + paths;
        if (b != null) {
            String bundlePath = b.getArchive().getArchiveFile().getAbsolutePath();
            if (!paths.contains(bundlePath)) {
                exceptionString += "(2.1) Activity Resources path not contains:" + b.getArchive().getArchiveFile().getAbsolutePath();
            }
            if (!pathsRuntime.contains(bundlePath)) {
                exceptionString += "(2.2) Activity Resources path not contains:" + b.getArchive().getArchiveFile().getAbsolutePath();
            }
            if (!pathsOfHis.contains(bundlePath)) {
                exceptionString += "(2.3) paths in history not contains:" + b.getArchive().getArchiveFile().getAbsolutePath();
            }
            if (b.getArchive().getArchiveFile().exists() == false) {
                exceptionString += "(2.4) Bundle archive file not exist:" + b.getArchive().getArchiveFile().getAbsolutePath();
            }
            if (FileUtils.CheckFileValidation(b.getArchive().getArchiveFile().getAbsolutePath())) {
                exceptionString += "(2.5) Bundle archive file can not opened with stream:" + b.getArchive().getArchiveFile().getAbsolutePath();
            }
        }
        if (resource == RuntimeVariables.delegateResources) {
            exceptionString += "(2.6) DelegateResources equals Activity Resources";
        }
        exceptionString += "(2.7) Activity Resources paths length:" + paths.size();
        AtlasMonitor.getInstance().trace(AtlasMonitor.BUNDLE_INSTALL_FAIL, bundleName, AtlasMonitor.GET_RESOURCES_FAIL_MSG, FileUtils.getDataAvailableSpace());
    } catch (Exception e1) {
        String pathsInRunTime = " " + DelegateResources.getCurrentAssetpathStr(RuntimeVariables.androidApplication.getAssets());
        exceptionString = "(2.8) paths in history:" + pathsInRunTime + " getAssetPath fail: " + e1;
    }
    throw new RuntimeException(exceptionString, e);
}
Also used : BundleImpl(android.taobao.atlas.framework.BundleImpl) Resources(android.content.res.Resources)

Example 7 with BundleImpl

use of android.taobao.atlas.framework.BundleImpl in project atlas by alibaba.

the class InstrumentationHook method execStartActivityInternal.

private ActivityResult execStartActivityInternal(final Context context, final Intent intent, final int requestCode, ExecStartActivityCallback callback) {
    //intent.putExtra("atlas_wrapper",true);
    /**
         * bundle update后可能需要预处理
         */
    Log.e("InsturmentationHook", "patch execStartActivity start");
    if (BundlePackageManager.isNeedCheck(intent)) {
        List<org.osgi.framework.Bundle> bundles = Atlas.getInstance().getBundles();
        for (org.osgi.framework.Bundle bundle : bundles) {
            if (((BundleImpl) bundle).isUpdated()) {
                BundlePackageManager packageManager = ((BundleImpl) bundle).getPackageManager();
                if (null != packageManager && packageManager.wrapperActivityIntentIfNeed(intent) != null) {
                    break;
                }
            }
        }
    }
    if (intent != null) {
        Atlas.getInstance().checkDownGradeToH5(intent);
    }
    // Get package name and component name
    String packageName = null;
    String componentName = null;
    if (intent.getComponent() != null) {
        packageName = intent.getComponent().getPackageName();
        componentName = intent.getComponent().getClassName();
    } else {
        ResolveInfo resolveInfo = context.getPackageManager().resolveActivity(intent, 0);
        if (resolveInfo != null && resolveInfo.activityInfo != null) {
            packageName = resolveInfo.activityInfo.packageName;
            componentName = resolveInfo.activityInfo.name;
        }
    }
    if (componentName == null) {
        ActivityResult result = null;
        try {
            // Just invoke callback since component is null
            result = callback.execStartActivity();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
    // Taobao may start a component not exist in com.taobao.taobao package.
    if (!StringUtils.equals(context.getPackageName(), packageName)) {
        if (sOnIntentRedirectListener != null) {
            Activity sourceActivity = ActivityTaskMgr.getInstance().peekTopActivity();
            if (!sOnIntentRedirectListener.onExternalRedirect(intent, packageName, componentName, sourceActivity)) {
                Log.e("InstrumentationHook", "fiter app" + packageName);
                return null;
            }
        }
        return callback.execStartActivity();
    }
    String bundleName = AtlasBundleInfoManager.instance().getBundleForComponet(componentName);
    if (!TextUtils.isEmpty(bundleName)) {
        BundleImpl impl = (BundleImpl) Atlas.getInstance().getBundle(bundleName);
        if (impl != null && impl.checkValidate()) {
            return callback.execStartActivity();
        } else {
            if (ActivityTaskMgr.getInstance().peekTopActivity() != null && Looper.getMainLooper().getThread().getId() == Thread.currentThread().getId()) {
                final String component = componentName;
                asyncStartActivity(context, bundleName, intent, requestCode, component, callback);
            } else {
                callback.execStartActivity();
                Log.e("InsturmentationHook", "patch execStartActivity finish");
            }
        }
        return null;
    }
    // Try to get class from system Classloader
    try {
        Class<?> clazz = null;
        clazz = Framework.getSystemClassLoader().loadClass(componentName);
        if (clazz != null) {
            return callback.execStartActivity();
        }
    } catch (ClassNotFoundException e) {
        fallBackToClassNotFoundCallback(context, intent, componentName);
    }
    return null;
}
Also used : BundleImpl(android.taobao.atlas.framework.BundleImpl) Bundle(android.os.Bundle) BundlePackageManager(android.taobao.atlas.runtime.newcomponent.BundlePackageManager) Activity(android.app.Activity) ResolveInfo(android.content.pm.ResolveInfo)

Example 8 with BundleImpl

use of android.taobao.atlas.framework.BundleImpl in project atlas by alibaba.

the class BundlePackageManager method queryIntentService.

/**
     * 新增service中进行优先filter
     * @param intent
     * @param resolvedType
     * @param flags
     * @param userId
     * @return
     */
public static List<ResolveInfo> queryIntentService(Intent intent, String resolvedType, int flags, int userId) {
    List<Bundle> bundles = Atlas.getInstance().getBundles();
    for (Bundle bundle : bundles) {
        BundleImpl impl = (BundleImpl) bundle;
        if (impl.isUpdated() && impl.getPackageManager() != null) {
            ResolveInfo info = impl.getPackageManager().wrapperServiceIntentIfNeed(intent);
            if (info != null) {
                List<ResolveInfo> rf = new ArrayList<ResolveInfo>(1);
                rf.add(info);
                return rf;
            }
        }
    }
    return null;
}
Also used : ResolveInfo(android.content.pm.ResolveInfo) BundleImpl(android.taobao.atlas.framework.BundleImpl) Bundle(org.osgi.framework.Bundle) ArrayList(java.util.ArrayList)

Example 9 with BundleImpl

use of android.taobao.atlas.framework.BundleImpl in project atlas by alibaba.

the class BundlePackageManager method wrapperServiceIntentIfNeed.

/**
     * Service 和 Activity支持动态部署的逻辑存在不同:
     * 动态部署新增的Activity是通过外壳欺骗PackageManagerService,并运用其创建的Binder生成完整的Activity
     * 动态部署新增的Service不同于正常使用的service,目前只支持LocalAIDLService,只是通过代理查找到Service的resolveInfo,并直接通过
     * Class创建Object,然后进程内管理其生命周期,并未通过IPC和PackageManagerService进行通信,不同于android原生的Service
     */
public ResolveInfo wrapperServiceIntentIfNeed(Intent intent) {
    if (intent == null) {
        return null;
    }
    intent.putExtra("atlas_checked", true);
    if (mExternalServices != null) {
        ComponentName comp = intent.getComponent();
        if (comp == null) {
            if (intent.getSelector() != null) {
                intent = intent.getSelector();
                comp = intent.getComponent();
            }
        }
        if (comp != null && null == AtlasBundleInfoManager.instance().getBundleForComponet(comp.getClassName())) {
            Object serviceObj = mExternalServices.mComponents.get(comp);
            if (serviceObj != null) {
                try {
                    final ResolveInfo ri = new ResolveInfo();
                    ri.serviceInfo = (ServiceInfo) serviceObj.getClass().getField("info").get(serviceObj);
                    BundleImpl impl = (BundleImpl) Atlas.getInstance().getBundle(bundleName);
                    if (!impl.getArchive().isDexOpted()) {
                        impl.getArchive().optDexFile();
                    }
                    return ri;
                } catch (Exception e) {
                    return null;
                }
            } else {
                return null;
            }
        } else {
            // 先检测包名
            if (!TextUtils.isEmpty(intent.getPackage()) && !TextUtils.equals(intent.getPackage(), RuntimeVariables.androidApplication.getPackageName())) {
                return null;
            }
            List<ResolveInfo> serviceList = mExternalServices.queryIntent(intent, intent.resolveTypeIfNeeded(RuntimeVariables.androidApplication.getContentResolver()), false);
            if (serviceList != null && serviceList.size() > 0) {
                BundleImpl impl = (BundleImpl) Atlas.getInstance().getBundle(bundleName);
                if (!impl.getArchive().isDexOpted()) {
                    impl.getArchive().optDexFile();
                }
                return serviceList.get(0);
            } else {
                return null;
            }
        }
    } else {
        return null;
    }
}
Also used : ResolveInfo(android.content.pm.ResolveInfo) BundleImpl(android.taobao.atlas.framework.BundleImpl) ComponentName(android.content.ComponentName) InvocationTargetException(java.lang.reflect.InvocationTargetException)

Example 10 with BundleImpl

use of android.taobao.atlas.framework.BundleImpl in project atlas by alibaba.

the class BundlePackageManager method processActivityIntentIfNeed.

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里面的bundle内容,否则会触发反序列化操作,bundle内的serialable对象无法找到
        Intent intent = (Intent) intent_Field.get(activityclientrecord);
        android.os.Bundle targetBundle = sTargetBundleStorage.poll();
        if (intent.getComponent() != null && intent.getComponent().getClassName().equals(AtlasFakeActivity.class.getName())) {
            Field activityInfo_Field = ActivityClientRecord_Class.getDeclaredField("activityInfo");
            activityInfo_Field.setAccessible(true);
            String dataString = targetBundle.getString("atlas_rawData");
            if (!TextUtils.isEmpty(dataString)) {
                intent.setData(Uri.parse(dataString != null ? dataString : null));
            }
            intent.setClassName(RuntimeVariables.androidApplication.getPackageName(), targetBundle.getString("atlas_rawComponent"));
            BundleImpl bundle = (BundleImpl) Atlas.getInstance().getBundle(targetBundle.getString("atlas_activity_location"));
            Object activity = bundle.getPackageManager().mExternalActivity.mComponents.get(intent.getComponent());
            Object activityInfo = Class.forName("android.content.pm.PackageParser$Activity").getField("info").get(activity);
            activityInfo_Field.set(activityclientrecord, activityInfo);
        }
    } catch (Throwable e) {
        e.printStackTrace();
    }
}
Also used : Field(java.lang.reflect.Field) BundleImpl(android.taobao.atlas.framework.BundleImpl) Intent(android.content.Intent)

Aggregations

BundleImpl (android.taobao.atlas.framework.BundleImpl)21 ResolveInfo (android.content.pm.ResolveInfo)5 Bundle (org.osgi.framework.Bundle)5 ArrayList (java.util.ArrayList)4 ComponentName (android.content.ComponentName)3 Resources (android.content.res.Resources)3 BundleClassLoader (android.taobao.atlas.framework.BundleClassLoader)3 Field (java.lang.reflect.Field)3 InvocationTargetException (java.lang.reflect.InvocationTargetException)3 Intent (android.content.Intent)2 Activity (android.app.Activity)1 Application (android.app.Application)1 BroadcastReceiver (android.content.BroadcastReceiver)1 ComponentCallbacks (android.content.ComponentCallbacks)1 ActivityInfo (android.content.pm.ActivityInfo)1 ApplicationInfo (android.content.pm.ApplicationInfo)1 ServiceInfo (android.content.pm.ServiceInfo)1 AssetManager (android.content.res.AssetManager)1 Configuration (android.content.res.Configuration)1 XmlResourceParser (android.content.res.XmlResourceParser)1