Fix issue #2569139: Cannot login to last.fm after upgrade from Donut to FRF01B

This is a quick and dirty solution to re-assign permissions after booting
from a platform update.  It is not great, because it means that an app
can have permissions that the user didn't get to see when they originally
installed it.  Unfortunately it's not clear what else to do here, nor is
there time to do anything significant.

Change-Id: I82faba141b5883c87212afa7febecf9860a413e3
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index b1bd263..b1b4028 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -954,7 +954,20 @@
                     + ((SystemClock.uptimeMillis()-startTime)/1000f)
                     + " seconds");
 
-            updatePermissionsLP(null, null, true, false);
+            // If the platform SDK has changed since the last time we booted,
+            // we need to re-grant app permission to catch any new ones that
+            // appear.  This is really a hack, and means that apps can in some
+            // cases get permissions that the user didn't initially explicitly
+            // allow...  it would be nice to have some better way to handle
+            // this situation.
+            final boolean regrantPermissions = mSettings.mInternalSdkPlatform
+                    != mSdkVersion;
+            if (regrantPermissions) Slog.i(TAG, "Platform changed from "
+                    + mSettings.mInternalSdkPlatform + " to " + mSdkVersion
+                    + "; regranting permissions for internal storage");
+            mSettings.mInternalSdkPlatform = mSdkVersion;
+            
+            updatePermissionsLP(null, null, true, regrantPermissions);
 
             mSettings.writeLP();
 
@@ -7707,6 +7720,12 @@
         final HashMap<String, PackageSetting> mDisabledSysPackages =
             new HashMap<String, PackageSetting>();
 
+        // These are the last platform API version we were using for
+        // the apps installed on internal and external storage.  It is
+        // used to grant newer permissions one time during a system upgrade.
+        int mInternalSdkPlatform;
+        int mExternalSdkPlatform;
+        
         // The user's preferred activities associated with particular intent
         // filters.
         private final IntentResolver<PreferredActivity, PreferredActivity> mPreferredActivities =
@@ -8291,6 +8310,11 @@
 
                 serializer.startTag(null, "packages");
 
+                serializer.startTag(null, "last-platform-version");
+                serializer.attribute(null, "internal", Integer.toString(mInternalSdkPlatform));
+                serializer.attribute(null, "external", Integer.toString(mExternalSdkPlatform));
+                serializer.endTag(null, "last-platform-version");
+                
                 serializer.startTag(null, "permission-trees");
                 for (BasePermission bp : mPermissionTrees.values()) {
                     writePermission(serializer, bp);
@@ -8684,6 +8708,19 @@
                         if (nname != null && oname != null) {
                             mRenamedPackages.put(nname, oname);
                         }
+                    } else if (tagName.equals("last-platform-version")) {
+                        mInternalSdkPlatform = mExternalSdkPlatform = 0;
+                        try {
+                            String internal = parser.getAttributeValue(null, "internal");
+                            if (internal != null) {
+                                mInternalSdkPlatform = Integer.parseInt(internal);
+                            }
+                            String external = parser.getAttributeValue(null, "external");
+                            if (external != null) {
+                                mInternalSdkPlatform = Integer.parseInt(external);
+                            }
+                        } catch (NumberFormatException e) {
+                        }
                     } else {
                         Slog.w(TAG, "Unknown element under <packages>: "
                               + parser.getName());
@@ -9553,9 +9590,22 @@
            }
        }
        synchronized (mPackages) {
+           // If the platform SDK has changed since the last time we booted,
+           // we need to re-grant app permission to catch any new ones that
+           // appear.  This is really a hack, and means that apps can in some
+           // cases get permissions that the user didn't initially explicitly
+           // allow...  it would be nice to have some better way to handle
+           // this situation.
+           final boolean regrantPermissions = mSettings.mExternalSdkPlatform
+                   != mSdkVersion;
+           if (regrantPermissions) Slog.i(TAG, "Platform changed from "
+                   + mSettings.mExternalSdkPlatform + " to " + mSdkVersion
+                   + "; regranting permissions for external storage");
+           mSettings.mExternalSdkPlatform = mSdkVersion;
+           
            // Make sure group IDs have been assigned, and any permission
            // changes in other apps are accounted for
-           updatePermissionsLP(null, null, true, false);
+           updatePermissionsLP(null, null, true, regrantPermissions);
            // Persist settings
            mSettings.writeLP();
        }