예제 #1
0
  private static boolean killForegroundAppInternal(Context context, int userId)
      throws RemoteException {
    final IActivityManager am = ActivityManagerNative.getDefault();
    String defaultHomePackage = resolveCurrentLauncherPackage(context, userId);

    for (ActivityManager.RunningAppProcessInfo appInfo : am.getRunningAppProcesses()) {
      // Make sure it's a foreground user application (not system, root, phone, etc.)
      int uid = appInfo.uid, importance = appInfo.importance;
      if (uid < Process.FIRST_APPLICATION_UID
          || uid > Process.LAST_APPLICATION_UID
          || importance != ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
        continue;
      }

      if (appInfo.pkgList != null && appInfo.pkgList.length > 0) {
        for (String pkg : appInfo.pkgList) {
          if (!pkg.equals(SYSTEMUI_PACKAGE) && !pkg.equals(defaultHomePackage)) {
            am.forceStopPackage(pkg, userId);
            return true;
          }
        }
      } else {
        Process.killProcess(appInfo.pid);
        return true;
      }
    }

    return false;
  }
  /** Instantiates the clipboard. */
  public ClipboardService(Context context) {
    mContext = context;
    mAm = ActivityManagerNative.getDefault();
    mPm = context.getPackageManager();
    mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
    IBinder permOwner = null;
    try {
      permOwner = mAm.newUriPermissionOwner("clipboard");
    } catch (RemoteException e) {
      Slog.w("clipboard", "AM dead", e);
    }
    mPermissionOwner = permOwner;

    // Remove the clipboard if a user is removed
    IntentFilter userFilter = new IntentFilter();
    userFilter.addAction(Intent.ACTION_USER_REMOVED);
    mContext.registerReceiver(
        new BroadcastReceiver() {
          @Override
          public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (Intent.ACTION_USER_REMOVED.equals(action)) {
              removeClipboard(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
            }
          }
        },
        userFilter);
  }
  /**
   * Attach to the required system interfaces.
   *
   * @return Returns true if all system interfaces were available.
   */
  private boolean getSystemInterfaces() {
    mAm = ActivityManagerNative.getDefault();
    if (mAm == null) {
      System.err.println(
          "** Error: Unable to connect to activity manager; is the system " + "running?");
      return false;
    }

    mWm = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
    if (mWm == null) {
      System.err.println(
          "** Error: Unable to connect to window manager; is the system " + "running?");
      return false;
    }

    mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
    if (mPm == null) {
      System.err.println(
          "** Error: Unable to connect to package manager; is the system " + "running?");
      return false;
    }

    try {
      mAm.setActivityController(new ActivityController());
      mNetworkMonitor.register(mAm);
    } catch (RemoteException e) {
      System.err.println("** Failed talking with activity manager!");
      return false;
    }

    return true;
  }
  private void runStart() {
    Intent intent = makeIntent();

    if (intent != null) {
      System.out.println("Starting: " + intent);
      try {
        intent.addFlags(intent.FLAG_ACTIVITY_NEW_TASK);
        // XXX should do something to determine the MIME type.
        int res =
            mAm.startActivity(
                null, intent, intent.getType(), null, 0, null, null, 0, false, mDebugOption);
        switch (res) {
          case IActivityManager.START_SUCCESS:
            break;
          case IActivityManager.START_CLASS_NOT_FOUND:
            System.err.println("Error type 3");
            System.err.println(
                "Error: Activity class "
                    + intent.getComponent().toShortString()
                    + " does not exist.");
            break;
          case IActivityManager.START_DELIVERED_TO_TOP:
            System.err.println(
                "Warning: Activity not started, intent has "
                    + "been delivered to currently running "
                    + "top-most instance.");
            break;
          case IActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
            System.err.println(
                "Error: Activity not started, you requested to "
                    + "both forward and receive its result");
            break;
          case IActivityManager.START_INTENT_NOT_RESOLVED:
            System.err.println(
                "Error: Activity not started, unable to " + "resolve " + intent.toString());
            break;
          case IActivityManager.START_RETURN_INTENT_TO_CALLER:
            System.err.println(
                "Warning: Activity not started because intent "
                    + "should be handled by the caller");
            break;
          case IActivityManager.START_TASK_TO_FRONT:
            System.err.println(
                "Warning: Activity not started, its current "
                    + "task has been brought to the front");
            break;
          default:
            System.err.println("Error: Activity not started, unknown error " + "code " + res);
            break;
        }
      } catch (RemoteException e) {
        System.err.println("Error type 1");
        System.err.println(
            "Error: Activity not started, unable to " + "call on to activity manager service");
      }
    }
  }
 private final void grantUriLocked(Uri uri, String pkg) {
   long ident = Binder.clearCallingIdentity();
   try {
     mAm.grantUriPermissionFromOwner(
         mPermissionOwner, Process.myUid(), pkg, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
   } catch (RemoteException e) {
   } finally {
     Binder.restoreCallingIdentity(ident);
   }
 }
  private void sendBroadcast() {
    Intent intent = makeIntent();

    if (intent != null) {
      System.out.println("Broadcasting: " + intent);
      try {
        mAm.broadcastIntent(null, intent, null, null, 0, null, null, null, true, false);
      } catch (RemoteException e) {
      }
    }
  }
예제 #7
0
  private static ActivityManager.RecentTaskInfo getLastTask(Context context, int userId)
      throws RemoteException {
    final String defaultHomePackage = resolveCurrentLauncherPackage(context, userId);
    final IActivityManager am = ActivityManagerNative.getDefault();
    final List<ActivityManager.RecentTaskInfo> tasks =
        am.getRecentTasks(5, ActivityManager.RECENT_IGNORE_UNAVAILABLE, userId);

    for (int i = 1; i < tasks.size(); i++) {
      ActivityManager.RecentTaskInfo task = tasks.get(i);
      if (task.origActivity != null) {
        task.baseIntent.setComponent(task.origActivity);
      }
      String packageName = task.baseIntent.getComponent().getPackageName();
      if (!packageName.equals(defaultHomePackage) && !packageName.equals(SYSTEMUI_PACKAGE)) {
        return tasks.get(i);
      }
    }

    return null;
  }
 private void killProcess() {
   try {
     final Intent intent = new Intent(Intent.ACTION_MAIN);
     String defaultHomePackage = "com.android.launcher";
     intent.addCategory(Intent.CATEGORY_HOME);
     final ResolveInfo res = mContext.getPackageManager().resolveActivity(intent, 0);
     if (res.activityInfo != null && !res.activityInfo.packageName.equals("android")) {
       defaultHomePackage = res.activityInfo.packageName;
     }
     boolean targetKilled = false;
     IActivityManager am = ActivityManagerNative.getDefault();
     List<RunningAppProcessInfo> apps = am.getRunningAppProcesses();
     for (RunningAppProcessInfo appInfo : apps) {
       int uid = appInfo.uid;
       // Make sure it's a foreground user application (not system,
       // root, phone, etc.)
       if (uid >= Process.FIRST_APPLICATION_UID
           && uid <= Process.LAST_APPLICATION_UID
           && appInfo.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
         if (appInfo.pkgList != null && (appInfo.pkgList.length > 0)) {
           for (String pkg : appInfo.pkgList) {
             if (!pkg.equals("com.android.systemui") && !pkg.equals(defaultHomePackage)) {
               am.forceStopPackage(pkg);
               targetKilled = true;
               break;
             }
           }
         } else {
           Process.killProcess(appInfo.pid);
           targetKilled = true;
         }
       }
       if (targetKilled) {
         Toast.makeText(mContext, R.string.app_killed_message, Toast.LENGTH_SHORT).show();
         break;
       }
     }
   } catch (RemoteException remoteException) {
     // Do nothing; just let it go.
   }
 }
 private final void revokeUriLocked(Uri uri) {
   long ident = Binder.clearCallingIdentity();
   try {
     mAm.revokeUriPermissionFromOwner(
         mPermissionOwner,
         uri,
         Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
   } catch (RemoteException e) {
   } finally {
     Binder.restoreCallingIdentity(ident);
   }
 }
  /**
   * Send SIGNAL_USR1 to all processes. This will generate large (5mb) profiling reports in
   * data/misc, so use with care.
   */
  private void signalPersistentProcesses() {
    try {
      mAm.signalPersistentProcesses(Process.SIGNAL_USR1);

      synchronized (this) {
        wait(2000);
      }
    } catch (RemoteException e) {
      System.err.println("** Failed talking with activity manager!");
    } catch (InterruptedException e) {
    }
  }
예제 #11
0
  private static boolean switchToLastAppInternal(Context context, int userId)
      throws RemoteException {
    ActivityManager.RecentTaskInfo lastTask = getLastTask(context, userId);

    if (lastTask == null || lastTask.id < 0) {
      return false;
    }

    final String packageName = lastTask.baseIntent.getComponent().getPackageName();
    final IActivityManager am = ActivityManagerNative.getDefault();
    final ActivityOptions opts =
        ActivityOptions.makeCustomAnimation(
            context,
            com.android.internal.R.anim.last_app_in,
            com.android.internal.R.anim.last_app_out);

    if (DEBUG) Log.d(TAG, "switching to " + packageName);
    sendCloseSystemWindows(context, null);
    am.moveTaskToFront(lastTask.id, ActivityManager.MOVE_TASK_NO_USER_ACTION, opts.toBundle());

    return true;
  }
 private final void checkUriOwnerLocked(Uri uri, int uid) {
   if (!"content".equals(uri.getScheme())) {
     return;
   }
   long ident = Binder.clearCallingIdentity();
   try {
     // This will throw SecurityException for us.
     mAm.checkGrantUriPermission(uid, null, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
   } catch (RemoteException e) {
   } finally {
     Binder.restoreCallingIdentity(ident);
   }
 }
예제 #13
0
  /**
   * Sets the system locale to the new one specified.
   *
   * @param locale A locale name in the form "ab_AB". Must not be null or empty.
   * @return True if the locale was succesfully changed.
   */
  public static boolean changeSystemLocale(String locale) {
    if (DEBUG) {
      Log.d(TAG, "Change locale to: " + locale);
    }

    try {
      IActivityManager am = ActivityManagerNative.getDefault();
      Configuration config = am.getConfiguration();

      Locale loc = null;

      String[] langCountry = locale.split("_");
      if (langCountry.length == 2) {
        loc = new Locale(langCountry[0], langCountry[1]);
      } else {
        loc = new Locale(locale);
      }

      config.locale = loc;

      // indicate this isn't some passing default - the user wants this
      // remembered
      config.userSetLocale = true;

      am.updateConfiguration(config);

      return true;

    } catch (RemoteException e) {
      if (DEBUG) {
        Log.e(TAG, "Change locale failed", e);
      }
    }

    return false;
  }
 // lock on mToastQueue
 private void keepProcessAliveLocked(int pid) {
   int toastCount = 0; // toasts from this pid
   ArrayList<ToastRecord> list = mToastQueue;
   int N = list.size();
   for (int i = 0; i < N; i++) {
     ToastRecord r = list.get(i);
     if (r.pid == pid) {
       toastCount++;
     }
   }
   try {
     mAm.setProcessForeground(mForegroundToken, pid, toastCount > 0);
   } catch (RemoteException e) {
     // Shouldn't happen.
   }
 }
  private void runProfile() {
    String profileFile = null;
    boolean start = false;

    String process = nextArg();
    if (process == null) {
      System.err.println("Error: No profile process supplied");
      showUsage();
      return;
    }

    String cmd = nextArg();
    if ("start".equals(cmd)) {
      start = true;
      profileFile = nextArg();
      if (profileFile == null) {
        System.err.println("Error: No profile file path supplied");
        showUsage();
        return;
      }
    } else if (!"stop".equals(cmd)) {
      System.err.println("Error: Profile command " + cmd + " not valid");
      showUsage();
      return;
    }

    try {
      if (!mAm.profileControl(process, start, profileFile)) {
        System.out.println("PROFILE FAILED on process " + process);
        return;
      }
    } catch (IllegalArgumentException e) {
      System.out.println("PROFILE FAILED: " + e.getMessage());
      return;
    } catch (IllegalStateException e) {
      System.out.println("PROFILE FAILED: " + e.getMessage());
      return;
    } catch (RemoteException e) {
      System.out.println("PROFILE FAILED: activity manager gone");
      return;
    }
  }
예제 #16
0
  /**
   * Get running process information from AMS and get the same pid , uid process.
   *
   * @param pid process id
   * @param uid user id
   * @return process record
   */
  private ProcessRecord createProcessRecordLocked(int pid, int uid) {

    ProcessRecord record = mProcessRecords.get(pid);
    if (record == null) {
      try {
        List<RunningAppProcessInfo> procInfos = mActivityManager.getRunningAppProcesses();
        if (procInfos != null && procInfos.size() > 0) {
          for (RunningAppProcessInfo info : procInfos) {
            if (info.pid == pid && info.uid == uid) {
              record = new ProcessRecord(info.pid, info.uid, info.processName);
              mProcessRecords.put(pid, record);
              break;
            }
          }
        }
      } catch (RemoteException e) {
        // TODO Auto-generated catch block
        Log.e(TAG, "IPC Exception while get process info from AMS " + e.toString());
      }
    }

    return record;
  }
예제 #17
0
  /**
   * Makes sure we handle the shutdown gracefully. Shuts off power regardless of radio and bluetooth
   * state if the alloted time has passed.
   */
  public void run() {
    BroadcastReceiver br =
        new BroadcastReceiver() {
          @Override
          public void onReceive(Context context, Intent intent) {
            // We don't allow apps to cancel this, so ignore the result.
            actionDone();
          }
        };

    /*
     * Write a system property in case the system_server reboots before we
     * get to the actual hardware restart. If that happens, we'll retry at
     * the beginning of the SystemServer startup.
     */
    {
      String reason = (mReboot ? "1" : "0") + (mRebootReason != null ? mRebootReason : "");
      SystemProperties.set(SHUTDOWN_ACTION_PROPERTY, reason);
    }

    /*
     * If we are rebooting into safe mode, write a system property
     * indicating so.
     */
    if (mRebootSafeMode) {
      SystemProperties.set(REBOOT_SAFEMODE_PROPERTY, "1");
    }

    Log.i(TAG, "Sending shutdown broadcast...");

    // First send the high-level shut down broadcast.
    mActionDone = false;
    mContext.sendOrderedBroadcastAsUser(
        new Intent(Intent.ACTION_SHUTDOWN), UserHandle.ALL, null, br, mHandler, 0, null, null);

    final long endTime = SystemClock.elapsedRealtime() + MAX_BROADCAST_TIME;
    synchronized (mActionDoneSync) {
      while (!mActionDone) {
        long delay = endTime - SystemClock.elapsedRealtime();
        if (delay <= 0) {
          Log.w(TAG, "Shutdown broadcast timed out");
          break;
        }
        try {
          mActionDoneSync.wait(delay);
        } catch (InterruptedException e) {
        }
      }
    }

    Log.i(TAG, "Shutting down activity manager...");

    final IActivityManager am =
        ActivityManagerNative.asInterface(ServiceManager.checkService("activity"));
    if (am != null) {
      try {
        am.shutdown(MAX_BROADCAST_TIME);
      } catch (RemoteException e) {
      }
    }

    // Shutdown radios.
    shutdownRadios(MAX_RADIO_WAIT_TIME);

    // Shutdown MountService to ensure media is in a safe state
    IMountShutdownObserver observer =
        new IMountShutdownObserver.Stub() {
          public void onShutDownComplete(int statusCode) throws RemoteException {
            Log.w(TAG, "Result code " + statusCode + " from MountService.shutdown");
            actionDone();
          }
        };

    Log.i(TAG, "Shutting down MountService");

    // Set initial variables and time out time.
    mActionDone = false;
    final long endShutTime = SystemClock.elapsedRealtime() + MAX_SHUTDOWN_WAIT_TIME;
    synchronized (mActionDoneSync) {
      try {
        final IMountService mount =
            IMountService.Stub.asInterface(ServiceManager.checkService("mount"));
        if (mount != null) {
          mount.shutdown(observer);
        } else {
          Log.w(TAG, "MountService unavailable for shutdown");
        }
      } catch (Exception e) {
        Log.e(TAG, "Exception during MountService shutdown", e);
      }
      while (!mActionDone) {
        long delay = endShutTime - SystemClock.elapsedRealtime();
        if (delay <= 0) {
          Log.w(TAG, "Shutdown wait timed out");
          break;
        }
        try {
          mActionDoneSync.wait(delay);
        } catch (InterruptedException e) {
        }
      }
    }

    rebootOrShutdown(mReboot, mRebootReason);
  }
  /**
   * Makes sure we handle the shutdown gracefully. Shuts off power regardless of radio and bluetooth
   * state if the alloted time has passed.
   */
  public void run() {
    boolean bluetoothOff;
    boolean radioOff;

    BroadcastReceiver br =
        new BroadcastReceiver() {
          @Override
          public void onReceive(Context context, Intent intent) {
            // We don't allow apps to cancel this, so ignore the result.
            broadcastDone();
          }
        };

    Log.i(TAG, "Sending shutdown broadcast...");

    // First send the high-level shut down broadcast.
    mBroadcastDone = false;
    mContext.sendOrderedBroadcast(
        new Intent(Intent.ACTION_SHUTDOWN), null, br, mHandler, 0, null, null);

    final long endTime = System.currentTimeMillis() + MAX_BROADCAST_TIME;
    synchronized (mBroadcastDoneSync) {
      while (!mBroadcastDone) {
        long delay = endTime - System.currentTimeMillis();
        if (delay <= 0) {
          Log.w(TAG, "Shutdown broadcast timed out");
          break;
        }
        try {
          mBroadcastDoneSync.wait(delay);
        } catch (InterruptedException e) {
        }
      }
    }

    Log.i(TAG, "Shutting down activity manager...");

    final IActivityManager am =
        ActivityManagerNative.asInterface(ServiceManager.checkService("activity"));
    if (am != null) {
      try {
        am.shutdown(MAX_BROADCAST_TIME);
      } catch (RemoteException e) {
      }
    }

    final ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
    final IBluetooth bluetooth =
        IBluetooth.Stub.asInterface(
            ServiceManager.checkService(BluetoothAdapter.BLUETOOTH_SERVICE));

    final IMountService mount =
        IMountService.Stub.asInterface(ServiceManager.checkService("mount"));

    try {
      bluetoothOff =
          bluetooth == null || bluetooth.getBluetoothState() == BluetoothAdapter.STATE_OFF;
      if (!bluetoothOff) {
        Log.w(TAG, "Disabling Bluetooth...");
        bluetooth.disable(false); // disable but don't persist new state
      }
    } catch (RemoteException ex) {
      Log.e(TAG, "RemoteException during bluetooth shutdown", ex);
      bluetoothOff = true;
    }

    try {
      radioOff = phone == null || !phone.isRadioOn();
      if (!radioOff) {
        Log.w(TAG, "Turning off radio...");
        phone.setRadio(false);
      }
    } catch (RemoteException ex) {
      Log.e(TAG, "RemoteException during radio shutdown", ex);
      radioOff = true;
    }

    Log.i(TAG, "Waiting for Bluetooth and Radio...");

    // Wait a max of 32 seconds for clean shutdown
    for (int i = 0; i < MAX_NUM_PHONE_STATE_READS; i++) {
      if (!bluetoothOff) {
        try {
          bluetoothOff = bluetooth.getBluetoothState() == BluetoothAdapter.STATE_OFF;
        } catch (RemoteException ex) {
          Log.e(TAG, "RemoteException during bluetooth shutdown", ex);
          bluetoothOff = true;
        }
      }
      if (!radioOff) {
        try {
          radioOff = !phone.isRadioOn();
        } catch (RemoteException ex) {
          Log.e(TAG, "RemoteException during radio shutdown", ex);
          radioOff = true;
        }
      }
      if (radioOff && bluetoothOff) {
        Log.i(TAG, "Radio and Bluetooth shutdown complete.");
        break;
      }
      SystemClock.sleep(PHONE_STATE_POLL_SLEEP_MSEC);
    }

    // Shutdown MountService to ensure media is in a safe state
    try {
      if (mount != null) {
        mount.shutdown();
      } else {
        Log.w(TAG, "MountService unavailable for shutdown");
      }
    } catch (Exception e) {
      Log.e(TAG, "Exception during MountService shutdown", e);
    }

    // shutdown power
    Log.i(TAG, "Performing low-level shutdown...");
    Power.shutdown();
  }
  /**
   * Run the command!
   *
   * @param args The command-line arguments
   * @return Returns a posix-style result code. 0 for no error.
   */
  private int run(String[] args) {
    // Super-early debugger wait
    for (String s : args) {
      if ("--wait-dbg".equals(s)) {
        Debug.waitForDebugger();
      }
    }

    // Default values for some command-line options
    mVerbose = 0;
    mCount = 1000;
    mSeed = 0;
    mThrottle = 0;

    // prepare for command-line processing
    mArgs = args;
    mNextArg = 0;

    // set a positive value, indicating none of the factors is provided yet
    for (int i = 0; i < MonkeySourceRandom.FACTORZ_COUNT; i++) {
      mFactors[i] = 1.0f;
    }

    if (!processOptions()) {
      return -1;
    }

    if (!loadPackageLists()) {
      return -1;
    }

    // now set up additional data in preparation for launch
    if (mMainCategories.size() == 0) {
      mMainCategories.add(Intent.CATEGORY_LAUNCHER);
      mMainCategories.add(Intent.CATEGORY_MONKEY);
    }

    if (mVerbose > 0) {
      System.out.println(":Monkey: seed=" + mSeed + " count=" + mCount);
      if (mValidPackages.size() > 0) {
        Iterator<String> it = mValidPackages.iterator();
        while (it.hasNext()) {
          System.out.println(":AllowPackage: " + it.next());
        }
      }
      if (mInvalidPackages.size() > 0) {
        Iterator<String> it = mInvalidPackages.iterator();
        while (it.hasNext()) {
          System.out.println(":DisallowPackage: " + it.next());
        }
      }
      if (mMainCategories.size() != 0) {
        Iterator<String> it = mMainCategories.iterator();
        while (it.hasNext()) {
          System.out.println(":IncludeCategory: " + it.next());
        }
      }
    }

    if (!checkInternalConfiguration()) {
      return -2;
    }

    if (!getSystemInterfaces()) {
      return -3;
    }

    if (!getMainApps()) {
      return -4;
    }

    mRandom = new SecureRandom();
    mRandom.setSeed((mSeed == 0) ? -1 : mSeed);

    if (mScriptFileNames != null && mScriptFileNames.size() == 1) {
      // script mode, ignore other options
      mEventSource =
          new MonkeySourceScript(
              mRandom,
              mScriptFileNames.get(0),
              mThrottle,
              mRandomizeThrottle,
              mProfileWaitTime,
              mDeviceSleepTime);
      mEventSource.setVerbose(mVerbose);

      mCountEvents = false;
    } else if (mScriptFileNames != null && mScriptFileNames.size() > 1) {
      if (mSetupFileName != null) {
        mEventSource =
            new MonkeySourceRandomScript(
                mSetupFileName,
                mScriptFileNames,
                mThrottle,
                mRandomizeThrottle,
                mRandom,
                mProfileWaitTime,
                mDeviceSleepTime,
                mRandomizeScript);
        mCount++;
      } else {
        mEventSource =
            new MonkeySourceRandomScript(
                mScriptFileNames,
                mThrottle,
                mRandomizeThrottle,
                mRandom,
                mProfileWaitTime,
                mDeviceSleepTime,
                mRandomizeScript);
      }
      mEventSource.setVerbose(mVerbose);
      mCountEvents = false;
    } else if (mServerPort != -1) {
      try {
        mEventSource = new MonkeySourceNetwork(mServerPort);
      } catch (IOException e) {
        System.out.println("Error binding to network socket.");
        return -5;
      }
      mCount = Integer.MAX_VALUE;
    } else {
      // random source by default
      if (mVerbose >= 2) { // check seeding performance
        System.out.println("// Seeded: " + mSeed);
      }
      mEventSource = new MonkeySourceRandom(mRandom, mMainApps, mThrottle, mRandomizeThrottle);
      mEventSource.setVerbose(mVerbose);
      // set any of the factors that has been set
      for (int i = 0; i < MonkeySourceRandom.FACTORZ_COUNT; i++) {
        if (mFactors[i] <= 0.0f) {
          ((MonkeySourceRandom) mEventSource).setFactors(i, mFactors[i]);
        }
      }

      // in random mode, we start with a random activity
      ((MonkeySourceRandom) mEventSource).generateActivity();
    }

    // validate source generator
    if (!mEventSource.validate()) {
      return -5;
    }

    // If we're profiling, do it immediately before/after the main monkey
    // loop
    if (mGenerateHprof) {
      signalPersistentProcesses();
    }

    mNetworkMonitor.start();
    int crashedAtCycle = runMonkeyCycles();
    mNetworkMonitor.stop();

    synchronized (this) {
      if (mRequestAnrTraces) {
        reportAnrTraces();
        mRequestAnrTraces = false;
      }
      if (mRequestAnrBugreport) {
        System.out.println("Print the anr report");
        getBugreport("anr_" + mReportProcessName + "_");
        mRequestAnrBugreport = false;
      }
      if (mRequestAppCrashBugreport) {
        getBugreport("app_crash" + mReportProcessName + "_");
        mRequestAppCrashBugreport = false;
      }
      if (mRequestDumpsysMemInfo) {
        reportDumpsysMemInfo();
        mRequestDumpsysMemInfo = false;
      }
    }

    if (mGenerateHprof) {
      signalPersistentProcesses();
      if (mVerbose > 0) {
        System.out.println("// Generated profiling reports in /data/misc");
      }
    }

    try {
      mAm.setActivityController(null);
      mNetworkMonitor.unregister(mAm);
    } catch (RemoteException e) {
      // just in case this was latent (after mCount cycles), make sure
      // we report it
      if (crashedAtCycle >= mCount) {
        crashedAtCycle = mCount - 1;
      }
    }

    // report dropped event stats
    if (mVerbose > 0) {
      System.out.print(":Dropped: keys=");
      System.out.print(mDroppedKeyEvents);
      System.out.print(" pointers=");
      System.out.print(mDroppedPointerEvents);
      System.out.print(" trackballs=");
      System.out.print(mDroppedTrackballEvents);
      System.out.print(" flips=");
      System.out.println(mDroppedFlipEvents);
    }

    // report network stats
    mNetworkMonitor.dump();

    if (crashedAtCycle < mCount - 1) {
      System.err.println(
          "** System appears to have crashed at event "
              + crashedAtCycle
              + " of "
              + mCount
              + " using seed "
              + mSeed);
      return crashedAtCycle;
    } else {
      if (mVerbose > 0) {
        System.out.println("// Monkey finished");
      }
      return 0;
    }
  }
  private void runInstrument() {
    String profileFile = null;
    boolean wait = false;
    boolean rawMode = false;
    boolean no_window_animation = false;
    Bundle args = new Bundle();
    String argKey = null, argValue = null;
    IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));

    try {
      String opt;
      while ((opt = nextOption()) != null) {
        if (opt.equals("-p")) {
          profileFile = nextOptionData();
        } else if (opt.equals("-w")) {
          wait = true;
        } else if (opt.equals("-r")) {
          rawMode = true;
        } else if (opt.equals("-e")) {
          argKey = nextOptionData();
          argValue = nextOptionData();
          args.putString(argKey, argValue);
        } else if (opt.equals("--no_window_animation")) {
          no_window_animation = true;
        } else {
          System.err.println("Error: Unknown option: " + opt);
          showUsage();
          return;
        }
      }
    } catch (RuntimeException ex) {
      System.err.println("Error: " + ex.toString());
      showUsage();
      return;
    }

    String cnArg = nextArg();
    if (cnArg == null) {
      System.err.println("Error: No instrumentation component supplied");
      showUsage();
      return;
    }

    ComponentName cn = ComponentName.unflattenFromString(cnArg);
    if (cn == null) {
      System.err.println("Error: Bad component name: " + cnArg);
      showUsage();
      return;
    }

    InstrumentationWatcher watcher = null;
    if (wait) {
      watcher = new InstrumentationWatcher();
      watcher.setRawOutput(rawMode);
    }
    float[] oldAnims = null;
    if (no_window_animation) {
      try {
        oldAnims = wm.getAnimationScales();
        wm.setAnimationScale(0, 0.0f);
        wm.setAnimationScale(1, 0.0f);
      } catch (RemoteException e) {
      }
    }

    try {
      if (!mAm.startInstrumentation(cn, profileFile, 0, args, watcher)) {
        System.out.println("INSTRUMENTATION_FAILED: " + cn.flattenToString());
        showUsage();
        return;
      }
    } catch (RemoteException e) {
    }

    if (watcher != null) {
      if (!watcher.waitForFinish()) {
        System.out.println("INSTRUMENTATION_ABORTED: System has crashed.");
      }
    }

    if (oldAnims != null) {
      try {
        wm.setAnimationScales(oldAnims);
      } catch (RemoteException e) {
      }
    }
  }