Permalink
Browse files

PermissionGrant: Introduce Support for flashing Gapps

* this makes AOSP/CAF based ROMs compatible with 6.0 Gapps packages
* this resolves the problem of permissions not being granted to google core apps
* this will probably need to be updated regulary

* this resolves one aspect of opengapps/opengapps#93

Copyright (C) by Alex Naidis (alex.naidis@linux.com), Team Exodus, The Linux Foundation

Change-Id: Iee4954d0425d8040361ff0fba653c5f1583f3bf2
Signed-off-by: Alex Naidis <alex.naidis@linux.com>
1 parent c6bccad commit 9c36be651e83fb039a262682839bd920b033007a @TheCrazyLex TheCrazyLex committed Oct 31, 2015
Showing with 89 additions and 0 deletions.
  1. +89 −0 services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2015 Alex Naidis <alex.naidis@linux.com> , Team Exodus, The Linux Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -571,6 +572,92 @@ private void grantDefaultSystemHandlerPermissions(int userId) {
grantRuntimePermissionsLPw(musicPackage, STORAGE_PERMISSIONS, userId);
}
+ // Google Account
+ PackageParser.Package googleaccountPackage = getDefaultProviderAuthorityPackageLPr(
+ "com.google.android.gsf.login", userId);
+ if (googleaccountPackage != null) {
+ grantRuntimePermissionsLPw(googleaccountPackage, CONTACTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(googleaccountPackage, PHONE_PERMISSIONS, userId);
+ }
+
+ // Google App
+ PackageParser.Package googleappPackage = getDefaultProviderAuthorityPackageLPr(
+ "com.google.android.googlequicksearchbox", userId);
+ if (googleappPackage != null) {
+ grantRuntimePermissionsLPw(googleappPackage, CALENDAR_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(googleappPackage, CAMERA_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(googleappPackage, CONTACTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(googleappPackage, LOCATION_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(googleappPackage, MICROPHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(googleappPackage, PHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(googleappPackage, SMS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(googleappPackage, STORAGE_PERMISSIONS, userId);
+ }
+
+ // Google Play Services
+ PackageParser.Package gmscorePackage = getDefaultProviderAuthorityPackageLPr(
+ "com.google.android.gms", userId);
+ if (gmscorePackage != null) {
+ grantRuntimePermissionsLPw(gmscorePackage, SENSORS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(gmscorePackage, CALENDAR_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(gmscorePackage, CAMERA_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(gmscorePackage, CONTACTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(gmscorePackage, LOCATION_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(gmscorePackage, MICROPHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(gmscorePackage, PHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(gmscorePackage, SMS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(gmscorePackage, STORAGE_PERMISSIONS, userId);
+ }
+
+ // Google Connectivity Services
+ PackageParser.Package gcsPackage = getDefaultProviderAuthorityPackageLPr(
+ "com.google.android.apps.gcs", userId);
+ if (gcsPackage != null) {
+ grantRuntimePermissionsLPw(gcsPackage, CONTACTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(gcsPackage, LOCATION_PERMISSIONS, userId);
+ }
+
+ // Google Contacts Sync
+ PackageParser.Package googlecontactssyncPackage = getDefaultProviderAuthorityPackageLPr(
+ "com.google.android.syncadapters.contacts", userId);
+ if (googlecontactssyncPackage != null) {
+ grantRuntimePermissionsLPw(googlecontactssyncPackage, CONTACTS_PERMISSIONS, userId);
+ }
+
+ // Google Backup Transport
+ PackageParser.Package googlebackuptransportPackage = getDefaultProviderAuthorityPackageLPr(
+ "com.google.android.backuptransport", userId);
+ if (googlebackuptransportPackage != null) {
+ grantRuntimePermissionsLPw(googlebackuptransportPackage, CONTACTS_PERMISSIONS, userId);
+ }
+
+ // Google Play Framework
+ PackageParser.Package gsfcorePackage = getDefaultProviderAuthorityPackageLPr(
+ "com.google.android.gsf", userId);
+ if (gsfcorePackage != null) {
+ grantRuntimePermissionsLPw(gsfcorePackage, CONTACTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(gsfcorePackage, PHONE_PERMISSIONS, userId);
+ }
+
+ // Google Setup Wizard
+ PackageParser.Package setupwizardPackage = getDefaultProviderAuthorityPackageLPr(
+ "com.google.android.setupwizard", userId);
+ if (setupwizardPackage != null) {
+ grantRuntimePermissionsLPw(setupwizardPackage, CONTACTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(setupwizardPackage, PHONE_PERMISSIONS, userId);
+ }
+
+ // Google Play Store
+ PackageParser.Package vendingPackage = getDefaultProviderAuthorityPackageLPr(
+ "com.android.vending", userId);
+ if (vendingPackage != null) {
+ grantRuntimePermissionsLPw(vendingPackage, CONTACTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(vendingPackage, PHONE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(vendingPackage, LOCATION_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(vendingPackage, SMS_PERMISSIONS, userId);
+ }
+
+
mService.mSettings.onDefaultRuntimePermissionsGrantedLPr(userId);
}
}
@@ -591,7 +678,9 @@ private void grantDefaultPermissionsToDefaultSystemSmsAppLPr(
if (doesPackageSupportRuntimePermissions(smsPackage)) {
grantRuntimePermissionsLPw(smsPackage, PHONE_PERMISSIONS, userId);
grantRuntimePermissionsLPw(smsPackage, CONTACTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(smsPackage, PHONE_PERMISSIONS, userId);
grantRuntimePermissionsLPw(smsPackage, SMS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(smsPackage, STORAGE_PERMISSIONS, true, userId);
}
}

24 comments on commit 9c36be6

@abdollheid

Sorry could you tell me how could i patch this on cyanogemod 13 ?!

@AlmightyMegadeth00
Member
@abdollheid

So this version of gApps wont work on CM ?

@AlmightyMegadeth00
Member
@AlmightyMegadeth00
Member
@abdollheid

I tried a clean flash but this didnt work on CM 13 the system keep optimizing apps repeatedly , i couldn't boot up the system again until i format the system,preload,sdcard,data and cache

@abdollheid

Although i flash both rom and gApps together

@RajaMu
Member
RajaMu commented on 9c36be6 Mar 4, 2016

@abdollheid which gapps u have used is it opengapps ? if not can u try with opengapps and also if it 64bit device try 64bit gapps

@abdollheid

I have used the opengapps 6.0_arm_nano for CM 13 marshmallow, it was for samsung s3

@abdollheid

I wonder if this problem happen because of aosp os i use as you said i should patch your code ib order to boot the os?

@RajaMu
Member
RajaMu commented on 9c36be6 Mar 4, 2016

@abdollheid yes u need to patch this and do a clean flash of rom along with gapps and boot ..!
it should work !

@abdollheid

Sorry could you tell me how can i patch this code on CM ?

@beckx020

Yes. I don't know how to do this. I also have an S3 and want to install CM 13.0 and the gapps. Or can you point to instructions on doing this? Thank you

@GuiltyHands

Almighty, sorry for being a bit ignorant, but can you tell me what I need to do with this file? I understand gapps has to be installed one a clean flash (I'm actually on stock ROM for galaxy S6 but it's a chinese model that has GAPS removed).

@TheCrazyLex
Contributor

@all This patch only works at compile time, means you have to compile the ROM or make your ROM maker including this patch.

@jaredrummler

Instead of updating this everytime a new Google app adds a new permission, you should consider loading the requestedPermissions via PackageManager.

I just now found out about this issue and wrote the following code to create a script to grant GAPPs permissions they needed. The script did not resolve the problem. However, the code I wrote could be useful here. Please check it out and consider granting permissions to all package's that begin with com.google.*

Warning: I'm tired and this code shows it.

/**
 * Finds all denied permission from GAPPS and creates a script to grant permissions.
 * <p/>
 * Sadly, granting permissions (even as root user) seems to not be working.
 * http://stackoverflow.com/a/32619933/1048340
 * <p/>
 * This could still be useful info since it looks like some ROMs are attempting to grant GAPPS permissions in
 * DefaultPermissionGrantPolicy.java
 * <p/>
 * https://github.com/TeamExodus/frameworks_base/commit/9c36be651e83fb039a262682839bd920b033007a
 * <p/>
 * Run this method in a worker thread.
 *
 * @param context
 *     application context
 */
static void attemptFixGappsProblem(Context context) {

  // We will be attempting to write a script to grant permissions to GAPPS.
  StringBuilder script = new StringBuilder("#!/system/bin/sh\n\n");

  PackageManager pm = context.getPackageManager();

  // get all installed apps with info about what permissions they requested.
  List<PackageInfo> packageInfos = pm.getInstalledPackages(PackageManager.GET_PERMISSIONS);

  // Get the hidden method PermissionInfo#protectionToString(int) so we can log info about the requested permission
  Method protectionToString;
  try {
    protectionToString = PermissionInfo.class.getDeclaredMethod("protectionToString", int.class);
    if (!protectionToString.isAccessible()) protectionToString.setAccessible(true);
  } catch (NoSuchMethodException e) {
    throw new RuntimeException(e);
  }

  // loop through all installed apps
  for (PackageInfo packageInfo : packageInfos) {

    String packageName = packageInfo.packageName;
    String appName = null;

    // we are only interested in Gapps or System packages
    if (!packageName.startsWith("com.google.") && !packageName.startsWith("com.android.")) {
      continue;
    }

    if (packageInfo.requestedPermissions == null) {
      // No permissions are requested in the AndroidManifest
      continue;
    }

    // loop through all requested permissions in the AndroidManifest
    for (String permission : packageInfo.requestedPermissions) {

      PermissionInfo permissionInfo;
      try {
        permissionInfo = pm.getPermissionInfo(permission, 0);
      } catch (PackageManager.NameNotFoundException e) {
        Log.i("PERMS", String.format("unknown permission '%s' found in '%s'", permission, packageName));
        continue;
      }

      // convert the protectionLevel to a string (not necessary, but useful info)
      String protLevel = null;
      try {
        protLevel = (String) protectionToString.invoke(null, permissionInfo.protectionLevel);
      } catch (Exception ignored) {
        protLevel = "????";
      }

      // Create the package's context to check if the package has the requested permission
      Context packageContext;
      try {
        packageContext = context.createPackageContext(packageName, 0);
      } catch (PackageManager.NameNotFoundException wtf) {
        continue;
      }

      int ret = packageContext.checkCallingPermission(permission);
      if (ret == PackageManager.PERMISSION_DENIED) {
        if (appName == null) {
          appName = packageInfo.applicationInfo.loadLabel(pm).toString();

          script.append("################################").append("\n");
          script.append("# ").append(appName).append(" [").append(packageName).append("]\n#\n");
        }

        // log info about the denied permission
        Log.i("PERMS", String.format("%s [%s] is denied permission %s (%s)",
            appName, packageName, permission, protLevel));

        script.append("pm grant ").append(packageName).append(" ").append(permission);
        script.append(" # ").append(protLevel).append("\n");
      } else {
        Log.i("PERMS", String.format("%s [%s] has granted permission %s (%s)",
            appName, packageName, permission, protLevel));
      }

    }

  }

  // We got all denied permissions to GAPPS, lets create our script.
  // It will be located in /data/data/[packagename]/files/grant_perms.sh
  File scriptFile = new File(context.getFilesDir(), "grant_perms.sh");
  Log.i("PERMS", "Creating script file...");
  try {
    FileWriter writer = new FileWriter(scriptFile);
    writer.write(script.toString());
    writer.close();
  } catch (IOException e) {
    Log.e("PERMS", "Error creating script file", e);
  }

}

Also, see http://stackoverflow.com/questions/37164716/is-it-possible-to-check-if-another-app-has-been-granted-a-permission-on-android

@jomo
jomo commented on 9c36be6 Aug 28, 2016 edited

I converted this patch to a bash script and was able to fix OpenGApps on CyanogenMod 13 without the need to patch anything. Hope it helps some of you!

@TheCrazyLex
Contributor

That's actually awesome @jomo !
Thank you!

Maybe @mfonville can integrate it?

@mfonville

@jomo @TheCrazyLex I had some alike code ready in a branch (see opengapps/opengapps@6fd25d0 ) but trying to do it from the recovery as file-manipulation, because in recovery we don't have this grantPerm available. And putting a script to automatically execute some commands are not available on all ROMs and partly dependent on init.d or superuser support.
Unfortunately I was not able yet to reach the goal with the file manipulation yet :-/

@TheCrazyLex
Contributor

@mfonville Ah yeah, I saw that, just didn't know why it was broken, thanks :)

@dajuno
dajuno commented on 9c36be6 Aug 31, 2016 edited

On my cm13 the shell script didn't throw any errors, but didn't modify any permissions either (E.g. play services have only location). And the error persists.
Any ideas, comments?

edit: did wipe & factory reset + reinstall, works now even without the bash script..

@mddvul22

Thanks for this useful script! I've successfully used this to patch AOSP Nougat.

@vilanova2

@TheCrazyLex hey I'm kind of new to android and flashing custom roms, but I'm trying to learn. I've got a galaxy nexus phone which is now alittle outdated (sadly) so im flashing it with stock android 6.0, and im pretty sure its AOSP. Could you give me a quick explanation on how to use this patch that you provided or direct me to a tutorial because i have no idea. please & thanks!

@jjmontero9

@vilanova2 this patch is for compiling Android 6.0 from the sources, if you are flashing a precompiled ROM then you do not need this.
First flash your ROM, do not turn on your phone yet. Flash TWRP recovery, then flash Gapps using this recovery. And finally turn on your phone. If Gapps works, you don't need anything else. If Gapps do not work, try this script: https://github.com/jomo/fix_open_gapps_permissions

Please sign in to comment.