OSDN Git Service

Restricted account visibility
authorAmith Yamasani <yamasani@google.com>
Thu, 28 Mar 2013 01:56:08 +0000 (18:56 -0700)
committerAmith Yamasani <yamasani@google.com>
Thu, 28 Mar 2013 01:56:08 +0000 (18:56 -0700)
When accounts are shared to a restricted/limited user, apps can
opt-in to viewing accounts of a certain type. Other shared accounts
are not visible to the app.

App would specify the account type in the manifest <application> tag
with the attribute restrictedAccountType="foo.bar", where "foo.bar"
is the account type as defined by the authenticator.

Change-Id: I7586da04d6d6d32aae15adc6b1366f325bb07384

api/current.txt
core/java/android/content/pm/PackageInfo.java
core/java/android/content/pm/PackageParser.java
core/res/res/values/attrs_manifest.xml
core/res/res/values/public.xml
services/java/com/android/server/accounts/AccountManagerService.java

index d1a904a..9a90c9f 100644 (file)
@@ -858,6 +858,7 @@ package android {
     field public static final int resource = 16842789; // 0x1010025
     field public static final int restoreAnyVersion = 16843450; // 0x10102ba
     field public static final deprecated int restoreNeedsApplication = 16843421; // 0x101029d
+    field public static final int restrictedAccountType = 16843733; // 0x10103d5
     field public static final int right = 16843183; // 0x10101af
     field public static final int ringtonePreferenceStyle = 16842899; // 0x1010093
     field public static final int ringtoneType = 16843257; // 0x10101f9
index 77ca7f6..33a6757 100644 (file)
@@ -221,6 +221,9 @@ public class PackageInfo implements Parcelable {
     /** @hide */
     public boolean requiredForAllUsers;
 
+    /** @hide */
+    public String restrictedAccountType;
+
     public PackageInfo() {
     }
 
@@ -262,6 +265,7 @@ public class PackageInfo implements Parcelable {
         dest.writeTypedArray(reqFeatures, parcelableFlags);
         dest.writeInt(installLocation);
         dest.writeInt(requiredForAllUsers ? 1 : 0);
+        dest.writeString(restrictedAccountType);
     }
 
     public static final Parcelable.Creator<PackageInfo> CREATOR
@@ -301,5 +305,6 @@ public class PackageInfo implements Parcelable {
         reqFeatures = source.createTypedArray(FeatureInfo.CREATOR);
         installLocation = source.readInt();
         requiredForAllUsers = source.readInt() != 0;
+        restrictedAccountType = source.readString();
     }
 }
index 149b8e5..8893538 100644 (file)
@@ -290,6 +290,7 @@ public class PackageParser {
         pi.applicationInfo = generateApplicationInfo(p, flags, state, userId);
         pi.installLocation = p.installLocation;
         pi.requiredForAllUsers = p.mRequiredForAllUsers;
+        pi.restrictedAccountType = p.mRestrictedAccountType;
         pi.firstInstallTime = firstInstallTime;
         pi.lastUpdateTime = lastUpdateTime;
         if ((flags&PackageManager.GET_GIDS) != 0) {
@@ -1766,6 +1767,11 @@ public class PackageParser {
                     false)) {
                 owner.mRequiredForAllUsers = true;
             }
+            String accountType = sa.getString(com.android.internal.R.styleable
+                    .AndroidManifestApplication_restrictedAccountType);
+            if (accountType != null && accountType.length() > 0) {
+                owner.mRestrictedAccountType = accountType;
+            }
         }
 
         if (sa.getBoolean(
@@ -3193,6 +3199,7 @@ public class PackageParser {
     }
 
     public final static class Package {
+
         public String packageName;
 
         // For now we only support one application per package.
@@ -3280,6 +3287,9 @@ public class PackageParser {
         /* An app that's required for all users and cannot be uninstalled for a user */
         public boolean mRequiredForAllUsers;
 
+        /* The restricted account authenticator type that is used by this application */
+        public String mRestrictedAccountType;
+
         /**
          * Digest suitable for comparing whether this package's manifest is the
          * same as another.
index 6f59817..7b70e21 100644 (file)
         <!-- Declare that your application will be able to deal with RTL (right to left) layouts.
              If set to  false (default value), your application will not care about RTL layouts. -->
         <attr name="supportsRtl" format="boolean" />
+        <!-- Declare that this application requires access to restricted accounts of a certain
+             type. The default value is null and restricted accounts won\'t be visible to this
+             application. The type should correspond to the account authenticator type, such as
+             "com.google" -->
+        <attr name="restrictedAccountType" format="string"/>
     </declare-styleable>
     
     <!-- The <code>permission</code> tag declares a security permission that can be
index 489a947..42d692f 100644 (file)
   <public type="attr" name="indicatorEnd" />
   <public type="attr" name="childIndicatorStart" />
   <public type="attr" name="childIndicatorEnd" />
+  <public type="attr" name="restrictedAccountType" />
 
   <public type="style" name="Theme.NoTitleBar.Overscan" />
   <public type="style" name="Theme.Light.NoTitleBar.Overscan" />
index c4b98ad..53ac0a0 100644 (file)
@@ -2710,7 +2710,7 @@ public class AccountManagerService
         }
         if (mUserManager.getUserInfo(userAccounts.userId).isRestricted()) {
             String[] packages = mPackageManager.getPackagesForUid(callingUid);
-            // If any of the packages includes a white listed package, return the full set,
+            // If any of the packages is a white listed package, return the full set,
             // otherwise return non-shared accounts only.
             // This might be a temporary way to specify a whitelist
             String whiteList = mContext.getResources().getString(
@@ -2723,16 +2723,30 @@ public class AccountManagerService
             ArrayList<Account> allowed = new ArrayList<Account>();
             Account[] sharedAccounts = getSharedAccountsAsUser(userAccounts.userId);
             if (sharedAccounts == null || sharedAccounts.length == 0) return unfiltered;
-            for (Account account : unfiltered) {
-                boolean found = false;
-                for (Account shared : sharedAccounts) {
-                    if (shared.equals(account)) {
-                        found = true;
-                        break;
+            String requiredAccountType = "";
+            try {
+                for (String packageName : packages) {
+                    PackageInfo pi = mPackageManager.getPackageInfo(packageName, 0);
+                    if (pi != null && pi.restrictedAccountType != null) {
+                        requiredAccountType = pi.restrictedAccountType;
                     }
                 }
-                if (!found) {
+            } catch (NameNotFoundException nnfe) {
+            }
+            for (Account account : unfiltered) {
+                if (account.type.equals(requiredAccountType)) {
                     allowed.add(account);
+                } else {
+                    boolean found = false;
+                    for (Account shared : sharedAccounts) {
+                        if (shared.equals(account)) {
+                            found = true;
+                            break;
+                        }
+                    }
+                    if (!found) {
+                        allowed.add(account);
+                    }
                 }
             }
             Account[] filtered = new Account[allowed.size()];