Handling exception when per-use prompt cannot be generated

Decline full device log access when the system fails to generate per-use prompt for
device log access

Bug: 228037077
Test: CtsVerifier
Ignore-AOSP-First: pending fix for logcat privacy issue
Change-Id: Ic1e1f4891a8f198e400e942142a60c2031c9439f
This commit is contained in:
eunjeongshin
2022-04-04 23:35:08 +00:00
parent ee9ba8ff1b
commit f41f0dea68
2 changed files with 103 additions and 44 deletions

View File

@@ -30,6 +30,7 @@ import android.os.ServiceManager;
import android.os.UserHandle; import android.os.UserHandle;
import android.os.logcat.ILogcatManagerService; import android.os.logcat.ILogcatManagerService;
import android.util.Slog; import android.util.Slog;
import android.view.InflateException;
import android.view.View; import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.TextView; import android.widget.TextView;
@@ -56,33 +57,46 @@ public class LogAccessDialogActivity extends Activity implements
private String mAlertTitle; private String mAlertTitle;
private AlertDialog.Builder mAlertDialog; private AlertDialog.Builder mAlertDialog;
private AlertDialog mAlert; private AlertDialog mAlert;
private View mAlertView;
private static final int DIALOG_TIME_OUT = Build.IS_DEBUGGABLE ? 60000 : 300000; private static final int DIALOG_TIME_OUT = Build.IS_DEBUGGABLE ? 60000 : 300000;
private static final int MSG_DISMISS_DIALOG = 0; private static final int MSG_DISMISS_DIALOG = 0;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
mContext = this;
Intent intent = getIntent(); try {
mPackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME); mContext = this;
mUid = intent.getIntExtra("com.android.server.logcat.uid", 0);
mGid = intent.getIntExtra("com.android.server.logcat.gid", 0);
mPid = intent.getIntExtra("com.android.server.logcat.pid", 0);
mFd = intent.getIntExtra("com.android.server.logcat.fd", 0);
mAlertTitle = getTitleString(mContext, mPackageName, mUid);
if (mAlertTitle != null) { // retrieve Intent extra information
Intent intent = getIntent();
getIntentInfo(intent);
// retrieve the title string from passed intent extra
mAlertTitle = getTitleString(mContext, mPackageName, mUid);
// creaet View
mAlertView = createView();
// create AlertDialog
mAlertDialog = new AlertDialog.Builder(this); mAlertDialog = new AlertDialog.Builder(this);
mAlertDialog.setView(createView()); mAlertDialog.setView(mAlertView);
// show Alert
mAlert = mAlertDialog.create(); mAlert = mAlertDialog.create();
mAlert.show(); mAlert.show();
// set Alert Timeout
mHandler.sendEmptyMessageDelayed(MSG_DISMISS_DIALOG, DIALOG_TIME_OUT); mHandler.sendEmptyMessageDelayed(MSG_DISMISS_DIALOG, DIALOG_TIME_OUT);
} catch (Exception e) {
try {
Slog.e(TAG, "onCreate failed, declining the logd access", e);
mLogcatManagerService.decline(mUid, mGid, mPid, mFd);
} catch (RemoteException ex) {
Slog.e(TAG, "Fails to call remote functions", ex);
}
} }
} }
@@ -95,6 +109,19 @@ public class LogAccessDialogActivity extends Activity implements
mAlert = null; mAlert = null;
} }
private void getIntentInfo(Intent intent) throws Exception {
if (intent == null) {
throw new NullPointerException("Intent is null");
}
mPackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
mUid = intent.getIntExtra("com.android.server.logcat.uid", 0);
mGid = intent.getIntExtra("com.android.server.logcat.gid", 0);
mPid = intent.getIntExtra("com.android.server.logcat.pid", 0);
mFd = intent.getIntExtra("com.android.server.logcat.fd", 0);
}
private Handler mHandler = new Handler() { private Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) { public void handleMessage(android.os.Message msg) {
switch (msg.what) { switch (msg.what) {
@@ -116,26 +143,41 @@ public class LogAccessDialogActivity extends Activity implements
} }
}; };
private String getTitleString(Context context, String callingPackage, int uid) { private String getTitleString(Context context, String callingPackage, int uid)
throws Exception {
PackageManager pm = context.getPackageManager(); PackageManager pm = context.getPackageManager();
try { if (pm == null) {
return context.getString( throw new NullPointerException("PackageManager is null");
com.android.internal.R.string.log_access_confirmation_title,
pm.getApplicationInfoAsUser(callingPackage,
PackageManager.MATCH_DIRECT_BOOT_AUTO,
UserHandle.getUserId(uid)).loadLabel(pm));
} catch (NameNotFoundException e) {
Slog.e(TAG, "App name is unknown.", e);
return null;
} }
CharSequence appLabel = pm.getApplicationInfoAsUser(callingPackage,
PackageManager.MATCH_DIRECT_BOOT_AUTO,
UserHandle.getUserId(uid)).loadLabel(pm);
if (appLabel == null) {
throw new NameNotFoundException("Application Label is null");
}
return context.getString(com.android.internal.R.string.log_access_confirmation_title,
appLabel);
} }
private View createView() { /**
* Returns the dialog view.
* If we cannot retrieve the package name, it returns null and we decline the full device log
* access
*/
private View createView() throws Exception {
final View view = getLayoutInflater().inflate( final View view = getLayoutInflater().inflate(
R.layout.log_access_user_consent_dialog_permission, null /*root*/); R.layout.log_access_user_consent_dialog_permission, null /*root*/);
if (view == null) {
throw new InflateException();
}
((TextView) view.findViewById(R.id.log_access_dialog_title)) ((TextView) view.findViewById(R.id.log_access_dialog_title))
.setText(mAlertTitle); .setText(mAlertTitle);
Button button_allow = (Button) view.findViewById(R.id.log_access_dialog_allow_button); Button button_allow = (Button) view.findViewById(R.id.log_access_dialog_allow_button);
button_allow.setOnClickListener(this); button_allow.setOnClickListener(this);
@@ -144,6 +186,7 @@ public class LogAccessDialogActivity extends Activity implements
button_deny.setOnClickListener(this); button_deny.setOnClickListener(this);
return view; return view;
} }
@Override @Override

View File

@@ -102,16 +102,27 @@ public final class LogcatManagerService extends SystemService {
} }
} }
private void showDialog(int uid, int gid, int pid, int fd) { /**
* Returns the package name.
* If we cannot retrieve the package name, it returns null and we decline the full device log
* access
*/
private String getPackageName(int uid, int gid, int pid, int fd) {
final ActivityManagerInternal activityManagerInternal = final ActivityManagerInternal activityManagerInternal =
LocalServices.getService(ActivityManagerInternal.class); LocalServices.getService(ActivityManagerInternal.class);
if (activityManagerInternal != null) {
String packageName = activityManagerInternal.getPackageNameByPid(pid);
if (packageName != null) {
return packageName;
}
}
PackageManager pm = mContext.getPackageManager(); PackageManager pm = mContext.getPackageManager();
String packageName = activityManagerInternal.getPackageNameByPid(pid); if (pm == null) {
if (packageName != null) { // Decline the logd access if PackageManager is null
Intent mIntent = createIntent(packageName, uid, gid, pid, fd); Slog.e(TAG, "PackageManager is null, declining the logd access");
mContext.startActivityAsUser(mIntent, UserHandle.SYSTEM); return null;
return;
} }
String[] packageNames = pm.getPackagesForUid(uid); String[] packageNames = pm.getPackagesForUid(uid);
@@ -119,21 +130,19 @@ public final class LogcatManagerService extends SystemService {
if (ArrayUtils.isEmpty(packageNames)) { if (ArrayUtils.isEmpty(packageNames)) {
// Decline the logd access if the app name is unknown // Decline the logd access if the app name is unknown
Slog.e(TAG, "Unknown calling package name, declining the logd access"); Slog.e(TAG, "Unknown calling package name, declining the logd access");
declineLogdAccess(uid, gid, pid, fd); return null;
return;
} }
String firstPackageName = packageNames[0]; String firstPackageName = packageNames[0];
if (firstPackageName.isEmpty() || firstPackageName == null) { if (firstPackageName == null || firstPackageName.isEmpty()) {
// Decline the logd access if the package name from uid is unknown // Decline the logd access if the package name from uid is unknown
Slog.e(TAG, "Unknown calling package name, declining the logd access"); Slog.e(TAG, "Unknown calling package name, declining the logd access");
declineLogdAccess(uid, gid, pid, fd); return null;
return;
} }
final Intent mIntent = createIntent(firstPackageName, uid, gid, pid, fd); return firstPackageName;
mContext.startActivityAsUser(mIntent, UserHandle.SYSTEM);
} }
private void declineLogdAccess(int uid, int gid, int pid, int fd) { private void declineLogdAccess(int uid, int gid, int pid, int fd) {
@@ -198,16 +207,23 @@ public final class LogcatManagerService extends SystemService {
final int procState = LocalServices.getService(ActivityManagerInternal.class) final int procState = LocalServices.getService(ActivityManagerInternal.class)
.getUidProcessState(mUid); .getUidProcessState(mUid);
// If the process is foreground, show a dialog for user consent // If the process is foreground and we can retrieve the package name, show a dialog
// for user consent
if (procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) { if (procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
showDialog(mUid, mGid, mPid, mFd); String packageName = getPackageName(mUid, mGid, mPid, mFd);
} else { if (packageName != null) {
/** final Intent mIntent = createIntent(packageName, mUid, mGid, mPid, mFd);
* If the process is background, decline the logd access. mContext.startActivityAsUser(mIntent, UserHandle.SYSTEM);
**/ return;
declineLogdAccess(mUid, mGid, mPid, mFd); }
return;
} }
/**
* If the process is background or cannot retrieve the package name,
* decline the logd access.
**/
declineLogdAccess(mUid, mGid, mPid, mFd);
return;
} }
} }
} }