void handleShowAnrUi(Message msg) { Dialog d = null; synchronized (mService) { HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; ProcessRecord proc = (ProcessRecord) data.get("app"); if (proc != null && proc.anrDialog != null) { Slog.e(TAG, "App already has anr dialog: " + proc); MetricsLogger.action( mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR, AppNotRespondingDialog.ALREADY_SHOWING); return; } Intent intent = new Intent("android.intent.action.ANR"); if (!mService.mProcessesReady) { intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND); } mService.broadcastIntentLocked( null, null, intent, null, null, 0, null, null, null, AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); if (mService.canShowErrorDialogs()) { d = new AppNotRespondingDialog( mService, mContext, proc, (ActivityRecord) data.get("activity"), msg.arg1 != 0); proc.anrDialog = d; } else { MetricsLogger.action( mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR, AppNotRespondingDialog.CANT_SHOW); // Just kill the app if there is no dialog to be shown. mService.killAppAtUsersRequest(proc, null); } } // If we've created a crash dialog, show it without the lock held if (d != null) { d.show(); } }
@Override public void setToggleState(boolean state) { if (DEBUG) Log.d(TAG, "setToggleState " + state); MetricsLogger.action(mContext, MetricsLogger.QS_WIFI_TOGGLE, state); mController.setWifiEnabled(state); showDetail(false); }
@Override protected void handleClick() { if (mController == null) return; MetricsLogger.action(mContext, getMetricsCategory(), !mState.value); final boolean newState = !mState.value; mController.setRotationLocked(newState); refreshState(newState ? UserBoolean.USER_TRUE : UserBoolean.USER_FALSE); }
/** Called when the user clicked the notification in the UI. */ public synchronized void registerClickedByUser(NotificationRecord notification) { MetricsLogger.histogram( mContext, "note_click_longevity", (int) (System.currentTimeMillis() - notification.getRankingTimeMs()) / (60 * 1000)); notification.stats.onClick(); if (ENABLE_SQLITE_LOG) { mSQLiteLog.logClicked(notification); } }
@Override public void showPrevAffiliatedTask() { // Ensure the device has been provisioned before allowing the user to interact with // recents if (!isDeviceProvisioned()) { return; } // Keep track of when the affiliated task is triggered MetricsLogger.count(mContext, "overview_affiliated_task_prev", 1); showRelativeAffiliatedTask(false); }
@Override public void onAllTaskViewsDismissed(ArrayList<Task> removedTasks) { if (removedTasks != null) { int taskCount = removedTasks.size(); for (int i = 0; i < taskCount; i++) { onTaskViewDismissed(removedTasks.get(i)); } } mCb.onAllTaskViewsDismissed(); // Keep track of all-deletions MetricsLogger.count(getContext(), "overview_task_all_dismissed", 1); }
void crashApplicationInner(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { long timeMillis = System.currentTimeMillis(); String shortMsg = crashInfo.exceptionClassName; String longMsg = crashInfo.exceptionMessage; String stackTrace = crashInfo.stackTrace; if (shortMsg != null && longMsg != null) { longMsg = shortMsg + ": " + longMsg; } else if (shortMsg != null) { longMsg = shortMsg; } AppErrorResult result = new AppErrorResult(); TaskRecord task; synchronized (mService) { /** * If crash is handled by instance of {@link android.app.IActivityController}, finish now and * don't show the app error dialog. */ if (handleAppCrashInActivityController( r, crashInfo, shortMsg, longMsg, stackTrace, timeMillis)) { return; } /** * If this process was running instrumentation, finish now - it will be handled in {@link * ActivityManagerService#handleAppDiedLocked}. */ if (r != null && r.instrumentationClass != null) { return; } // Log crash in battery stats. if (r != null) { mService.mBatteryStatsService.noteProcessCrash(r.processName, r.uid); } AppErrorDialog.Data data = new AppErrorDialog.Data(); data.result = result; data.proc = r; // If we can't identify the process or it's already exceeded its crash quota, // quit right away without showing a crash dialog. if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace, data)) { return; } Message msg = Message.obtain(); msg.what = ActivityManagerService.SHOW_ERROR_UI_MSG; task = data.task; msg.obj = data; mService.mUiHandler.sendMessage(msg); } int res = result.get(); Intent appErrorIntent = null; MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_CRASH, res); if (res == AppErrorDialog.TIMEOUT || res == AppErrorDialog.CANCEL) { res = AppErrorDialog.FORCE_QUIT; } synchronized (mService) { if (res == AppErrorDialog.MUTE) { stopReportingCrashesLocked(r); } if (res == AppErrorDialog.RESTART) { mService.removeProcessLocked(r, false, true, "crash"); if (task != null) { try { mService.startActivityFromRecents(task.taskId, ActivityOptions.makeBasic().toBundle()); } catch (IllegalArgumentException e) { // Hmm, that didn't work, app might have crashed before creating a // recents entry. Let's see if we have a safe-to-restart intent. if (task.intent.getCategories().contains(Intent.CATEGORY_LAUNCHER)) { mService.startActivityInPackage( task.mCallingUid, task.mCallingPackage, task.intent, null, null, null, 0, 0, ActivityOptions.makeBasic().toBundle(), task.userId, null, null); } } } } if (res == AppErrorDialog.FORCE_QUIT) { long orig = Binder.clearCallingIdentity(); try { // Kill it with fire! mService.mStackSupervisor.handleAppCrashLocked(r); if (!r.persistent) { mService.removeProcessLocked(r, false, false, "crash"); mService.mStackSupervisor.resumeFocusedStackTopActivityLocked(); } } finally { Binder.restoreCallingIdentity(orig); } } if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); } if (r != null && !r.isolated && res != AppErrorDialog.RESTART) { // XXX Can't keep track of crash time for isolated processes, // since they don't have a persistent identity. mProcessCrashTimes.put(r.info.processName, r.uid, SystemClock.uptimeMillis()); } } if (appErrorIntent != null) { try { mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); } catch (ActivityNotFoundException e) { Slog.w(TAG, "bug report receiver dissappeared", e); } } }
@Override protected void handleClick() { final boolean isEnabled = (Boolean) mState.value; MetricsLogger.action(mContext, getMetricsCategory(), !isEnabled); mController.setBluetoothEnabled(!isEnabled); }
@Override public void setToggleState(boolean state) { MetricsLogger.action(mContext, MetricsLogger.QS_BLUETOOTH_TOGGLE, state); mController.setBluetoothEnabled(state); fireToggleStateChanged(state); }
void maybeCount(String name, int value) { if (value > 0) { MetricsLogger.count(mContext, name, value); } }
@Override public void handleClick() { MetricsLogger.action(mContext, getMetricsCategory(), !mState.value); setEnabled(!mState.value); }
@Override protected void handleClick() { mState.copyTo(mStateBeforeClick); MetricsLogger.action(mContext, getMetricsCategory(), !mState.enabled); mController.setWifiEnabled(!mState.enabled); }
@Override public void onPause() { super.onPause(); MetricsLogger.visibility(getContext(), MetricsEvent.TUNER_POWER_NOTIFICATION_CONTROLS, false); }
/** ** TaskStackView.TaskStackCallbacks Implementation *** */ @Override public void onTaskViewClicked( final TaskStackView stackView, final TaskView tv, final TaskStack stack, final Task task, final boolean lockToTask) { Log.d(TAG, "onTaskViewClicked: "); // Notify any callbacks of the launching of a new task if (mCb != null) { mCb.onTaskViewClicked(); } // Upfront the processing of the thumbnail TaskViewTransform transform = new TaskViewTransform(); View sourceView; int offsetX = 0; int offsetY = 0; float stackScroll = stackView.getScroller().getStackScroll(); if (tv == null) { // If there is no actual task view, then use the stack view as the source view // and then offset to the expected transform rect, but bound this to just // outside the display rect (to ensure we don't animate from too far away) sourceView = stackView; transform = stackView.getStackAlgorithm().getStackTransform(task, stackScroll, transform, null); offsetX = transform.rect.left; offsetY = mConfig.displayRect.height(); } else { sourceView = tv.mThumbnailView; transform = stackView.getStackAlgorithm().getStackTransform(task, stackScroll, transform, null); } // Compute the thumbnail to scale up from final SystemServicesProxy ssp = RecentsTaskLoader.getInstance().getSystemServicesProxy(); ActivityOptions opts = null; if (task.thumbnail != null && task.thumbnail.getWidth() > 0 && task.thumbnail.getHeight() > 0) { ActivityOptions.OnAnimationStartedListener animStartedListener = null; if (lockToTask) { animStartedListener = new ActivityOptions.OnAnimationStartedListener() { boolean mTriggered = false; @Override public void onAnimationStarted() { if (!mTriggered) { postDelayed( new Runnable() { @Override public void run() { mCb.onScreenPinningRequest(); } }, 350); mTriggered = true; } } }; } if (tv != null) { postDrawHeaderThumbnailTransitionRunnable( tv, offsetX, offsetY, transform, animStartedListener); } if (mConfig.multiStackEnabled) { opts = ActivityOptions.makeCustomAnimation( sourceView.getContext(), R.anim.recents_from_unknown_enter, R.anim.recents_from_unknown_exit, sourceView.getHandler(), animStartedListener); } else { opts = ActivityOptions.makeThumbnailAspectScaleUpAnimation( sourceView, Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8).createAshmemBitmap(), offsetX, offsetY, transform.rect.width(), transform.rect.height(), sourceView.getHandler(), animStartedListener); } } final ActivityOptions launchOpts = opts; final Runnable launchRunnable = new Runnable() { @Override public void run() { if (task.isActive) { // Bring an active task to the foreground ssp.moveTaskToFront(task.key.id, launchOpts); } else { if (ssp.startActivityFromRecents( getContext(), task.key.id, task.activityLabel, launchOpts)) { if (launchOpts == null && lockToTask) { mCb.onScreenPinningRequest(); } } else { // Dismiss the task and return the user to home if we fail to // launch the task onTaskViewDismissed(task); if (mCb != null) { mCb.onTaskLaunchFailed(); } // Keep track of failed launches MetricsLogger.count(getContext(), "overview_task_launch_failed", 1); } } } }; // Keep track of the index of the task launch int taskIndexFromFront = 0; int taskIndex = stack.indexOfTask(task); if (taskIndex > -1) { taskIndexFromFront = stack.getTaskCount() - taskIndex - 1; } MetricsLogger.histogram(getContext(), "overview_task_launch_index", taskIndexFromFront); // Launch the app right away if there is no task view, otherwise, animate the icon out first if (tv == null) { launchRunnable.run(); } else { if (task.group != null && !task.group.isFrontMostTask(task)) { // For affiliated tasks that are behind other tasks, we must animate the front cards // out of view before starting the task transition stackView.startLaunchTaskAnimation(tv, launchRunnable, lockToTask); } else { // Otherwise, we can start the task transition immediately stackView.startLaunchTaskAnimation(tv, null, lockToTask); launchRunnable.run(); } } }
void showRelativeAffiliatedTask(boolean showNextTask) { // Return early if there is no focused stack int focusedStackId = mSystemServicesProxy.getFocusedStack(); TaskStack focusedStack = null; RecentsTaskLoader loader = RecentsTaskLoader.getInstance(); RecentsTaskLoadPlan plan = loader.createLoadPlan(mContext); loader.preloadTasks(plan, true /* isTopTaskHome */); if (mConfig.multiStackEnabled) { if (focusedStackId < 0) return; focusedStack = plan.getTaskStack(focusedStackId); } else { focusedStack = plan.getAllTaskStacks().get(0); } // Return early if there are no tasks in the focused stack if (focusedStack == null || focusedStack.getTaskCount() == 0) return; ActivityManager.RunningTaskInfo runningTask = mSystemServicesProxy.getTopMostTask(); // Return early if there is no running task (can't determine affiliated tasks in this case) if (runningTask == null) return; // Return early if the running task is in the home stack (optimization) if (mSystemServicesProxy.isInHomeStack(runningTask.id)) return; // Find the task in the recents list ArrayList<Task> tasks = focusedStack.getTasks(); Task toTask = null; ActivityOptions launchOpts = null; int taskCount = tasks.size(); int numAffiliatedTasks = 0; for (int i = 0; i < taskCount; i++) { Task task = tasks.get(i); if (task.key.id == runningTask.id) { TaskGrouping group = task.group; Task.TaskKey toTaskKey; if (showNextTask) { toTaskKey = group.getNextTaskInGroup(task); launchOpts = ActivityOptions.makeCustomAnimation( mContext, R.anim.recents_launch_next_affiliated_task_target, R.anim.recents_launch_next_affiliated_task_source); } else { toTaskKey = group.getPrevTaskInGroup(task); launchOpts = ActivityOptions.makeCustomAnimation( mContext, R.anim.recents_launch_prev_affiliated_task_target, R.anim.recents_launch_prev_affiliated_task_source); } if (toTaskKey != null) { toTask = focusedStack.findTaskWithId(toTaskKey.id); } numAffiliatedTasks = group.getTaskCount(); break; } } // Return early if there is no next task if (toTask == null) { if (numAffiliatedTasks > 1) { if (showNextTask) { mSystemServicesProxy.startInPlaceAnimationOnFrontMostApplication( ActivityOptions.makeCustomInPlaceAnimation( mContext, R.anim.recents_launch_next_affiliated_task_bounce)); } else { mSystemServicesProxy.startInPlaceAnimationOnFrontMostApplication( ActivityOptions.makeCustomInPlaceAnimation( mContext, R.anim.recents_launch_prev_affiliated_task_bounce)); } } return; } // Keep track of actually launched affiliated tasks MetricsLogger.count(mContext, "overview_affiliated_task_launch", 1); // Launch the task if (toTask.isActive) { // Bring an active task to the foreground mSystemServicesProxy.moveTaskToFront(toTask.key.id, launchOpts); } else { mSystemServicesProxy.startActivityFromRecents( mContext, toTask.key.id, toTask.activityLabel, launchOpts); } }
@Override public void handleClick() { MetricsLogger.action(mContext, getMetricsCategory(), !mState.value); mProfileController.setWorkModeEnabled(!mState.value); }