public static ImageUploaderInterface getInstance(
     final Application application, final String uploader_name) {
   if (uploader_name == null) return null;
   final Intent intent = new Intent(INTENT_ACTION_EXTENSION_UPLOAD_IMAGE);
   final ComponentName component = ComponentName.unflattenFromString(uploader_name);
   intent.setComponent(component);
   if (application.getPackageManager().queryIntentServices(intent, 0).size() != 1) return null;
   return new ImageUploaderInterface(application, uploader_name);
 }
Пример #2
0
 @Override
 public String getFullVersionName() {
   try {
     final PackageInfo info =
         myApplication.getPackageManager().getPackageInfo(myApplication.getPackageName(), 0);
     return info.versionName + " (" + info.versionCode + ")";
   } catch (Exception e) {
     return "";
   }
 }
Пример #3
0
 public static String getAppVersionName(Application application) {
   try {
     PackageManager pm = application.getPackageManager();
     if (pm != null) {
       PackageInfo pi = pm.getPackageInfo(application.getPackageName(), 0);
       String versionName = pi.versionName;
       if (versionName != null && versionName.length() > 0) {
         return versionName;
       }
     }
   } catch (PackageManager.NameNotFoundException e) {
   }
   return "";
 }
  @Before
  public void setUp() throws PackageManager.NameNotFoundException {
    initMocks(this);
    mockStatic(MoEHelper.class);
    when(analytics.getApplication()).thenReturn(context);

    when(context.getPackageManager()).thenReturn(manager);
    when(activity.getPackageManager()).thenReturn(manager);
    when(manager.getApplicationInfo(context.getPackageName(), 0)).thenReturn(applicationInfo);
    when(context.getApplicationContext()).thenReturn(RuntimeEnvironment.application);

    integration =
        new MoEngageIntegration(
            analytics,
            new ValueMap().putValue("pushSenderId", "12324441").putValue("apiKey", "ASJKSLJAL"));
    integration.helper = moeHelper;
  }
Пример #5
0
    @Inject
    public BaseConfig(Application context) {
      try {
        packageName = context.getPackageName();
        final int flags = context.getPackageManager().getApplicationInfo(packageName, 0).flags;
        minimumLogLevel = (flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0 ? Log.VERBOSE : Log.INFO;
        scope = packageName.toUpperCase();

        Ln.d("Configuring Logging, minimum log level is %s", logLevelToString(minimumLogLevel));

      } catch (Exception e) {
        try {
          Log.e(packageName, "Error configuring logger", e);
        } catch (RuntimeException f) {
          // HACK ignore Stub! errors in mock objects during testing
        }
      }
    }
Пример #6
0
 public static void init(Application app) {
   application = new WeakReference<Application>(app);
   TelephonyManager tm = (TelephonyManager) app.getSystemService(Context.TELEPHONY_SERVICE);
   // 获取本机ID
   deviceId = tm.getDeviceId();
   // 初始化Volley的请求队列.
   requestQueue = Volley.newRequestQueue(app);
   // 是否有相机
   hasCamera = app.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);
   APP_BASE_EXTERNAL_STORAGE_PATH =
       EXTERNAL_STORAGE_PATH
           + File.separator
           + application.get().getPackageName()
           + File.separator;
   File base = new File(APP_BASE_EXTERNAL_STORAGE_PATH);
   if (base.exists() && !base.isDirectory()) {
     base.delete();
   }
   if (!base.exists()) {
     base.mkdir();
   }
 }
  /**
   * 初始化loader, 只可调用一次
   *
   * @param app
   */
  public static synchronized void initLoader(Application app, PluginManager manager) {

    if (!isLoaderInited) {
      LogUtil.d("插件框架初始化中...");

      isLoaderInited = true;
      sApplication = app;
      pluginManager = manager;
      changeListener = new PluginCallbackImpl();

      AndroidAppIActivityManager.installProxy();
      AndroidAppINotificationManager.installProxy();
      AndroidAppIPackageManager.installProxy(sApplication.getPackageManager());
      AndroidWidgetToast.installProxy();
      // 不可在主进程中同步安装,因为此时ActivityThread还没有准备好, 会导致空指针。
      new Handler()
          .postDelayed(
              new Runnable() {
                @Override
                public void run() {
                  AndroidWebkitWebViewFactoryProvider.installProxy();
                }
              },
              50);

      PluginInjector.injectInstrumentation();
      PluginInjector.injectHandlerCallback();
      PluginInjector.injectBaseContext(sApplication);

      pluginManager.loadInstalledPlugins();
      Iterator<PluginDescriptor> itr = getPlugins().iterator();
      while (itr.hasNext()) {
        PluginDescriptor plugin = itr.next();
        LocalServiceManager.registerService(plugin);
      }
      changeListener.onPluginLoaderInited();

      if (Build.VERSION.SDK_INT >= 14) {
        sApplication.registerActivityLifecycleCallbacks(
            new Application.ActivityLifecycleCallbacks() {
              @Override
              public void onActivityCreated(Activity activity, Bundle savedInstanceState) {}

              @Override
              public void onActivityStarted(Activity activity) {}

              @Override
              public void onActivityResumed(Activity activity) {}

              @Override
              public void onActivityPaused(Activity activity) {}

              @Override
              public void onActivityStopped(Activity activity) {}

              @Override
              public void onActivitySaveInstanceState(Activity activity, Bundle outState) {}

              @Override
              public void onActivityDestroyed(Activity activity) {
                PluginStubBinding.unBindLaunchModeStubActivity(
                    activity.getClass().getName(), activity.getIntent());
              }
            });
      }
      LogUtil.d("插件框架初始化完成");
    }
  }
  /**
   * 安装一个插件
   *
   * @param srcPluginFile
   * @return
   */
  public static synchronized int installPlugin(String srcPluginFile) {
    LogUtil.e("开始安装插件", srcPluginFile);
    if (TextUtils.isEmpty(srcPluginFile) || !new File(srcPluginFile).exists()) {
      return SRC_FILE_NOT_FOUND;
    }

    // 第0步,先将apk复制到宿主程序私有目录,防止在安装过程中文件被篡改
    if (!srcPluginFile.startsWith(sApplication.getCacheDir().getAbsolutePath())) {
      String tempFilePath =
          sApplication.getCacheDir().getAbsolutePath()
              + File.separator
              + System.currentTimeMillis()
              + ".apk";
      if (FileUtil.copyFile(srcPluginFile, tempFilePath)) {
        srcPluginFile = tempFilePath;
      } else {
        LogUtil.e("复制插件文件失败", srcPluginFile, tempFilePath);
        return COPY_FILE_FAIL;
      }
    }

    // 第1步,验证插件APK签名,如果被篡改过,将获取不到证书
    // sApplication.getPackageManager().getPackageArchiveInfo(srcPluginFile,
    // PackageManager.GET_SIGNATURES);
    Signature[] pluginSignatures = PackageVerifyer.collectCertificates(srcPluginFile, false);
    boolean isDebugable =
        (0 != (sApplication.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE));
    if (pluginSignatures == null) {
      LogUtil.e("插件签名验证失败", srcPluginFile);
      new File(srcPluginFile).delete();
      return SIGNATURES_INVALIDATE;
    } else if (NEED_VERIFY_CERT && !isDebugable) {
      // 可选步骤,验证插件APK证书是否和宿主程序证书相同。
      // 证书中存放的是公钥和算法信息,而公钥和私钥是1对1的
      // 公钥相同意味着是同一个作者发布的程序
      Signature[] mainSignatures = null;
      try {
        PackageInfo pkgInfo =
            sApplication
                .getPackageManager()
                .getPackageInfo(sApplication.getPackageName(), PackageManager.GET_SIGNATURES);
        mainSignatures = pkgInfo.signatures;
      } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
      }
      if (!PackageVerifyer.isSignaturesSame(mainSignatures, pluginSignatures)) {
        LogUtil.e("插件证书和宿主证书不一致", srcPluginFile);
        new File(srcPluginFile).delete();
        return VERIFY_SIGNATURES_FAIL;
      }
    }

    // 第2步,解析Manifest,获得插件详情
    PluginDescriptor pluginDescriptor = PluginManifestParser.parseManifest(srcPluginFile);
    if (pluginDescriptor == null || TextUtils.isEmpty(pluginDescriptor.getPackageName())) {
      LogUtil.e("解析插件Manifest文件失败", srcPluginFile);
      new File(srcPluginFile).delete();
      return PARSE_MANIFEST_FAIL;
    }

    PackageInfo packageInfo =
        sApplication
            .getPackageManager()
            .getPackageArchiveInfo(srcPluginFile, PackageManager.GET_GIDS);
    if (packageInfo != null) {
      pluginDescriptor.setApplicationTheme(packageInfo.applicationInfo.theme);
      pluginDescriptor.setApplicationIcon(packageInfo.applicationInfo.icon);
      pluginDescriptor.setApplicationLogo(packageInfo.applicationInfo.logo);
    }

    boolean isNeedPending = false;
    // 第3步,检查插件是否已经存在,若存在删除旧的
    PluginDescriptor oldPluginDescriptor =
        getPluginDescriptorByPluginId(pluginDescriptor.getPackageName());
    if (oldPluginDescriptor != null) {
      LogUtil.e(
          "已安装过,安装路径为",
          oldPluginDescriptor.getInstalledPath(),
          oldPluginDescriptor.getVersion(),
          pluginDescriptor.getVersion());

      // 检查插件是否已经加载
      if (oldPluginDescriptor.getPluginContext() != null) {
        if (!oldPluginDescriptor.getVersion().equals(pluginDescriptor.getVersion())) {
          LogUtil.e("旧版插件已经加载, 且新版插件和旧版插件版本不同,进入pending状态,新版插件将在安装后进程重启再生效");
          isNeedPending = true;
        } else {
          LogUtil.e("旧版插件已经加载, 且新版插件和旧版插件版本相同,拒绝安装");
          new File(srcPluginFile).delete();
          return FAIL_BECAUSE_HAS_LOADED;
        }
      } else {
        LogUtil.e("旧版插件还未加载,忽略版本,直接删除旧版,尝试安装新版");
        remove(oldPluginDescriptor.getPackageName());
      }
    }

    // 第4步骤,复制插件到插件目录
    String destApkPath =
        pluginManager.genInstallPath(
            pluginDescriptor.getPackageName(), pluginDescriptor.getVersion());
    boolean isCopySuccess = FileUtil.copyFile(srcPluginFile, destApkPath);

    if (!isCopySuccess) {

      LogUtil.e("复制插件到安装目录失败", srcPluginFile);
      // 删掉临时文件
      new File(srcPluginFile).delete();
      return COPY_FILE_FAIL;
    } else {

      // 第5步,先解压so到临时目录,再从临时目录复制到插件so目录。 在构造插件Dexclassloader的时候,会使用这个so目录作为参数
      File apkParent = new File(destApkPath).getParentFile();
      File tempSoDir = new File(apkParent, "temp");
      Set<String> soList = FileUtil.unZipSo(srcPluginFile, tempSoDir);
      if (soList != null) {
        for (String soName : soList) {
          FileUtil.copySo(tempSoDir, soName, apkParent.getAbsolutePath());
        }
        // 删掉临时文件
        FileUtil.deleteAll(tempSoDir);
      }

      // 第6步 添加到已安装插件列表
      pluginDescriptor.setInstalledPath(destApkPath);
      boolean isInstallSuccess = false;
      if (!isNeedPending) {
        isInstallSuccess = pluginManager.addOrReplace(pluginDescriptor);
      } else {
        isInstallSuccess = pluginManager.pending(pluginDescriptor);
      }
      // 删掉临时文件
      new File(srcPluginFile).delete();

      if (!isInstallSuccess) {
        LogUtil.e("安装插件失败", srcPluginFile);

        new File(destApkPath).delete();

        return INSTALL_FAIL;
      } else {
        // 通过创建classloader来触发dexopt,但不加载
        LogUtil.d("正在进行DEXOPT...", pluginDescriptor.getInstalledPath());
        FileUtil.deleteAll(new File(apkParent, "dalvik-cache"));
        PluginCreator.createPluginClassLoader(
            pluginDescriptor.getInstalledPath(), pluginDescriptor.isStandalone(), null);
        LogUtil.d("DEXOPT完毕");

        if (!isNeedPending) {
          LocalServiceManager.registerService(pluginDescriptor);
        }

        changeListener.onPluginInstalled(
            pluginDescriptor.getPackageName(), pluginDescriptor.getVersion());
        LogUtil.e("安装插件成功," + (isNeedPending ? " 重启进程生效" : " 立即生效"), destApkPath);

        return SUCCESS;
      }
    }
  }
  /**
   * 安装一个插件
   *
   * @param srcPluginFile
   * @return
   */
  public static synchronized int installPlugin(String srcPluginFile) {
    LogUtil.d("开始安装插件", srcPluginFile);
    if (TextUtils.isEmpty(srcPluginFile) || !new File(srcPluginFile).exists()) {
      return SRC_FILE_NOT_FOUND;
    }

    // 第0步,先将apk复制到宿主程序私有目录,防止在安装过程中文件被篡改
    if (!srcPluginFile.startsWith(sApplication.getCacheDir().getAbsolutePath())) {
      String tempFilePath =
          sApplication.getCacheDir().getAbsolutePath()
              + File.separator
              + System.currentTimeMillis()
              + ".apk";
      if (FileUtil.copyFile(srcPluginFile, tempFilePath)) {
        srcPluginFile = tempFilePath;
      } else {
        LogUtil.e("复制插件文件失败失败", srcPluginFile, tempFilePath);
        return COPY_FILE_FAIL;
      }
    }

    // 第1步,验证插件APK签名,如果被篡改过,将获取不到证书
    // sApplication.getPackageManager().getPackageArchiveInfo(srcPluginFile,
    // PackageManager.GET_SIGNATURES);
    Signature[] pluginSignatures = PackageVerifyer.collectCertificates(srcPluginFile, false);
    boolean isDebugable =
        (0 != (sApplication.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE));
    if (pluginSignatures == null) {
      LogUtil.e("插件签名验证失败", srcPluginFile);
      new File(srcPluginFile).delete();
      return SIGNATURES_INVALIDATE;
    } else if (NEED_VERIFY_CERT && !isDebugable) {
      // 可选步骤,验证插件APK证书是否和宿主程序证书相同。
      // 证书中存放的是公钥和算法信息,而公钥和私钥是1对1的
      // 公钥相同意味着是同一个作者发布的程序
      Signature[] mainSignatures = null;
      try {
        PackageInfo pkgInfo =
            sApplication
                .getPackageManager()
                .getPackageInfo(sApplication.getPackageName(), PackageManager.GET_SIGNATURES);
        mainSignatures = pkgInfo.signatures;
      } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
      }
      if (!PackageVerifyer.isSignaturesSame(mainSignatures, pluginSignatures)) {
        LogUtil.e("插件证书和宿主证书不一致", srcPluginFile);
        new File(srcPluginFile).delete();
        return VERIFY_SIGNATURES_FAIL;
      }
    }

    // 第2步,解析Manifest,获得插件详情
    PluginDescriptor pluginDescriptor = ManifestParser.parseManifest(srcPluginFile);
    if (pluginDescriptor == null || TextUtils.isEmpty(pluginDescriptor.getPackageName())) {
      LogUtil.e("解析插件Manifest文件失败", srcPluginFile);
      new File(srcPluginFile).delete();
      return PARSE_MANIFEST_FAIL;
    }

    PackageInfo packageInfo =
        sApplication
            .getPackageManager()
            .getPackageArchiveInfo(srcPluginFile, PackageManager.GET_GIDS);
    pluginDescriptor.setApplicationTheme(packageInfo.applicationInfo.theme);
    pluginDescriptor.setApplicationIcon(packageInfo.applicationInfo.icon);
    pluginDescriptor.setApplicationLogo(packageInfo.applicationInfo.logo);

    // 第3步,检查插件是否已经存在,若存在删除旧的
    PluginDescriptor oldPluginDescriptor =
        getPluginDescriptorByPluginId(pluginDescriptor.getPackageName());
    if (oldPluginDescriptor != null) {
      LogUtil.e("已安装过,先删除旧版本", pluginDescriptor.getInstalledPath());
      remove(pluginDescriptor.getPackageName());
    }

    // 第4步骤,复制插件到插件目录
    String destPluginFile =
        pluginManager.genInstallPath(
            pluginDescriptor.getPackageName(), pluginDescriptor.getVersion());
    boolean isCopySuccess = FileUtil.copyFile(srcPluginFile, destPluginFile);

    if (!isCopySuccess) {

      LogUtil.d("复制插件到安装目录失败", srcPluginFile);
      new File(srcPluginFile).delete();
      return COPY_FILE_FAIL;
    } else {

      // 第5步,复制插件so到插件so目录, 在构造插件Dexclassloader的时候,会使用这个so目录作为参数
      File tempDir = new File(new File(destPluginFile).getParentFile(), "temp");
      Set<String> soList = FileUtil.unZipSo(srcPluginFile, tempDir);
      if (soList != null) {
        for (String soName : soList) {
          FileUtil.copySo(
              tempDir, soName, new File(destPluginFile).getParent() + File.separator + "lib");
        }
        FileUtil.deleteAll(tempDir);
      }

      // 第6步 添加到已安装插件列表
      pluginDescriptor.setInstalledPath(destPluginFile);
      boolean isInstallSuccess = pluginManager.addOrReplace(pluginDescriptor);

      new File(srcPluginFile).delete();

      if (!isInstallSuccess) {
        LogUtil.d("安装插件失败", srcPluginFile);
        return INSTALL_FAIL;
      } else {
        changeListener.onPluginInstalled(
            pluginDescriptor.getPackageName(), pluginDescriptor.getVersion());
        LogUtil.d("安装插件成功", destPluginFile);
        return SUCCESS;
      }
    }
  }