Opt out Android Permission

How to selectively accept permission list required by the applicaiton for user?

  1. Android Security architecture overview.
  2. Pros and cons analysis.

On Google groups for Android AOSP, there is a issue requesting for the feature. The major concern from Android Product team is the complexity of writing applicaitons. Bullshit.

Reference:

  1. Issue 3778: Feature request: Application permissions should be individually grantable by the user

Code Analysis

/dev/android/source/frameworks base/core/java/android/app/ApplicationPackageManager.java


    @Override
    public int[] getPackageGids(String packageName)
            throws NameNotFoundException {  
        try {
            int[] gids = mPM.getPackageGids(packageName);
            if (gids == null || gids.length > 0) {
                return gids;
            }
        } catch (RemoteException e) {   
            throw new RuntimeException("Package manager has died", e);
        }

        throw new NameNotFoundException(packageName);
    }

    ApplicationPackageManager(ContextImpl context,
                              IPackageManager pm) {
        mContext = context;
        mPM = pm;
    }

source/frameworks/base/core/java android/app/ContextImpl.java


    @Override
    public PackageManager getPackageManager() {
        if (mPackageManager != null) {  
            return mPackageManager;         
        }

        IPackageManager pm = ActivityThread.getPackageManager();
        if (pm != null) {
            // Doesn't matter if we make more than one instance.
            return (mPackageManager = new ApplicationPackageManager(this, pm));
        }

        return null;
    }

services/java/com/android/server/pm/PackageManagerService.java

   public int[] getPackageGids(String packageName) {
        final boolean enforcedDefault = isPermissionEnforcedDefault(READ_EXTERNAL_STORAGE);
        // reader              
        synchronized (mPackages) {      
            PackageParser.Package p = mPackages.get(packageName); 
            if (DEBUG_PACKAGE_INFO)         
                Log.v(TAG, "getPackageGids" + packageName + ": " + p);
            if (p != null) {   
                final PackageSetting ps = (PackageSetting)p.mExtras; 
                final SharedUserSetting suid = ps.sharedUser;
                int[] gids = suid != null ? suid.gids : ps.gids;

                // include GIDs for any unenforced permissions
                if (!isPermissionEnforcedLocked(READ_EXTERNAL_STORAGE, enforcedDefault)) {
                    final BasePermission basePerm = mSettings.mPermissions.get(
                            READ_EXTERNAL_STORAGE);         
                    gids = appendInts(gids, basePerm.gids);
                }              

                return gids;   
            }                  
        }
        // stupid thing to indicate an error.
        return new int[0];     
    }

android.content.pm.PackageParser

365  public Package parsePackage(File sourceFile, String destCodePath,
366 DisplayMetrics metrics, int flags) {
367 = .;
369 = sourceFile.getPath();
370 if (!sourceFile.isFile()) {
371 Log.w(, "Skipping dir: " + );
372 = .;
373 return null;
374 }
375 if (!isPackageFilename(sourceFile.getName())
376 && (flags&) != 0) {
377 if ((flags&) == 0) {
378 // We expect to have non-.apk files in the system dir,
379 // so don't warn about them.
380 Log.w(, "Skipping non-package file: " + );
381 }
382 = .;
383 return null;
384 }
386 if ((flags&) != 0 && .) Log.d(
387 , "Scanning package: " + );
389 XmlResourceParser parser = null;
390 AssetManager assmgr = null;
391 boolean assetError = true;
392 try {
393 assmgr = new AssetManager();
394 int cookie = assmgr.addAssetPath();
395 if(cookie != 0) {
396 parser = assmgr.openXmlResourceParser(cookie, "AndroidManifest.xml");
397 assetError = false;
398 } else {
399 Log.w(, "Failed adding asset path:"+);
400 }