diff options
| -rw-r--r-- | core/api/current.txt | 3 | ||||
| -rw-r--r-- | core/java/android/os/DropBoxManager.java | 18 | ||||
| -rw-r--r-- | core/res/AndroidManifest.xml | 6 | ||||
| -rw-r--r-- | services/core/Android.bp | 1 | ||||
| -rw-r--r-- | services/core/java/com/android/server/DropBoxManagerService.java | 42 | ||||
| -rw-r--r-- | services/core/java/com/android/server/feature/Android.bp | 12 | ||||
| -rw-r--r-- | services/core/java/com/android/server/feature/dropbox_flags.aconfig | 8 |
7 files changed, 79 insertions, 11 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index 66aeb0f7cbaf..8b8494a1de53 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -232,6 +232,7 @@ package android { field public static final String READ_CALENDAR = "android.permission.READ_CALENDAR"; field public static final String READ_CALL_LOG = "android.permission.READ_CALL_LOG"; field public static final String READ_CONTACTS = "android.permission.READ_CONTACTS"; + field @FlaggedApi("com.android.server.feature.flags.enable_read_dropbox_permission") public static final String READ_DROPBOX_DATA = "android.permission.READ_DROPBOX_DATA"; field public static final String READ_EXTERNAL_STORAGE = "android.permission.READ_EXTERNAL_STORAGE"; field public static final String READ_HOME_APP_SEARCH_DATA = "android.permission.READ_HOME_APP_SEARCH_DATA"; field @Deprecated public static final String READ_INPUT_STATE = "android.permission.READ_INPUT_STATE"; @@ -32393,7 +32394,7 @@ package android.os { method public void addData(@NonNull String, @Nullable byte[], int); method public void addFile(@NonNull String, @NonNull java.io.File, int) throws java.io.IOException; method public void addText(@NonNull String, @NonNull String); - method @Nullable @RequiresPermission(allOf={android.Manifest.permission.READ_LOGS, android.Manifest.permission.PACKAGE_USAGE_STATS}) public android.os.DropBoxManager.Entry getNextEntry(String, long); + method @Nullable @RequiresPermission(allOf={android.Manifest.permission.READ_DROPBOX_DATA, android.Manifest.permission.PACKAGE_USAGE_STATS}) public android.os.DropBoxManager.Entry getNextEntry(String, long); method public boolean isTagEnabled(String); field public static final String ACTION_DROPBOX_ENTRY_ADDED = "android.intent.action.DROPBOX_ENTRY_ADDED"; field public static final String EXTRA_DROPPED_COUNT = "android.os.extra.DROPPED_COUNT"; diff --git a/core/java/android/os/DropBoxManager.java b/core/java/android/os/DropBoxManager.java index cf3546057549..a1d2dcc74246 100644 --- a/core/java/android/os/DropBoxManager.java +++ b/core/java/android/os/DropBoxManager.java @@ -17,7 +17,7 @@ package android.os; import static android.Manifest.permission.PACKAGE_USAGE_STATS; -import static android.Manifest.permission.READ_LOGS; +import static android.Manifest.permission.READ_DROPBOX_DATA; import android.annotation.BytesLong; import android.annotation.CurrentTimeMillisLong; @@ -81,9 +81,12 @@ public class DropBoxManager { /** * Broadcast Action: This is broadcast when a new entry is added in the dropbox. - * You must hold the {@link android.Manifest.permission#READ_LOGS} permission - * in order to receive this broadcast. This broadcast can be rate limited for low priority - * entries + * For apps targeting {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM} and later, you + * must hold the {@link android.Manifest.permission#READ_DROPBOX_DATA} permission + * in order to receive this broadcast. For apps targeting Android versions lower + * than {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM}, you must hold + * {@link android.Manifest.permission#READ_LOGS}. + * This broadcast can be rate limited for low priority entries * * <p class="note">This is a protected intent that can only be sent * by the system. @@ -382,12 +385,17 @@ public class DropBoxManager { /** * Gets the next entry from the drop box <em>after</em> the specified time. * You must always call {@link Entry#close()} on the return value! + * {@link android.Manifest.permission#READ_DROPBOX_DATA} permission is + * required for apps targeting {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM} + * and later. {@link android.Manifest.permission#READ_LOGS} permission is + * required for apps targeting Android versions lower than + * {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM}. * * @param tag of entry to look for, null for all tags * @param msec time of the last entry seen * @return the next entry, or null if there are no more entries */ - @RequiresPermission(allOf = { READ_LOGS, PACKAGE_USAGE_STATS }) + @RequiresPermission(allOf = { READ_DROPBOX_DATA, PACKAGE_USAGE_STATS }) public @Nullable Entry getNextEntry(String tag, long msec) { try { return mService.getNextEntryWithAttribution(tag, msec, mContext.getOpPackageName(), diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 6daa5b934284..f2e50b3f2daa 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -4565,6 +4565,12 @@ <permission android:name="android.permission.SET_DEBUG_APP" android:protectionLevel="signature|privileged|development" /> + <!-- Allows an application to access the data in Dropbox. + <p>Not for use by third-party applications. + @FlaggedApi("com.android.server.feature.flags.enable_read_dropbox_permission") --> + <permission android:name="android.permission.READ_DROPBOX_DATA" + android:protectionLevel="signature|privileged|development" /> + <!-- Allows an application to set the maximum number of (not needed) application processes that can be running. <p>Not for use by third-party applications. --> diff --git a/services/core/Android.bp b/services/core/Android.bp index 898cdcc30e0f..50d9e6fcc623 100644 --- a/services/core/Android.bp +++ b/services/core/Android.bp @@ -196,6 +196,7 @@ java_library_static { "android.hardware.power.stats-V2-java", "android.hidl.manager-V1.2-java", "cbor-java", + "dropbox_flags_lib", "icu4j_calendar_astronomer", "android.security.aaid_aidl-java", "netd-client", diff --git a/services/core/java/com/android/server/DropBoxManagerService.java b/services/core/java/com/android/server/DropBoxManagerService.java index 55069b779a37..f82a6aabfefb 100644 --- a/services/core/java/com/android/server/DropBoxManagerService.java +++ b/services/core/java/com/android/server/DropBoxManagerService.java @@ -16,10 +16,14 @@ package com.android.server; +import android.Manifest; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.AppOpsManager; import android.app.BroadcastOptions; +import android.app.compat.CompatChanges; +import android.compat.annotation.ChangeId; +import android.compat.annotation.EnabledAfter; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; @@ -30,6 +34,7 @@ import android.content.res.Resources; import android.database.ContentObserver; import android.net.Uri; import android.os.Binder; +import android.os.Build; import android.os.Bundle; import android.os.BundleMerger; import android.os.Debug; @@ -66,6 +71,7 @@ import com.android.internal.util.DumpUtils; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.ObjectUtils; import com.android.server.DropBoxManagerInternal.EntrySource; +import com.android.server.feature.flags.Flags; import libcore.io.IoUtils; @@ -89,6 +95,13 @@ import java.util.zip.GZIPOutputStream; * Clients use {@link DropBoxManager} to access this service. */ public final class DropBoxManagerService extends SystemService { + /** + * For Android U and earlier versions, apps can continue to use the READ_LOGS permission, + * but for all subsequent versions, the READ_DROPBOX_DATA permission must be used. + */ + @ChangeId + @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) + private static final long ENFORCE_READ_DROPBOX_DATA = 296060945L; private static final String TAG = "DropBoxManagerService"; private static final int DEFAULT_AGE_SECONDS = 3 * 86400; private static final int DEFAULT_MAX_FILES = 1000; @@ -109,7 +122,6 @@ public final class DropBoxManagerService extends SystemService { // Tags that we should drop by default. private static final List<String> DISABLED_BY_DEFAULT_TAGS = List.of("data_app_wtf", "system_app_wtf", "system_server_wtf"); - // TODO: This implementation currently uses one file per entry, which is // inefficient for smallish entries -- consider using a single queue file // per tag (or even globally) instead. @@ -291,8 +303,21 @@ public final class DropBoxManagerService extends SystemService { if (!DropBoxManagerService.this.mBooted) { intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); } - getContext().sendBroadcastAsUser(intent, UserHandle.ALL, - android.Manifest.permission.READ_LOGS, options); + if (Flags.enableReadDropboxPermission()) { + BroadcastOptions unbundledOptions = (options == null) + ? BroadcastOptions.makeBasic() : BroadcastOptions.fromBundle(options); + + unbundledOptions.setRequireCompatChange(ENFORCE_READ_DROPBOX_DATA, true); + getContext().sendBroadcastAsUser(intent, UserHandle.ALL, + Manifest.permission.READ_DROPBOX_DATA, unbundledOptions.toBundle()); + + unbundledOptions.setRequireCompatChange(ENFORCE_READ_DROPBOX_DATA, false); + getContext().sendBroadcastAsUser(intent, UserHandle.ALL, + Manifest.permission.READ_LOGS, unbundledOptions.toBundle()); + } else { + getContext().sendBroadcastAsUser(intent, UserHandle.ALL, + android.Manifest.permission.READ_LOGS, options); + } } private Intent createIntent(String tag, long time) { @@ -572,9 +597,16 @@ public final class DropBoxManagerService extends SystemService { return true; } + + String permission = Manifest.permission.READ_LOGS; + if (Flags.enableReadDropboxPermission() + && CompatChanges.isChangeEnabled(ENFORCE_READ_DROPBOX_DATA, callingUid)) { + permission = Manifest.permission.READ_DROPBOX_DATA; + } + // Callers always need this permission - getContext().enforceCallingOrSelfPermission( - android.Manifest.permission.READ_LOGS, TAG); + getContext().enforceCallingOrSelfPermission(permission, TAG); + // Callers also need the ability to read usage statistics switch (getContext().getSystemService(AppOpsManager.class).noteOp( diff --git a/services/core/java/com/android/server/feature/Android.bp b/services/core/java/com/android/server/feature/Android.bp new file mode 100644 index 000000000000..067288d6650d --- /dev/null +++ b/services/core/java/com/android/server/feature/Android.bp @@ -0,0 +1,12 @@ +aconfig_declarations { + name: "dropbox_flags", + package: "com.android.server.feature.flags", + srcs: [ + "dropbox_flags.aconfig", + ], +} + +java_aconfig_library { + name: "dropbox_flags_lib", + aconfig_declarations: "dropbox_flags", +} diff --git a/services/core/java/com/android/server/feature/dropbox_flags.aconfig b/services/core/java/com/android/server/feature/dropbox_flags.aconfig new file mode 100644 index 000000000000..fee4bf377ddc --- /dev/null +++ b/services/core/java/com/android/server/feature/dropbox_flags.aconfig @@ -0,0 +1,8 @@ +package: "com.android.server.feature.flags" + +flag{ + name: "enable_read_dropbox_permission" + namespace: "preload_safety" + description: "Feature flag for permission to Read dropbox data" + bug: "287512663" +}
\ No newline at end of file |