Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c0cc220e authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Better ContentProvider error messages.

Help guide developers towards ACTION_OPEN_DOCUMENT and related
APIs when a Uri is backed by a DocumentProvider.

Also help developer understand that we expected a valid
ContentProvider for Uri notifications.

Test: builds, boots
Bug: 32642790, 36075317
Change-Id: I8e0e3cb25b183c4a9a094a53018822a4212bdaf9
parent 5dd59219
Loading
Loading
Loading
Loading
+9 −4
Original line number Diff line number Diff line
@@ -620,12 +620,17 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
            return MODE_IGNORED;
        }

        final String failReason = mExported
                ? " requires " + missingPerm + ", or grantUriPermission()"
                : " requires the provider be exported, or grantUriPermission()";
        final String suffix;
        if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(mReadPermission)) {
            suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
        } else if (mExported) {
            suffix = " requires " + missingPerm + ", or grantUriPermission()";
        } else {
            suffix = " requires the provider be exported, or grantUriPermission()";
        }
        throw new SecurityException("Permission Denial: reading "
                + ContentProvider.this.getClass().getName() + " uri " + uri + " from pid=" + pid
                + ", uid=" + uid + failReason);
                + ", uid=" + uid + suffix);
    }

    /** {@hide} */
+21 −14
Original line number Diff line number Diff line
@@ -1185,13 +1185,13 @@ public class ActivityManagerService extends IActivityManager.Stub
        @Override
        public String toString() {
            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
            String result = uri.toString() + " [user " + sourceUserId + "]";
            if (prefix) result += " [prefix]";
            return result;
        }
        public String toSafeString() {
            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
            String result = uri.toSafeString() + " [user " + sourceUserId + "]";
            if (prefix) result += " [prefix]";
            return result;
        }
@@ -8671,8 +8671,15 @@ public class ActivityManagerService extends IActivityManager.Stub
        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
            // Require they hold a strong enough Uri permission
            if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
                throw new SecurityException("Uid " + callingUid
                        + " does not have permission to uri " + grantUri);
                if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
                    throw new SecurityException(
                            "UID " + callingUid + " does not have permission to " + grantUri
                                    + "; you could obtain access using ACTION_OPEN_DOCUMENT "
                                    + "or related APIs");
                } else {
                    throw new SecurityException(
                            "UID " + callingUid + " does not have permission to " + grantUri);
                }
            }
        }
        return targetUid;
@@ -10927,7 +10934,8 @@ public class ActivityManagerService extends IActivityManager.Stub
        } catch (RemoteException ignored) {
        }
        if (cpi == null) {
            return "Failed to find provider " + authority + " for user " + userId;
            return "Failed to find provider " + authority + " for user " + userId
                    + "; expected to find a valid ContentProvider for this authority";
        }
        ProcessRecord r = null;
@@ -11007,18 +11015,17 @@ public class ActivityManagerService extends IActivityManager.Stub
            return null;
        }
        String msg;
        final String suffix;
        if (!cpi.exported) {
            msg = "Permission Denial: opening provider " + cpi.name
                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
                    + ", uid=" + callingUid + ") that is not exported from uid "
                    + cpi.applicationInfo.uid;
            suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
        } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
            suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
        } else {
            msg = "Permission Denial: opening provider " + cpi.name
                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
                    + ", uid=" + callingUid + ") requires "
                    + cpi.readPermission + " or " + cpi.writePermission;
            suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
        }
        final String msg = "Permission Denial: opening provider " + cpi.name
                + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
                + ", uid=" + callingUid + ")" + suffix;
        Slog.w(TAG, msg);
        return msg;
    }