summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AndroidManifest.xml7
-rw-r--r--src/com/android/providers/contacts/ContactsProvider2.java11
-rw-r--r--src/com/android/providers/contacts/ProfileProvider.java6
-rw-r--r--src/com/android/providers/contacts/VoicemailContentProvider.java5
-rw-r--r--src/com/android/providers/contacts/VoicemailPermissions.java9
-rw-r--r--src/com/android/providers/contacts/util/ContactsPermissions.java100
-rw-r--r--tests/AndroidManifest.xml2
-rw-r--r--tests/src/com/android/providers/contacts/ContactsActor.java5
8 files changed, 122 insertions, 23 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 347abb3..80bd125 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -10,16 +10,9 @@
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
<uses-permission android:name="android.permission.MANAGE_USERS" />
<uses-permission android:name="android.permission.PROCESS_PHONE_ACCOUNT_REGISTRATION" />
- <uses-permission android:name="android.permission.READ_CONTACTS" />
- <uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.SEND_CALL_LOG_CHANGE" />
<uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" />
- <uses-permission android:name="android.permission.WRITE_CONTACTS" />
- <uses-permission android:name="android.permission.WRITE_PROFILE" />
- <uses-permission android:name="com.android.voicemail.permission.ADD_VOICEMAIL" />
- <uses-permission android:name="com.android.voicemail.permission.WRITE_VOICEMAIL" />
- <uses-permission android:name="com.android.voicemail.permission.READ_VOICEMAIL" />
<permission
android:name="android.permission.SEND_CALL_LOG_CHANGE"
diff --git a/src/com/android/providers/contacts/ContactsProvider2.java b/src/com/android/providers/contacts/ContactsProvider2.java
index 5cbca9e..8fce6a6 100644
--- a/src/com/android/providers/contacts/ContactsProvider2.java
+++ b/src/com/android/providers/contacts/ContactsProvider2.java
@@ -159,6 +159,7 @@ import com.android.providers.contacts.MetadataEntryParser.MetadataEntry;
import com.android.providers.contacts.MetadataEntryParser.RawContactInfo;
import com.android.providers.contacts.MetadataEntryParser.UsageStats;
import com.android.providers.contacts.util.Clock;
+import com.android.providers.contacts.util.ContactsPermissions;
import com.android.providers.contacts.util.DbQueryUtils;
import com.android.providers.contacts.util.NeededForTesting;
import com.android.providers.contacts.util.UserUtils;
@@ -2214,7 +2215,7 @@ public class ContactsProvider2 extends AbstractContactsProvider
response.putParcelable(Authorization.KEY_AUTHORIZED_URI, authUri);
return response;
} else if (PinnedPositions.UNDEMOTE_METHOD.equals(method)) {
- getContext().enforceCallingOrSelfPermission(WRITE_PERMISSION, null);
+ ContactsPermissions.enforceCallingOrSelfPermission(getContext(), WRITE_PERMISSION);
final long id;
try {
id = Long.valueOf(arg);
@@ -2970,8 +2971,8 @@ public class ContactsProvider2 extends AbstractContactsProvider
private void enforceSocialStreamReadPermission(Uri uri) {
if (SOCIAL_STREAM_URIS.contains(sUriMatcher.match(uri))
&& !isValidPreAuthorizedUri(uri)) {
- getContext().enforceCallingOrSelfPermission(
- "android.permission.READ_SOCIAL_STREAM", null);
+ ContactsPermissions.enforceCallingOrSelfPermission(getContext(),
+ "android.permission.READ_SOCIAL_STREAM");
}
}
@@ -2982,8 +2983,8 @@ public class ContactsProvider2 extends AbstractContactsProvider
*/
private void enforceSocialStreamWritePermission(Uri uri) {
if (SOCIAL_STREAM_URIS.contains(sUriMatcher.match(uri))) {
- getContext().enforceCallingOrSelfPermission(
- "android.permission.WRITE_SOCIAL_STREAM", null);
+ ContactsPermissions.enforceCallingOrSelfPermission(getContext(),
+ "android.permission.WRITE_SOCIAL_STREAM");
}
}
diff --git a/src/com/android/providers/contacts/ProfileProvider.java b/src/com/android/providers/contacts/ProfileProvider.java
index d01195d..ee18a5e 100644
--- a/src/com/android/providers/contacts/ProfileProvider.java
+++ b/src/com/android/providers/contacts/ProfileProvider.java
@@ -15,6 +15,8 @@
*/
package com.android.providers.contacts;
+import com.android.providers.contacts.util.ContactsPermissions;
+
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
@@ -51,7 +53,7 @@ public class ProfileProvider extends AbstractContactsProvider {
*/
public void enforceReadPermission(Uri uri) {
if (!mDelegate.isValidPreAuthorizedUri(uri)) {
- mDelegate.getContext().enforceCallingOrSelfPermission(READ_PERMISSION, null);
+ ContactsPermissions.enforceCallingOrSelfPermission(getContext(), READ_PERMISSION);
}
}
@@ -59,7 +61,7 @@ public class ProfileProvider extends AbstractContactsProvider {
* Performs a permission check on the write profile permission.
*/
public void enforceWritePermission() {
- mDelegate.getContext().enforceCallingOrSelfPermission(WRITE_PERMISSION, null);
+ ContactsPermissions.enforceCallingOrSelfPermission(getContext(), WRITE_PERMISSION);
}
@Override
diff --git a/src/com/android/providers/contacts/VoicemailContentProvider.java b/src/com/android/providers/contacts/VoicemailContentProvider.java
index ba51b8e..e4f6a05 100644
--- a/src/com/android/providers/contacts/VoicemailContentProvider.java
+++ b/src/com/android/providers/contacts/VoicemailContentProvider.java
@@ -35,6 +35,7 @@ import android.provider.VoicemailContract.Voicemails;
import android.util.Log;
import com.android.providers.contacts.ContactsDatabaseHelper.Tables;
+import com.android.providers.contacts.util.ContactsPermissions;
import com.android.providers.contacts.util.SelectionBuilder;
import com.android.providers.contacts.util.TypedUriMatcherImpl;
import com.google.common.annotations.VisibleForTesting;
@@ -291,8 +292,8 @@ public class VoicemailContentProvider extends ContentProvider
private UriData checkPermissionsAndCreateUriDataForRead(Uri uri) {
// If the caller has been explicitly granted read permission to this URI then no need to
// check further.
- if (context().checkCallingUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION)
- == PackageManager.PERMISSION_GRANTED) {
+ if (ContactsPermissions.hasCallerUriPermission(
+ getContext(), uri, Intent.FLAG_GRANT_READ_URI_PERMISSION)) {
return UriData.createUriData(uri);
}
diff --git a/src/com/android/providers/contacts/VoicemailPermissions.java b/src/com/android/providers/contacts/VoicemailPermissions.java
index e1c9b57..50f2447 100644
--- a/src/com/android/providers/contacts/VoicemailPermissions.java
+++ b/src/com/android/providers/contacts/VoicemailPermissions.java
@@ -16,8 +16,9 @@
package com.android.providers.contacts;
+import com.android.providers.contacts.util.ContactsPermissions;
+
import android.content.Context;
-import android.content.pm.PackageManager;
import android.telecom.DefaultDialerManager;
/**
@@ -105,13 +106,11 @@ public class VoicemailPermissions {
/** Determines if the given package has the given permission. */
private boolean packageHasPermission(String packageName, String permission) {
- return mContext.getPackageManager().checkPermission(permission, packageName)
- == PackageManager.PERMISSION_GRANTED;
+ return ContactsPermissions.hasPackagePermission(mContext, permission, packageName);
}
/** Determines if the calling process has the given permission. */
private boolean callerHasPermission(String permission) {
- return mContext.checkCallingOrSelfPermission(permission)
- == PackageManager.PERMISSION_GRANTED;
+ return ContactsPermissions.hasCallerOrSelfPermission(mContext, permission);
}
}
diff --git a/src/com/android/providers/contacts/util/ContactsPermissions.java b/src/com/android/providers/contacts/util/ContactsPermissions.java
new file mode 100644
index 0000000..6dda50b
--- /dev/null
+++ b/src/com/android/providers/contacts/util/ContactsPermissions.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.providers.contacts.util;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.Process;
+import android.util.Log;
+
+public class ContactsPermissions {
+ private static final String TAG = "ContactsPermissions";
+
+ private static final boolean DEBUG = false; // DO NOT submit with true
+
+ // Normally, we allow calls from self, *except* in unit tests, where we clear this flag
+ // to emulate calls from other apps.
+ public static boolean ALLOW_SELF_CALL = true;
+
+ private ContactsPermissions() {
+ }
+
+ public static boolean hasCallerOrSelfPermission(Context context, String permission) {
+ boolean ok = false;
+
+ if (ALLOW_SELF_CALL && Binder.getCallingPid() == Process.myPid()) {
+ ok = true; // Called by self; always allow.
+ } else {
+ ok = context.checkCallingOrSelfPermission(permission)
+ == PackageManager.PERMISSION_GRANTED;
+ }
+ if (DEBUG) {
+ Log.d(TAG, "hasCallerOrSelfPermission: "
+ + " perm=" + permission
+ + " caller=" + Binder.getCallingPid()
+ + " self=" + Process.myPid()
+ + " ok=" + ok);
+ }
+ return ok;
+ }
+
+ public static void enforceCallingOrSelfPermission(Context context, String permission) {
+ final boolean ok = hasCallerOrSelfPermission(context, permission);
+ if (!ok) {
+ throw new SecurityException(String.format("The caller must have the %s permission.",
+ permission));
+ }
+ }
+
+ public static boolean hasPackagePermission(Context context, String permission, String pkg) {
+ boolean ok = false;
+ if (ALLOW_SELF_CALL && context.getPackageName().equals(pkg)) {
+ ok = true; // Called by self; always allow.
+ } else {
+ ok = context.getPackageManager().checkPermission(permission, pkg)
+ == PackageManager.PERMISSION_GRANTED;
+ }
+ if (DEBUG) {
+ Log.d(TAG, "hasCallerOrSelfPermission: "
+ + " perm=" + permission
+ + " pkg=" + pkg
+ + " self=" + context.getPackageName()
+ + " ok=" + ok);
+ }
+ return ok;
+ }
+
+ public static boolean hasCallerUriPermission(Context context, Uri uri, int modeFlags) {
+ boolean ok = false;
+ if (ALLOW_SELF_CALL && Binder.getCallingPid() == Process.myPid()) {
+ ok = true; // Called by self; always allow.
+ } else {
+ ok = context.checkCallingUriPermission(uri, modeFlags)
+ == PackageManager.PERMISSION_GRANTED;
+ }
+ if (DEBUG) {
+ Log.d(TAG, "hasCallerUriPermission: "
+ + " uri=" + uri
+ + " caller=" + Binder.getCallingPid()
+ + " self=" + Process.myPid()
+ + " ok=" + ok);
+ }
+ return ok;
+ }
+}
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index 91fceae..e08429a 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -18,8 +18,6 @@
package="com.android.providers.contacts.tests"
android:sharedUserId="android.uid.shared">
- <uses-permission android:name="android.permission.READ_CONTACTS" />
- <uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
diff --git a/tests/src/com/android/providers/contacts/ContactsActor.java b/tests/src/com/android/providers/contacts/ContactsActor.java
index bad7d5d..3ff4086 100644
--- a/tests/src/com/android/providers/contacts/ContactsActor.java
+++ b/tests/src/com/android/providers/contacts/ContactsActor.java
@@ -65,6 +65,7 @@ import android.test.mock.MockContentResolver;
import android.test.mock.MockContext;
import android.util.Log;
+import com.android.providers.contacts.util.ContactsPermissions;
import com.android.providers.contacts.util.MockSharedPreferences;
import com.google.android.collect.Sets;
@@ -263,6 +264,10 @@ public class ContactsActor {
*/
public ContactsActor(final Context overallContext, String packageName,
Class<? extends ContentProvider> providerClass, String authority) throws Exception {
+
+ // Force permission check even when called by self.
+ ContactsPermissions.ALLOW_SELF_CALL = false;
+
resolver = new MockContentResolver();
context = new RestrictionMockContext(overallContext, packageName, resolver,
mGrantedPermissions, mGrantedUriPermissions);