package org.acra.util; import static org.acra.ACRA.LOG_TAG; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import org.acra.ACRA; /** * Responsible for wrapping calls to PackageManager to ensure that they always complete without throwing RuntimeExceptions. * <p> * Depending upon the state of the application it is possible that * <ul> * <li>Context has no PackageManager.</li> * <li>PackageManager returned by Context throws RuntimeException("Package manager has died") * because it cannot contact the remote PackageManager service. * </li> * </ul> * I suspect that PackageManager death is caused during app installation. * But we need to make ACRA bullet proof, so it's better to handle the condition safely so that the error report itself doesn't fail. * </p> * @author William Ferguson * @since 4.3.0 */ public final class PackageManagerWrapper { private final Context context; public PackageManagerWrapper(Context context) { this.context = context; } /** * @param permission Manifest.permission to check whether it has been granted. * @return true if the permission has been granted to the app, false if it hasn't been granted or the PackageManager could not be contacted. */ public boolean hasPermission(String permission) { final PackageManager pm = context.getPackageManager(); if (pm == null) { return false; } try { return pm.checkPermission(permission, context.getPackageName()) == PackageManager.PERMISSION_GRANTED; } catch (RuntimeException e) { // To catch RuntimeException("Package manager has died") that can occur on some version of Android, // when the remote PackageManager is unavailable. I suspect this sometimes occurs when the App is being reinstalled. return false; } } /** * @return PackageInfo for the current application or null if the PackageManager could not be contacted. */ public PackageInfo getPackageInfo() { final PackageManager pm = context.getPackageManager(); if (pm == null) { return null; } try { return pm.getPackageInfo(context.getPackageName(), 0); } catch (PackageManager.NameNotFoundException e) { ACRA.log.v(LOG_TAG, "Failed to find PackageInfo for current App : " + context.getPackageName()); return null; } catch (RuntimeException e) { // To catch RuntimeException("Package manager has died") that can occur on some version of Android, // when the remote PackageManager is unavailable. I suspect this sometimes occurs when the App is being reinstalled. return null; } } }