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

Commit 5fe7e2a3 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Fix issue #6968859: home not exiting an ANR'd dream

Add a new call to the activity manager for the input dispatcher
to report about any pid having an ANR.  This has a new feature
where it can also tell the activity manager that it is above the
system alert layer, so the activity manager can pop its ANR dialog
on top of everything if it needs to.  (Normally we don't want
these dialogs appearing on top of the lock screen.)

Also fixed some debugging stuff here and there that was useful
as I was working on this -- windows now very clearly include
their uid, various system dialogs now have titles so you know
what they are in the window manager, etc.

Change-Id: Ib8f5d29a5572542cc506e6d338599ab64088ce4e
parent f7ee2a03
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -1772,6 +1772,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
            IUserSwitchObserver observer = IUserSwitchObserver.Stub.asInterface(
                    data.readStrongBinder());
            registerUserSwitchObserver(observer);
            reply.writeNoException();
            return true;
        }

@@ -1780,12 +1781,24 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
            IUserSwitchObserver observer = IUserSwitchObserver.Stub.asInterface(
                    data.readStrongBinder());
            unregisterUserSwitchObserver(observer);
            reply.writeNoException();
            return true;
        }

        case REQUEST_BUG_REPORT_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            requestBugReport();
            reply.writeNoException();
            return true;
        }

        case INPUT_DISPATCHING_TIMED_OUT_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            int pid = data.readInt();
            boolean aboveSystem = data.readInt() != 0;
            long res = inputDispatchingTimedOut(pid, aboveSystem);
            reply.writeNoException();
            reply.writeLong(res);
            return true;
        }

@@ -4082,5 +4095,19 @@ class ActivityManagerProxy implements IActivityManager
        reply.recycle();
    }

    public long inputDispatchingTimedOut(int pid, boolean aboveSystem) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeInt(pid);
        data.writeInt(aboveSystem ? 1 : 0);
        mRemote.transact(INPUT_DISPATCHING_TIMED_OUT_TRANSACTION, data, reply, 0);
        reply.readException();
        long res = reply.readInt();
        data.recycle();
        reply.recycle();
        return res;
    }

    private IBinder mRemote;
}
+3 −0
Original line number Diff line number Diff line
@@ -363,6 +363,8 @@ public interface IActivityManager extends IInterface {

    public void requestBugReport() throws RemoteException;

    public long inputDispatchingTimedOut(int pid, boolean aboveSystem) throws RemoteException;

    /*
     * Private non-Binder interfaces
     */
@@ -616,4 +618,5 @@ public interface IActivityManager extends IInterface {
    int UNREGISTER_USER_SWITCH_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+155;
    int GET_RUNNING_USER_IDS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+156;
    int REQUEST_BUG_REPORT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+157;
    int INPUT_DISPATCHING_TIMED_OUT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+158;
}
+3 −0
Original line number Diff line number Diff line
@@ -149,6 +149,9 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
        mDialog = createDialog();
        prepareDialog();

        WindowManager.LayoutParams attrs = mDialog.getWindow().getAttributes();
        attrs.setTitle("GlobalActions");
        mDialog.getWindow().setAttributes(attrs);
        mDialog.show();
        mDialog.getWindow().getDecorView().setSystemUiVisibility(View.STATUS_BAR_DISABLE_EXPAND);
    }
+1 −1
Original line number Diff line number Diff line
@@ -1850,7 +1850,7 @@ public class ActiveServices {
        }

        if (anrMessage != null) {
            mAm.appNotResponding(proc, null, null, anrMessage);
            mAm.appNotResponding(proc, null, null, false, anrMessage);
        }
    }

+49 −2
Original line number Diff line number Diff line
@@ -970,7 +970,8 @@ public final class ActivityManagerService extends ActivityManagerNative
                    if (mShowDialogs) {
                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
                                mContext, proc, (ActivityRecord)data.get("activity"));
                                mContext, proc, (ActivityRecord)data.get("activity"),
                                msg.arg1 != 0);
                        d.show();
                        proc.anrDialog = d;
                    } else {
@@ -3247,7 +3248,7 @@ public final class ActivityManagerService extends ActivityManagerNative
    }
    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
            ActivityRecord parent, final String annotation) {
            ActivityRecord parent, boolean aboveSystem, final String annotation) {
        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
@@ -3388,6 +3389,7 @@ public final class ActivityManagerService extends ActivityManagerNative
            HashMap map = new HashMap();
            msg.what = SHOW_NOT_RESPONDING_MSG;
            msg.obj = map;
            msg.arg1 = aboveSystem ? 1 : 0;
            map.put("app", app);
            if (activity != null) {
                map.put("activity", activity);
@@ -7340,6 +7342,51 @@ public final class ActivityManagerService extends ActivityManagerNative
        SystemProperties.set("ctl.start", "bugreport");
    }
    public long inputDispatchingTimedOut(int pid, boolean aboveSystem) {
        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Requires permission "
                    + android.Manifest.permission.FILTER_EVENTS);
        }
        ProcessRecord proc;
        // TODO: Unify this code with ActivityRecord.keyDispatchingTimedOut().
        synchronized (this) {
            synchronized (mPidsSelfLocked) {
                proc = mPidsSelfLocked.get(pid);
            }
            if (proc != null) {
                if (proc.debugging) {
                    return -1;
                }
                if (mDidDexOpt) {
                    // Give more time since we were dexopting.
                    mDidDexOpt = false;
                    return -1;
                }
                if (proc.instrumentationClass != null) {
                    Bundle info = new Bundle();
                    info.putString("shortMsg", "keyDispatchingTimedOut");
                    info.putString("longMsg", "Timed out while dispatching key event");
                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
                    proc = null;
                }
            }
        }
        if (proc != null) {
            appNotResponding(proc, null, null, aboveSystem, "keyDispatchingTimedOut");
            if (proc.instrumentationClass != null || proc.usingWrapper) {
                return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
            }
        }
        return KEY_DISPATCHING_TIMEOUT;
    }
    public void registerProcessObserver(IProcessObserver observer) {
        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
                "registerProcessObserver()");
Loading