diff options
Diffstat (limited to 'services/java/com')
14 files changed, 115 insertions, 23 deletions
diff --git a/services/java/com/android/server/am/ActiveServices.java b/services/java/com/android/server/am/ActiveServices.java index 1269433..7e3fdbd 100644 --- a/services/java/com/android/server/am/ActiveServices.java +++ b/services/java/com/android/server/am/ActiveServices.java @@ -1850,7 +1850,7 @@ public class ActiveServices { } if (anrMessage != null) { - mAm.appNotResponding(proc, null, null, anrMessage); + mAm.appNotResponding(proc, null, null, false, anrMessage); } } diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index e90eef9..3ef6767 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -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()"); diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java index 6cd86fd..b9f5b5b 100644 --- a/services/java/com/android/server/am/ActivityRecord.java +++ b/services/java/com/android/server/am/ActivityRecord.java @@ -841,6 +841,7 @@ final class ActivityRecord { } public boolean keyDispatchingTimedOut() { + // TODO: Unify this code with ActivityManagerService.inputDispatchingTimedOut(). ActivityRecord r; ProcessRecord anrApp = null; synchronized(service) { @@ -869,8 +870,7 @@ final class ActivityRecord { } if (anrApp != null) { - service.appNotResponding(anrApp, r, this, - "keyDispatchingTimedOut"); + service.appNotResponding(anrApp, r, this, false, "keyDispatchingTimedOut"); } return true; diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index 90a7abc..a6dc867 100755 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -2436,8 +2436,8 @@ final class ActivityStack { if (err == ActivityManager.START_SUCCESS) { final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0; - Slog.i(TAG, "START {" + intent.toShortString(true, true, true, false) - + " u=" + userId + "} from pid " + (callerApp != null ? callerApp.pid : callingPid)); + Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false) + + "} from pid " + (callerApp != null ? callerApp.pid : callingPid)); } ActivityRecord sourceRecord = null; diff --git a/services/java/com/android/server/am/AppErrorDialog.java b/services/java/com/android/server/am/AppErrorDialog.java index 0ebbe3b..a9c77fc 100644 --- a/services/java/com/android/server/am/AppErrorDialog.java +++ b/services/java/com/android/server/am/AppErrorDialog.java @@ -23,12 +23,9 @@ import android.content.DialogInterface; import android.content.res.Resources; import android.os.Handler; import android.os.Message; -import android.util.Slog; import android.view.WindowManager; class AppErrorDialog extends BaseErrorDialog { - private final static String TAG = "AppErrorDialog"; - private final ActivityManagerService mService; private final AppErrorResult mResult; private final ProcessRecord mProc; @@ -76,7 +73,9 @@ class AppErrorDialog extends BaseErrorDialog { setTitle(res.getText(com.android.internal.R.string.aerr_title)); getWindow().addFlags(FLAG_SYSTEM_ERROR); - getWindow().setTitle("Application Error: " + app.info.processName); + WindowManager.LayoutParams attrs = getWindow().getAttributes(); + attrs.setTitle("Application Error: " + app.info.processName); + getWindow().setAttributes(attrs); if (app.persistent) { getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); } diff --git a/services/java/com/android/server/am/AppNotRespondingDialog.java b/services/java/com/android/server/am/AppNotRespondingDialog.java index b546ae7..58e533b 100644 --- a/services/java/com/android/server/am/AppNotRespondingDialog.java +++ b/services/java/com/android/server/am/AppNotRespondingDialog.java @@ -25,8 +25,8 @@ import android.content.Intent; import android.content.res.Resources; import android.os.Handler; import android.os.Message; -import android.os.Process; import android.util.Slog; +import android.view.WindowManager; class AppNotRespondingDialog extends BaseErrorDialog { private static final String TAG = "AppNotRespondingDialog"; @@ -40,7 +40,7 @@ class AppNotRespondingDialog extends BaseErrorDialog { private final ProcessRecord mProc; public AppNotRespondingDialog(ActivityManagerService service, Context context, - ProcessRecord app, ActivityRecord activity) { + ProcessRecord app, ActivityRecord activity, boolean aboveSystem) { super(context); mService = service; @@ -91,8 +91,13 @@ class AppNotRespondingDialog extends BaseErrorDialog { } setTitle(res.getText(com.android.internal.R.string.anr_title)); + if (aboveSystem) { + getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); + } getWindow().addFlags(FLAG_SYSTEM_ERROR); - getWindow().setTitle("Application Not Responding: " + app.info.processName); + WindowManager.LayoutParams attrs = getWindow().getAttributes(); + attrs.setTitle("Application Not Responding: " + app.info.processName); + getWindow().setAttributes(attrs); } public void onStop() { diff --git a/services/java/com/android/server/am/AppWaitingForDebuggerDialog.java b/services/java/com/android/server/am/AppWaitingForDebuggerDialog.java index 9fb48b3..d08bb10 100644 --- a/services/java/com/android/server/am/AppWaitingForDebuggerDialog.java +++ b/services/java/com/android/server/am/AppWaitingForDebuggerDialog.java @@ -20,6 +20,7 @@ import android.content.Context; import android.content.DialogInterface; import android.os.Handler; import android.os.Message; +import android.view.WindowManager; class AppWaitingForDebuggerDialog extends BaseErrorDialog { final ActivityManagerService mService; @@ -52,7 +53,9 @@ class AppWaitingForDebuggerDialog extends BaseErrorDialog { setMessage(text.toString()); setButton(DialogInterface.BUTTON_POSITIVE, "Force Close", mHandler.obtainMessage(1, app)); setTitle("Waiting For Debugger"); - getWindow().setTitle("Waiting For Debugger: " + app.info.processName); + WindowManager.LayoutParams attrs = getWindow().getAttributes(); + attrs.setTitle("Waiting For Debugger: " + app.info.processName); + getWindow().setAttributes(attrs); } public void onStop() { diff --git a/services/java/com/android/server/am/BaseErrorDialog.java b/services/java/com/android/server/am/BaseErrorDialog.java index d1e89bc..6ede8f8 100644 --- a/services/java/com/android/server/am/BaseErrorDialog.java +++ b/services/java/com/android/server/am/BaseErrorDialog.java @@ -33,7 +33,9 @@ class BaseErrorDialog extends AlertDialog { getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); - getWindow().setTitle("Error Dialog"); + WindowManager.LayoutParams attrs = getWindow().getAttributes(); + attrs.setTitle("Error Dialog"); + getWindow().setAttributes(attrs); setIconAttribute(R.attr.alertDialogIcon); } diff --git a/services/java/com/android/server/am/BroadcastQueue.java b/services/java/com/android/server/am/BroadcastQueue.java index 9f27994..95c22ec 100644 --- a/services/java/com/android/server/am/BroadcastQueue.java +++ b/services/java/com/android/server/am/BroadcastQueue.java @@ -151,7 +151,7 @@ public class BroadcastQueue { @Override public void run() { - mService.appNotResponding(mApp, null, null, mAnnotation); + mService.appNotResponding(mApp, null, null, false, mAnnotation); } } diff --git a/services/java/com/android/server/am/FactoryErrorDialog.java b/services/java/com/android/server/am/FactoryErrorDialog.java index b19bb5c..0ffb588 100644 --- a/services/java/com/android/server/am/FactoryErrorDialog.java +++ b/services/java/com/android/server/am/FactoryErrorDialog.java @@ -20,6 +20,7 @@ import android.content.Context; import android.content.DialogInterface; import android.os.Handler; import android.os.Message; +import android.view.WindowManager; class FactoryErrorDialog extends BaseErrorDialog { public FactoryErrorDialog(Context context, CharSequence msg) { @@ -30,7 +31,9 @@ class FactoryErrorDialog extends BaseErrorDialog { setButton(DialogInterface.BUTTON_POSITIVE, context.getText(com.android.internal.R.string.factorytest_reboot), mHandler.obtainMessage(0)); - getWindow().setTitle("Factory Error"); + WindowManager.LayoutParams attrs = getWindow().getAttributes(); + attrs.setTitle("Factory Error"); + getWindow().setAttributes(attrs); } public void onStop() { diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java index 652fdb5..7fbab04 100644 --- a/services/java/com/android/server/am/ProcessRecord.java +++ b/services/java/com/android/server/am/ProcessRecord.java @@ -407,7 +407,7 @@ class ProcessRecord { sb.append('u'); sb.append(userId); sb.append('a'); - sb.append(info.uid%Process.FIRST_APPLICATION_UID); + sb.append(UserHandle.getAppId(info.uid)); if (uid != info.uid) { sb.append('i'); sb.append(UserHandle.getAppId(uid) - Process.FIRST_ISOLATED_UID); diff --git a/services/java/com/android/server/wm/InputMonitor.java b/services/java/com/android/server/wm/InputMonitor.java index 61310ca..d966001 100644 --- a/services/java/com/android/server/wm/InputMonitor.java +++ b/services/java/com/android/server/wm/InputMonitor.java @@ -21,6 +21,7 @@ import com.android.server.input.InputApplicationHandle; import com.android.server.input.InputWindowHandle; import com.android.server.wm.WindowManagerService.AllWindowsIterator; +import android.app.ActivityManagerNative; import android.graphics.Rect; import android.os.RemoteException; import android.util.Log; @@ -89,8 +90,9 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks { public long notifyANR(InputApplicationHandle inputApplicationHandle, InputWindowHandle inputWindowHandle) { AppWindowToken appWindowToken = null; + WindowState windowState = null; + boolean aboveSystem = false; synchronized (mService.mWindowMap) { - WindowState windowState = null; if (inputWindowHandle != null) { windowState = (WindowState) inputWindowHandle.windowState; if (windowState != null) { @@ -104,6 +106,12 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks { if (windowState != null) { Slog.i(WindowManagerService.TAG, "Input event dispatching timed out " + "sending to " + windowState.mAttrs.getTitle()); + // Figure out whether this window is layered above system windows. + // We need to do this here to help the activity manager know how to + // layer its ANR dialog. + int systemAlertLayer = mService.mPolicy.windowTypeToLayerLw( + WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); + aboveSystem = windowState.mBaseLayer > systemAlertLayer; } else if (appWindowToken != null) { Slog.i(WindowManagerService.TAG, "Input event dispatching timed out " + "sending to application " + appWindowToken.stringName); @@ -126,6 +134,19 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks { } } catch (RemoteException ex) { } + } else if (windowState != null) { + try { + // Notify the activity manager about the timeout and let it decide whether + // to abort dispatching or keep waiting. + long timeout = ActivityManagerNative.getDefault().inputDispatchingTimedOut( + windowState.mSession.mPid, aboveSystem); + if (timeout >= 0) { + // The activity manager declined to abort dispatching. + // Wait a bit longer and timeout again later. + return timeout; + } + } catch (RemoteException ex) { + } } return 0; // abort dispatching } diff --git a/services/java/com/android/server/wm/Session.java b/services/java/com/android/server/wm/Session.java index d84a52b..3b4c1ab 100644 --- a/services/java/com/android/server/wm/Session.java +++ b/services/java/com/android/server/wm/Session.java @@ -30,8 +30,10 @@ import android.os.Binder; import android.os.Bundle; import android.os.IBinder; import android.os.Parcel; +import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; +import android.os.UserHandle; import android.util.Slog; import android.view.Display; import android.view.IWindow; @@ -69,8 +71,17 @@ final class Session extends IWindowSession.Stub StringBuilder sb = new StringBuilder(); sb.append("Session{"); sb.append(Integer.toHexString(System.identityHashCode(this))); - sb.append(" uid "); - sb.append(mUid); + sb.append(" "); + sb.append(mPid); + if (mUid < Process.FIRST_APPLICATION_UID) { + sb.append(":"); + sb.append(mUid); + } else { + sb.append(":u"); + sb.append(UserHandle.getUserId(mUid)); + sb.append('a'); + sb.append(UserHandle.getAppId(mUid)); + } sb.append("}"); mStringName = sb.toString(); diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java index 9963d14..d23448b 100644 --- a/services/java/com/android/server/wm/WindowState.java +++ b/services/java/com/android/server/wm/WindowState.java @@ -1219,7 +1219,8 @@ final class WindowState implements WindowManagerPolicy.WindowState { mLastTitle = mAttrs.getTitle(); mWasPaused = mToken.paused; mStringNameCache = "Window{" + Integer.toHexString(System.identityHashCode(this)) - + " " + mLastTitle + " paused=" + mWasPaused + "}"; + + " u" + UserHandle.getUserId(mSession.mUid) + + " " + mLastTitle + (mWasPaused ? " PAUSED}" : "}"); } return mStringNameCache; } |
