diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt index 8db7de3a3e7f0..9b6f63197f247 100644 --- a/config/hiddenapi-light-greylist.txt +++ b/config/hiddenapi-light-greylist.txt @@ -7575,7 +7575,7 @@ Lcom/android/internal/os/HandlerCaller;->obtainMessageOO(ILjava/lang/Object;Ljav Lcom/android/internal/os/HandlerCaller;->obtainMessageOOO(ILjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Landroid/os/Message; Lcom/android/internal/os/HandlerCaller;->sendMessage(Landroid/os/Message;)V Lcom/android/internal/os/IDropBoxManagerService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/os/IDropBoxManagerService; -Lcom/android/internal/os/IDropBoxManagerService;->getNextEntry(Ljava/lang/String;J)Landroid/os/DropBoxManager$Entry; +Lcom/android/internal/os/IDropBoxManagerService;->getNextEntry(Ljava/lang/String;JLjava/lang/String;)Landroid/os/DropBoxManager$Entry; Lcom/android/internal/os/PowerProfile;->(Landroid/content/Context;)V Lcom/android/internal/os/PowerProfile;->getAveragePower(Ljava/lang/String;)D Lcom/android/internal/os/PowerProfile;->getAveragePower(Ljava/lang/String;I)D diff --git a/core/java/android/os/DropBoxManager.java b/core/java/android/os/DropBoxManager.java index 97f0e0cf31e98..eeae25e9e913c 100644 --- a/core/java/android/os/DropBoxManager.java +++ b/core/java/android/os/DropBoxManager.java @@ -16,9 +16,14 @@ package android.os; +import static android.Manifest.permission.PACKAGE_USAGE_STATS; +import static android.Manifest.permission.READ_LOGS; + +import android.annotation.Nullable; +import android.annotation.RequiresPermission; import android.annotation.SdkConstant; -import android.annotation.SystemService; import android.annotation.SdkConstant.SdkConstantType; +import android.annotation.SystemService; import android.content.Context; import android.util.Log; @@ -351,16 +356,23 @@ public class DropBoxManager { /** * Gets the next entry from the drop box after the specified time. - * Requires android.permission.READ_LOGS. You must always call - * {@link Entry#close()} on the return value! + * You must always call {@link Entry#close()} on the return value! * * @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 */ - public Entry getNextEntry(String tag, long msec) { + @RequiresPermission(allOf = { READ_LOGS, PACKAGE_USAGE_STATS }) + public @Nullable Entry getNextEntry(String tag, long msec) { try { - return mService.getNextEntry(tag, msec); + return mService.getNextEntry(tag, msec, mContext.getOpPackageName()); + } catch (SecurityException e) { + if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.P) { + throw e; + } else { + Log.w(TAG, e.getMessage()); + return null; + } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/com/android/internal/os/IDropBoxManagerService.aidl b/core/java/com/android/internal/os/IDropBoxManagerService.aidl index d16579c03d7a1..70844ee4ef11e 100644 --- a/core/java/com/android/internal/os/IDropBoxManagerService.aidl +++ b/core/java/com/android/internal/os/IDropBoxManagerService.aidl @@ -37,5 +37,5 @@ interface IDropBoxManagerService { boolean isTagEnabled(String tag); /** @see DropBoxManager#getNextEntry */ - DropBoxManager.Entry getNextEntry(String tag, long millis); + DropBoxManager.Entry getNextEntry(String tag, long millis, String packageName); } diff --git a/libs/services/src/os/DropBoxManager.cpp b/libs/services/src/os/DropBoxManager.cpp index c2907a66fb996..8282518f75c64 100644 --- a/libs/services/src/os/DropBoxManager.cpp +++ b/libs/services/src/os/DropBoxManager.cpp @@ -236,7 +236,7 @@ DropBoxManager::getNextEntry(const String16& tag, long msec, Entry* entry) if (service == NULL) { return Status::fromExceptionCode(Status::EX_NULL_POINTER, "can't find dropbox service"); } - return service->getNextEntry(tag, msec, entry); + return service->getNextEntry(tag, msec, android::String16("android"), entry); } }} // namespace android::os diff --git a/services/core/java/com/android/server/DropBoxManagerService.java b/services/core/java/com/android/server/DropBoxManagerService.java index 887de74f1cf9a..b393d8758f3b0 100644 --- a/services/core/java/com/android/server/DropBoxManagerService.java +++ b/services/core/java/com/android/server/DropBoxManagerService.java @@ -17,12 +17,12 @@ package com.android.server; import android.app.ActivityManager; +import android.app.AppOpsManager; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.pm.PackageManager; import android.database.ContentObserver; import android.net.Uri; import android.os.Binder; @@ -41,13 +41,13 @@ import android.text.format.Time; import android.util.ArrayMap; import android.util.Slog; -import libcore.io.IoUtils; - import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.IDropBoxManagerService; import com.android.internal.util.DumpUtils; import com.android.internal.util.ObjectUtils; +import libcore.io.IoUtils; + import java.io.BufferedOutputStream; import java.io.File; import java.io.FileDescriptor; @@ -58,7 +58,6 @@ import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.Objects; import java.util.SortedSet; import java.util.TreeSet; import java.util.zip.GZIPOutputStream; @@ -145,8 +144,8 @@ public final class DropBoxManagerService extends SystemService { } @Override - public DropBoxManager.Entry getNextEntry(String tag, long millis) { - return DropBoxManagerService.this.getNextEntry(tag, millis); + public DropBoxManager.Entry getNextEntry(String tag, long millis, String callingPackage) { + return DropBoxManagerService.this.getNextEntry(tag, millis, callingPackage); } @Override @@ -327,10 +326,29 @@ public final class DropBoxManagerService extends SystemService { } } - public synchronized DropBoxManager.Entry getNextEntry(String tag, long millis) { - if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.READ_LOGS) - != PackageManager.PERMISSION_GRANTED) { - throw new SecurityException("READ_LOGS permission required"); + private boolean checkPermission(int callingUid, String callingPackage) { + // Callers always need this permission + getContext().enforceCallingOrSelfPermission( + android.Manifest.permission.READ_LOGS, TAG); + + // Callers also need the ability to read usage statistics + switch (getContext().getSystemService(AppOpsManager.class) + .noteOp(AppOpsManager.OP_GET_USAGE_STATS, callingUid, callingPackage)) { + case AppOpsManager.MODE_ALLOWED: + return true; + case AppOpsManager.MODE_DEFAULT: + getContext().enforceCallingOrSelfPermission( + android.Manifest.permission.PACKAGE_USAGE_STATS, TAG); + return true; + default: + return false; + } + } + + public synchronized DropBoxManager.Entry getNextEntry(String tag, long millis, + String callingPackage) { + if (!checkPermission(Binder.getCallingUid(), callingPackage)) { + return null; } try {