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);
  }
Esempio n. 6
0
  @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);
 }
Esempio n. 14
0
  /** ** 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);
 }