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

Commit 2b6a2340 authored by Robert Horvath's avatar Robert Horvath
Browse files

LogAccessDialogActivity improvements

1. Makes the activity under AlertDialog translucent

When the AlertDialog is dismissed, a dialog like view can be seen with
the activity's label (with a "%s" placeholder) can be seen.
This change makes the activity itself translucent.

2. Handles cancel/dismiss of the dialog

When the dialog is canceled (eg. pressing back button or tapping
outside the dialog) decline the log access request.
When the dialog is dismissed finish the activity hosting the dialog.

3. Clean up unused code, some refactoring, more error handling

Bug: 228001277
Bug: 228563090
Test: Manual
Change-Id: Ib5f39eb12b41ed4137bc281b12e30072c9f5b7c7
parent a512a9b9
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -6776,9 +6776,8 @@
        </activity>

        <activity android:name="com.android.server.logcat.LogAccessDialogActivity"
                  android:theme="@style/Theme.DeviceDefault.Dialog.Alert.DayNight"
                  android:theme="@style/Theme.Translucent.NoTitleBar"
                  android:excludeFromRecents="true"
                  android:label="@string/log_access_confirmation_title"
                  android:exported="false">
        </activity>

+92 −67
Original line number Diff line number Diff line
@@ -16,12 +16,19 @@

package com.android.server.logcat;

import static com.android.server.logcat.LogcatManagerService.EXTRA_FD;
import static com.android.server.logcat.LogcatManagerService.EXTRA_GID;
import static com.android.server.logcat.LogcatManagerService.EXTRA_PID;
import static com.android.server.logcat.LogcatManagerService.EXTRA_UID;

import android.annotation.StyleRes;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
@@ -30,7 +37,9 @@ import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.logcat.ILogcatManagerService;
import android.util.Slog;
import android.view.ContextThemeWrapper;
import android.view.InflateException;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
@@ -43,45 +52,57 @@ import com.android.internal.R;
public class LogAccessDialogActivity extends Activity implements
        View.OnClickListener {
    private static final String TAG = LogAccessDialogActivity.class.getSimpleName();
    private Context mContext;

    private static final int DIALOG_TIME_OUT = Build.IS_DEBUGGABLE ? 60000 : 300000;
    private static final int MSG_DISMISS_DIALOG = 0;

    private final ILogcatManagerService mLogcatManagerService =
            ILogcatManagerService.Stub.asInterface(ServiceManager.getService("logcat"));

    private String mPackageName;

    private int mUid;
    private int mGid;
    private int mPid;
    private int mFd;

    private String mAlertTitle;
    private AlertDialog.Builder mAlertDialog;
    private AlertDialog mAlert;
    private View mAlertView;

    private static final int DIALOG_TIME_OUT = Build.IS_DEBUGGABLE ? 60000 : 300000;
    private static final int MSG_DISMISS_DIALOG = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        try {
            mContext = this;

        // retrieve Intent extra information
            Intent intent = getIntent();
            getIntentInfo(intent);
        if (!readIntentInfo(getIntent())) {
            Slog.e(TAG, "Invalid Intent extras, finishing");
            finish();
            return;
        }

        // retrieve the title string from passed intent extra
            mAlertTitle = getTitleString(mContext, mPackageName, mUid);
        try {
            mAlertTitle = getTitleString(this, mPackageName, mUid);
        } catch (NameNotFoundException e) {
            Slog.e(TAG, "Unable to fetch label of package " + mPackageName, e);
            declineLogAccess();
            finish();
            return;
        }

            // creaet View
            mAlertView = createView();
        // create View
        boolean isDarkTheme = (getResources().getConfiguration().uiMode
                & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
        int themeId = isDarkTheme ? android.R.style.Theme_DeviceDefault_Dialog_Alert :
                android.R.style.Theme_DeviceDefault_Light_Dialog_Alert;
        mAlertView = createView(themeId);

        // create AlertDialog
            mAlertDialog = new AlertDialog.Builder(this);
        mAlertDialog = new AlertDialog.Builder(this, themeId);
        mAlertDialog.setView(mAlertView);
        mAlertDialog.setOnCancelListener(dialog -> declineLogAccess());
        mAlertDialog.setOnDismissListener(dialog -> finish());

        // show Alert
        mAlert = mAlertDialog.create();
@@ -89,15 +110,6 @@ public class LogAccessDialogActivity extends Activity implements

        // set Alert Timeout
        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);
            }
        }
    }

    @Override
@@ -109,21 +121,44 @@ public class LogAccessDialogActivity extends Activity implements
        mAlert = null;
    }

    private void getIntentInfo(Intent intent) throws Exception {

    private boolean readIntentInfo(Intent intent) {
        if (intent == null) {
            throw new NullPointerException("Intent is null");
            Slog.e(TAG, "Intent is null");
            return false;
        }

        mPackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
        if (mPackageName == null || mPackageName.length() == 0) {
            throw new NullPointerException("Package Name is null");
            Slog.e(TAG, "Missing package name extra");
            return false;
        }

        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);
        if (!intent.hasExtra(EXTRA_UID)) {
            Slog.e(TAG, "Missing EXTRA_UID");
            return false;
        }

        if (!intent.hasExtra(EXTRA_GID)) {
            Slog.e(TAG, "Missing EXTRA_GID");
            return false;
        }

        if (!intent.hasExtra(EXTRA_PID)) {
            Slog.e(TAG, "Missing EXTRA_PID");
            return false;
        }

        if (!intent.hasExtra(EXTRA_FD)) {
            Slog.e(TAG, "Missing EXTRA_FD");
            return false;
        }

        mUid = intent.getIntExtra(EXTRA_UID, 0);
        mGid = intent.getIntExtra(EXTRA_GID, 0);
        mPid = intent.getIntExtra(EXTRA_PID, 0);
        mFd = intent.getIntExtra(EXTRA_FD, 0);

        return true;
    }

    private Handler mHandler = new Handler() {
@@ -133,11 +168,7 @@ public class LogAccessDialogActivity extends Activity implements
                    if (mAlert != null) {
                        mAlert.dismiss();
                        mAlert = null;
                        try {
                            mLogcatManagerService.decline(mUid, mGid, mPid, mFd);
                        } catch (RemoteException e) {
                            Slog.e(TAG, "Fails to call remote functions", e);
                        }
                        declineLogAccess();
                    }
                    break;

@@ -148,25 +179,15 @@ public class LogAccessDialogActivity extends Activity implements
    };

    private String getTitleString(Context context, String callingPackage, int uid)
            throws Exception {

            throws NameNotFoundException {
        PackageManager pm = context.getPackageManager();
        if (pm == null) {
            throw new NullPointerException("PackageManager is null");
        }

        CharSequence appLabel = pm.getApplicationInfoAsUser(callingPackage,
                PackageManager.MATCH_DIRECT_BOOT_AUTO,
                UserHandle.getUserId(uid)).loadLabel(pm);
        if (appLabel == null || appLabel.length() == 0) {
            throw new NameNotFoundException("Application Label is null");
        }

        String titleString = context.getString(
                com.android.internal.R.string.log_access_confirmation_title, appLabel);
        if (titleString == null || titleString.length() == 0) {
            throw new NullPointerException("Title is null");
        }

        return titleString;
    }
@@ -176,9 +197,9 @@ public class LogAccessDialogActivity extends Activity implements
     * 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(
    private View createView(@StyleRes int themeId) {
        Context themedContext = new ContextThemeWrapper(getApplicationContext(), themeId);
        final View view = LayoutInflater.from(themedContext).inflate(
                R.layout.log_access_user_consent_dialog_permission, null /*root*/);

        if (view == null) {
@@ -210,13 +231,17 @@ public class LogAccessDialogActivity extends Activity implements
                finish();
                break;
            case R.id.log_access_dialog_deny_button:
                declineLogAccess();
                finish();
                break;
        }
    }

    private void declineLogAccess() {
        try {
            mLogcatManagerService.decline(mUid, mGid, mPid, mFd);
        } catch (RemoteException e) {
            Slog.e(TAG, "Fails to call remote functions", e);
        }
                finish();
                break;
        }
    }
}
+6 −22
Original line number Diff line number Diff line
@@ -16,10 +16,8 @@

package com.android.server.logcat;

import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -42,22 +40,16 @@ import java.util.concurrent.Executors;
 * Service responsible for managing the access to Logcat.
 */
public final class LogcatManagerService extends SystemService {

    private static final String TAG = "LogcatManagerService";
    static final String EXTRA_UID = "com.android.server.logcat.uid";
    static final String EXTRA_GID = "com.android.server.logcat.gid";
    static final String EXTRA_PID = "com.android.server.logcat.pid";
    static final String EXTRA_FD = "com.android.server.logcat.fd";

    private final Context mContext;
    private final BinderService mBinderService;
    private final ExecutorService mThreadExecutor;
    private ILogd mLogdService;
    private @NonNull ActivityManager mActivityManager;
    private ActivityManagerInternal mActivityManagerInternal;
    private static final int MAX_UID_IMPORTANCE_COUNT_LISTENER = 2;
    private static final String TARGET_PACKAGE_NAME = "android";
    private static final String TARGET_ACTIVITY_NAME =
            "com.android.server.logcat.LogAccessDialogActivity";
    private static final String EXTRA_UID = "com.android.server.logcat.uid";
    private static final String EXTRA_GID = "com.android.server.logcat.gid";
    private static final String EXTRA_PID = "com.android.server.logcat.pid";
    private static final String EXTRA_FD = "com.android.server.logcat.fd";

    private final class BinderService extends ILogcatManagerService.Stub {
        @Override
@@ -153,11 +145,6 @@ public final class LogcatManagerService extends SystemService {
        }
    }

    private static String getClientInfo(int uid, int gid, int pid, int fd) {
        return "UID=" + Integer.toString(uid) + " GID=" + Integer.toString(gid) + " PID="
                + Integer.toString(pid) + " FD=" + Integer.toString(fd);
    }

    private class LogdMonitor implements Runnable {

        private final int mUid;
@@ -232,7 +219,6 @@ public final class LogcatManagerService extends SystemService {
        mContext = context;
        mBinderService = new BinderService();
        mThreadExecutor = Executors.newCachedThreadPool();
        mActivityManager = context.getSystemService(ActivityManager.class);
    }

    @Override
@@ -252,7 +238,7 @@ public final class LogcatManagerService extends SystemService {
     * Create the Intent for LogAccessDialogActivity.
     */
    public Intent createIntent(String targetPackageName, int uid, int gid, int pid, int fd) {
        final Intent intent = new Intent();
        final Intent intent = new Intent(mContext, LogAccessDialogActivity.class);

        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

@@ -262,8 +248,6 @@ public final class LogcatManagerService extends SystemService {
        intent.putExtra(EXTRA_PID, pid);
        intent.putExtra(EXTRA_FD, fd);

        intent.setComponent(new ComponentName(TARGET_PACKAGE_NAME, TARGET_ACTIVITY_NAME));

        return intent;
    }
}