Merge "Revert "Refactor Bug report flow to work for all ADMIN users""

This commit is contained in:
Gavin Corkery
2022-12-14 09:50:27 +00:00
committed by Android (Google) Code Review
5 changed files with 60 additions and 54 deletions

View File

@@ -455,7 +455,8 @@ public class BugreportProgressService extends Service {
intent.putExtra(DevicePolicyManager.EXTRA_REMOTE_BUGREPORT_HASH, bugreportHash);
intent.putExtra(DevicePolicyManager.EXTRA_REMOTE_BUGREPORT_NONCE, nonce);
intent.putExtra(EXTRA_BUGREPORT, bugreportFileName);
context.sendBroadcast(intent, android.Manifest.permission.DUMP);
context.sendBroadcastAsUser(intent, UserHandle.SYSTEM,
android.Manifest.permission.DUMP);
}
/**

View File

@@ -7438,11 +7438,10 @@ public class ActivityManagerService extends IActivityManager.Stub
if (shareDescription != null) {
triggerShellBugreport.putExtra(EXTRA_DESCRIPTION, shareDescription);
}
UserHandle callingUser = Binder.getCallingUserHandle();
final long identity = Binder.clearCallingIdentity();
try {
// Send broadcast to shell to trigger bugreport using Bugreport API
mContext.sendBroadcastAsUser(triggerShellBugreport, callingUser);
mContext.sendBroadcastAsUser(triggerShellBugreport, UserHandle.SYSTEM);
} finally {
Binder.restoreCallingIdentity(identity);
}

View File

@@ -34,6 +34,7 @@ import android.os.IncidentManager;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Log;
import com.android.internal.util.DumpUtils;
@@ -127,21 +128,21 @@ public class IncidentCompanionService extends SystemService {
try {
final Context context = getContext();
// Get the current admin user. Only they can do incident reports.
final int currentAdminUser = getCurrentUserIfAdmin();
if (currentAdminUser == UserHandle.USER_NULL) {
final int primaryUser = getAndValidateUser(context);
if (primaryUser == UserHandle.USER_NULL) {
return;
}
final Intent intent = new Intent(Intent.ACTION_INCIDENT_REPORT_READY);
intent.setComponent(new ComponentName(pkg, cls));
Log.d(TAG, "sendReportReadyBroadcast sending currentUser=" + currentAdminUser
+ " userHandle=" + UserHandle.of(currentAdminUser)
Log.d(TAG, "sendReportReadyBroadcast sending primaryUser=" + primaryUser
+ " userHandle=" + UserHandle.getUserHandleForUid(primaryUser)
+ " intent=" + intent);
// Send it to the primary user. Only they can do incident reports.
context.sendBroadcastAsUserMultiplePermissions(intent,
UserHandle.of(currentAdminUser),
UserHandle.getUserHandleForUid(primaryUser),
DUMP_AND_USAGE_STATS_PERMISSIONS);
} finally {
Binder.restoreCallingIdentity(ident);
@@ -413,10 +414,10 @@ public class IncidentCompanionService extends SystemService {
}
/**
* Check whether the current user is an admin user, and return the user id if they are.
* Check whether the current user is the primary user, and return the user id if they are.
* Returns UserHandle.USER_NULL if not valid.
*/
public static int getCurrentUserIfAdmin() {
public static int getAndValidateUser(Context context) {
// Current user
UserInfo currentUser;
try {
@@ -426,21 +427,28 @@ public class IncidentCompanionService extends SystemService {
throw new RuntimeException(ex);
}
// Primary user
final UserManager um = UserManager.get(context);
final UserInfo primaryUser = um.getPrimaryUser();
// Check that we're using the right user.
if (currentUser == null) {
Log.w(TAG, "No current user. Nobody to approve the report."
+ " The report will be denied.");
return UserHandle.USER_NULL;
}
if (!currentUser.isAdmin()) {
Log.w(TAG, "Only an admin user running in foreground can approve "
+ "bugreports, but the current foreground user is not an admin user. "
+ "The report will be denied.");
if (primaryUser == null) {
Log.w(TAG, "No primary user. Nobody to approve the report."
+ " The report will be denied.");
return UserHandle.USER_NULL;
}
if (primaryUser.id != currentUser.id) {
Log.w(TAG, "Only the primary user can approve bugreports, but they are not"
+ " the current user. The report will be denied.");
return UserHandle.USER_NULL;
}
return currentUser.id;
return primaryUser.id;
}
}

View File

@@ -16,7 +16,6 @@
package com.android.server.incident;
import android.annotation.UserIdInt;
import android.app.AppOpsManager;
import android.app.BroadcastOptions;
import android.content.ComponentName;
@@ -273,19 +272,15 @@ class PendingReports {
return;
}
// Find the current user of the device and check if they are an admin.
final int currentAdminUser = getCurrentUserIfAdmin();
// Deny the report if the current admin user is null
// or not the user who requested the report.
if (currentAdminUser == UserHandle.USER_NULL
|| currentAdminUser != UserHandle.getUserId(callingUid)) {
// Find the primary user of this device.
final int primaryUser = getAndValidateUser();
if (primaryUser == UserHandle.USER_NULL) {
denyReportBeforeAddingRec(listener, callingPackage);
return;
}
// Find the approver app (hint: it's PermissionController).
final ComponentName receiver = getApproverComponent(currentAdminUser);
final ComponentName receiver = getApproverComponent(primaryUser);
if (receiver == null) {
// We couldn't find an approver... so deny the request here and now, before we
// do anything else.
@@ -303,26 +298,26 @@ class PendingReports {
try {
listener.asBinder().linkToDeath(() -> {
Log.i(TAG, "Got death notification listener=" + listener);
cancelReportImpl(listener, receiver, currentAdminUser);
cancelReportImpl(listener, receiver, primaryUser);
}, 0);
} catch (RemoteException ex) {
Log.e(TAG, "Remote died while trying to register death listener: " + rec.getUri());
// First, remove from our list.
cancelReportImpl(listener, receiver, currentAdminUser);
cancelReportImpl(listener, receiver, primaryUser);
}
// Go tell Permission controller to start asking the user.
sendBroadcast(receiver, currentAdminUser);
sendBroadcast(receiver, primaryUser);
}
/**
* Cancel a pending report request (because of an explicit call to cancel)
*/
private void cancelReportImpl(IIncidentAuthListener listener) {
final int currentAdminUser = getCurrentUserIfAdmin();
final ComponentName receiver = getApproverComponent(currentAdminUser);
if (currentAdminUser != UserHandle.USER_NULL && receiver != null) {
cancelReportImpl(listener, receiver, currentAdminUser);
final int primaryUser = getAndValidateUser();
final ComponentName receiver = getApproverComponent(primaryUser);
if (primaryUser != UserHandle.USER_NULL && receiver != null) {
cancelReportImpl(listener, receiver, primaryUser);
}
}
@@ -331,13 +326,13 @@ class PendingReports {
* by the calling app, or because of a binder death).
*/
private void cancelReportImpl(IIncidentAuthListener listener, ComponentName receiver,
@UserIdInt int user) {
int primaryUser) {
// First, remove from our list.
synchronized (mLock) {
removePendingReportRecLocked(listener);
}
// Second, call back to PermissionController to say it's canceled.
sendBroadcast(receiver, user);
sendBroadcast(receiver, primaryUser);
}
/**
@@ -347,21 +342,21 @@ class PendingReports {
* cleanup cases to keep the apps' list in sync with ours.
*/
private void sendBroadcast() {
final int currentAdminUser = getCurrentUserIfAdmin();
if (currentAdminUser == UserHandle.USER_NULL) {
final int primaryUser = getAndValidateUser();
if (primaryUser == UserHandle.USER_NULL) {
return;
}
final ComponentName receiver = getApproverComponent(currentAdminUser);
final ComponentName receiver = getApproverComponent(primaryUser);
if (receiver == null) {
return;
}
sendBroadcast(receiver, currentAdminUser);
sendBroadcast(receiver, primaryUser);
}
/**
* Send the confirmation broadcast.
*/
private void sendBroadcast(ComponentName receiver, int currentUser) {
private void sendBroadcast(ComponentName receiver, int primaryUser) {
final Intent intent = new Intent(Intent.ACTION_PENDING_INCIDENT_REPORTS_CHANGED);
intent.setComponent(receiver);
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
@@ -369,8 +364,8 @@ class PendingReports {
final BroadcastOptions options = BroadcastOptions.makeBasic();
options.setBackgroundActivityStartsAllowed(true);
// Send it to the current user.
mContext.sendBroadcastAsUser(intent, UserHandle.of(currentUser),
// Send it to the primary user.
mContext.sendBroadcastAsUser(intent, UserHandle.getUserHandleForUid(primaryUser),
android.Manifest.permission.APPROVE_INCIDENT_REPORTS, options.toBundle());
}
@@ -425,11 +420,11 @@ class PendingReports {
}
/**
* Check whether the current user is an admin user, and return the user id if they are.
* Check whether the current user is the primary user, and return the user id if they are.
* Returns UserHandle.USER_NULL if not valid.
*/
private int getCurrentUserIfAdmin() {
return IncidentCompanionService.getCurrentUserIfAdmin();
private int getAndValidateUser() {
return IncidentCompanionService.getAndValidateUser(mContext);
}
/**

View File

@@ -33,8 +33,8 @@ import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Slog;
@@ -189,10 +189,10 @@ class BugreportManagerServiceImpl extends IDumpstate.Stub {
}
/**
* Validates that the current user is an admin user or, when bugreport is requested remotely
* that the current user is an affiliated user.
* Validates that the current user is the primary user or when bugreport is requested remotely
* and current user is affiliated user.
*
* @throws IllegalArgumentException if the current user is not an admin user
* @throws IllegalArgumentException if the current user is not the primary user
*/
private void ensureUserCanTakeBugReport(int bugreportMode) {
UserInfo currentUser = null;
@@ -202,17 +202,20 @@ class BugreportManagerServiceImpl extends IDumpstate.Stub {
// Impossible to get RemoteException for an in-process call.
}
UserInfo primaryUser = UserManager.get(mContext).getPrimaryUser();
if (currentUser == null) {
logAndThrow("There is no current user, so no bugreport can be requested.");
logAndThrow("No current user. Only primary user is allowed to take bugreports.");
}
if (!currentUser.isAdmin()) {
if (primaryUser == null) {
logAndThrow("No primary user. Only primary user is allowed to take bugreports.");
}
if (primaryUser.id != currentUser.id) {
if (bugreportMode == BugreportParams.BUGREPORT_MODE_REMOTE
&& isCurrentUserAffiliated(currentUser.id)) {
return;
}
logAndThrow(TextUtils.formatSimple("Current user %s is not an admin user."
+ " Only admin users are allowed to take bugreport.", currentUser.id));
logAndThrow("Current user not primary user. Only primary user"
+ " is allowed to take bugreports.");
}
}