public Debug.MemoryInfo dumpMemInfo(
     FileDescriptor fd, boolean checkin, boolean all, String[] args) throws RemoteException {
   Parcel data = Parcel.obtain();
   Parcel reply = Parcel.obtain();
   data.writeInterfaceToken(IApplicationThread.descriptor);
   data.writeFileDescriptor(fd);
   data.writeInt(checkin ? 1 : 0);
   data.writeInt(all ? 1 : 0);
   data.writeStringArray(args);
   mRemote.transact(DUMP_MEM_INFO_TRANSACTION, data, reply, 0);
   reply.readException();
   Debug.MemoryInfo info = new Debug.MemoryInfo();
   info.readFromParcel(reply);
   data.recycle();
   reply.recycle();
   return info;
 }
Ejemplo n.º 2
0
  /**
   * @param ctx 上下文环境
   * @return 当前手机正在运行的进程的相关信息
   */
  public static List<ProcessInfo> getProcessInfo(Context ctx) {
    // 获取进程相关信息
    List<ProcessInfo> processInfoList = new ArrayList<ProcessInfo>();
    // 1,activityManager管理者对象和PackageManager管理者对象
    ActivityManager am = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
    PackageManager pm = ctx.getPackageManager();
    // 2,获取正在运行的进程的集合
    List<RunningAppProcessInfo> runningAppProcesses = am.getRunningAppProcesses();

    // 3,循环遍历上诉集合,获取进程相关信息(名称,包名,图标,使用内存大小,是否为系统进程(状态机))
    for (RunningAppProcessInfo info : runningAppProcesses) {
      ProcessInfo processInfo = new ProcessInfo();
      // 4,获取进程的名称 == 应用的包名
      processInfo.packageName = info.processName;
      // 5,获取进程占用的内存大小(传递一个进程对应的pid数组)
      android.os.Debug.MemoryInfo[] processMemoryInfo =
          am.getProcessMemoryInfo(new int[] {info.pid});
      // 6,返回数组中索引位置为0的对象,为当前进程的内存信息的对象
      android.os.Debug.MemoryInfo memoryInfo = processMemoryInfo[0];
      // 7,获取已使用的大小
      processInfo.memSize = memoryInfo.getTotalPrivateDirty() * 1024;

      try {
        ApplicationInfo applicationInfo = pm.getApplicationInfo(processInfo.packageName, 0);
        // 8,获取应用的名称
        processInfo.name = applicationInfo.loadLabel(pm).toString();
        // 9,获取应用的图标
        processInfo.icon = applicationInfo.loadIcon(pm);
        // 10,判断是否为系统进程
        if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == ApplicationInfo.FLAG_SYSTEM) {
          processInfo.isSystem = true;
        } else {
          processInfo.isSystem = false;
        }
      } catch (NameNotFoundException e) {
        // 需要处理
        processInfo.name = info.processName;
        processInfo.icon = ctx.getResources().getDrawable(R.drawable.ic_launcher);
        processInfo.isSystem = true;
        e.printStackTrace();
      }
      processInfoList.add(processInfo);
    }
    return processInfoList;
  }
 public void getMemoryInfo(Debug.MemoryInfo outInfo) throws RemoteException {
   Parcel data = Parcel.obtain();
   Parcel reply = Parcel.obtain();
   data.writeInterfaceToken(IApplicationThread.descriptor);
   mRemote.transact(GET_MEMORY_INFO_TRANSACTION, data, reply, 0);
   reply.readException();
   outInfo.readFromParcel(reply);
   data.recycle();
   reply.recycle();
 }
 boolean updateSize(Context context, Debug.MemoryInfo mem, int curSeq) {
   mSize = ((long) mem.getTotalPss()) * 1024;
   if (mCurSeq == curSeq) {
     String sizeStr = Formatter.formatShortFileSize(context, mSize);
     if (!sizeStr.equals(mSizeStr)) {
       mSizeStr = sizeStr;
       // We update this on the second tick where we update just
       // the text in the current items, so no need to say we
       // changed here.
       return false;
     }
   }
   return false;
 }
Ejemplo n.º 5
0
  /**
   * Get all running apps 如何判断多个进程是属于一个app? 1. 相同的前缀包名 返回的运行时应用列表, 按照内存占用量降序排序
   *
   * @param ctx
   * @return
   */
  public List<Map<String, Object>> getRunningApps(Context ctx) {

    // get all running app processes
    List<RunningAppProcessInfo> runningAppProcesses = activityManager.getRunningAppProcesses();
    if (runningAppProcesses == null) return null;

    // sort all running app processes
    Collections.sort(
        runningAppProcesses,
        new Comparator<RunningAppProcessInfo>() {
          @Override
          public int compare(RunningAppProcessInfo lhs, RunningAppProcessInfo rhs) {
            String lhsPkgName = lhs.processName.split(":")[0];
            String rhsPkgName = rhs.processName.split(":")[0];
            return lhsPkgName.compareToIgnoreCase(rhsPkgName);
          }
        });

    Intent intent = new Intent(Intent.ACTION_MAIN);
    intent.addCategory(Intent.CATEGORY_HOME);
    ResolveInfo resolveInfo =
        appHelper.getPm().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
    String currentHomePackage = resolveInfo.activityInfo.packageName;
    IGNORE_PKGS.add(currentHomePackage);

    // remove all ignored packages
    Log.i(TAG, "before remove :" + runningAppProcesses.size());
    ArrayList<RunningAppProcessInfo> toBeRemoved = new ArrayList<RunningAppProcessInfo>();
    for (RunningAppProcessInfo runningProcessInfo : runningAppProcesses) {
      Log.i(TAG, "after sort:" + runningProcessInfo.processName);
      try {
        String appPkgname = runningProcessInfo.processName.split(":")[0];
        if (IGNORE_PKGS.contains(appPkgname)) {
          toBeRemoved.add(runningProcessInfo);
        }
      } catch (Exception e) {
        e.printStackTrace();
        Log.w(TAG, "exception raised while remove ignore list:" + e.toString());
      }
    }
    runningAppProcesses.removeAll(toBeRemoved);
    Log.i(
        TAG,
        "removed :"
            + toBeRemoved.size()
            + " ignored packages, after remove size:"
            + runningAppProcesses.size());

    Map<String, Map<String, Object>> runningApps = new HashMap<String, Map<String, Object>>();
    // iterate the running app process list
    for (RunningAppProcessInfo runningProcessInfo : runningAppProcesses) {
      String[] pkgNameSections = runningProcessInfo.processName.split(":");
      Log.i(
          TAG,
          "process name:"
              + runningProcessInfo.processName
              + ", pkgNameSections length:"
              + pkgNameSections.length);
      if (pkgNameSections.length == 0) {
        // TODO: process name is ""?
        continue;
      }
      String appPkgname = pkgNameSections[0];
      String subProcessName = (pkgNameSections.length == 2) ? pkgNameSections[1] : null;
      Log.i(TAG, "appPkgname:" + appPkgname + ", subProcessName:" + subProcessName);

      // get application info from package name
      ApplicationInfo appInfo = appHelper.getApplicationInfo(appPkgname);
      if (appInfo == null) appInfo = appHelper.getApplicationInfo(runningProcessInfo.processName);

      // get app info by app package name
      Map<String, Object> appInfoMap = runningApps.get(appPkgname);
      if (appInfoMap == null) appInfoMap = new HashMap<String, Object>();

      // put app package name
      if (!appInfoMap.containsKey(PKG_NAME)) {
        appInfoMap.put(PKG_NAME, appPkgname);
      }

      // put app uid
      if (!appInfoMap.containsKey(APP_UID)) {
        appInfoMap.put(APP_UID, runningProcessInfo.uid);
      }

      // put recommend flag
      if (!appInfoMap.containsKey(APP_RECOMMEND_CLEAN)) {
        appInfoMap.put(APP_RECOMMEND_CLEAN, !NOT_RECOMMAND_PKGS.contains(appPkgname));
      }

      // only main process can get human readable name
      if (appInfo != null) {
        appInfoMap.put(APP_NAME, appInfo.loadLabel(appHelper.getPm()).toString());
      } else if (!appInfoMap.containsKey(APP_NAME)) {
        appInfoMap.put(APP_NAME, appPkgname);
      }

      // get and put app icon
      if (appInfo != null) {
        appInfoMap.put(APP_ICON, appInfo.loadIcon(appHelper.getPm()));
      } else if (!appInfoMap.containsKey(APP_ICON)) {
        appInfoMap.put(APP_ICON, android.R.drawable.sym_def_app_icon);
      }

      // get memory size of app process, store mem info <Key(pid), Value(Debug.MemoryInfo)>
      SparseArray<Debug.MemoryInfo> memoryInfoArray =
          (SparseArray<Debug.MemoryInfo>) appInfoMap.get(APP_PROC_MEM);
      if (memoryInfoArray == null) memoryInfoArray = new SparseArray<Debug.MemoryInfo>();
      Debug.MemoryInfo memInfo = getDebugMemoryInfos(new int[] {runningProcessInfo.pid})[0];
      memoryInfoArray.put(runningProcessInfo.pid, memInfo);
      appInfoMap.put(APP_PROC_MEM, memoryInfoArray);

      // update total
      int totalPss = 0;
      if (appInfoMap.containsKey(APP_TOTAL_PSS)) totalPss = (Integer) appInfoMap.get(APP_TOTAL_PSS);
      totalPss += memInfo.getTotalPss();
      appInfoMap.put(APP_TOTAL_PSS, totalPss);

      // add process in process array
      List<RunningAppProcessInfo> processes =
          (ArrayList<RunningAppProcessInfo>) appInfoMap.get(APP_PROCS);
      if (processes == null) processes = new ArrayList<RunningAppProcessInfo>();
      processes.add(runningProcessInfo);
      appInfoMap.put(APP_PROCS, processes);

      runningApps.put(appPkgname, appInfoMap);
    }
    return sortMap(runningApps);
  }
  @Override
  protected void dispatchDraw(Canvas canvas) {
    super.dispatchDraw(canvas);

    if (mDragging) {
      if (mAnimationState == ANIMATION_STATE_STARTING) {
        mAnimationStartTime = SystemClock.uptimeMillis();
        mAnimationState = ANIMATION_STATE_RUNNING;
      }

      if (mAnimationState == ANIMATION_STATE_RUNNING) {
        float normalized =
            (float) (SystemClock.uptimeMillis() - mAnimationStartTime) / mAnimationDuration;
        if (normalized >= 1.0f) {
          mAnimationState = ANIMATION_STATE_DONE;
        }
        normalized = Math.min(normalized, 1.0f);
        final float value = mAnimationFrom + (mAnimationTo - mAnimationFrom) * normalized;

        switch (mAnimationType) {
          case ANIMATION_TYPE_SCALE:
            if (mDrawModeBitmap && mDragBitmap != null) {
              final Bitmap dragBitmap = mDragBitmap;
              canvas.save();
              canvas.translate(
                  getScrollX() + mLastMotionX - mTouchOffsetX - mBitmapOffsetX,
                  getScrollY() + mLastMotionY - mTouchOffsetY - mBitmapOffsetY);
              canvas.translate(
                  (dragBitmap.getWidth() * (1.0f - value)) / 2,
                  (dragBitmap.getHeight() * (1.0f - value)) / 2);
              canvas.scale(value, value);
              canvas.drawBitmap(dragBitmap, 0.0f, 0.0f, mDragPaint);
              canvas.restore();
            } else {
              canvas.save();
              canvas.translate(
                  getScrollX() + mLastMotionX - mTouchOffsetX - mBitmapOffsetX,
                  getScrollY() + mLastMotionY - mTouchOffsetY - mBitmapOffsetY);
              canvas.translate(
                  (mDrawWidth * (1.0f - value)) / 2, (mDrawHeight * (1.0f - value)) / 2);
              canvas.drawRoundRect(
                  new RectF(0, 0, mDrawWidth, mDrawHeight), 8.0f, 8.0f, mRectPaint);
              canvas.restore();
            }
            break;
        }
      } else {
        // Draw actual icon being dragged
        if (mDrawModeBitmap && mDragBitmap != null) {
          canvas.drawBitmap(
              mDragBitmap,
              getScrollX() + mLastMotionX - mTouchOffsetX - mBitmapOffsetX,
              getScrollY() + mLastMotionY - mTouchOffsetY - mBitmapOffsetY,
              mDragPaint);
        } else {
          canvas.save();
          canvas.translate(
              getScrollX() + mLastMotionX - mTouchOffsetX - mBitmapOffsetX,
              getScrollY() + mLastMotionY - mTouchOffsetY - mBitmapOffsetY);
          canvas.drawRoundRect(new RectF(0, 0, mDrawWidth, mDrawHeight), 8.0f, 8.0f, mRectPaint);
          canvas.restore();
        }
      }
    }
    if (pids.length > 0 && AlmostNexusSettingsHelper.getDebugShowMemUsage(getContext())) {
      mRectPaint.setTextSize(debugTextSize);
      mRectPaint.setAntiAlias(true);
      mRectPaint.setColor(0xff000000);
      if (pids.length > 0) canvas.drawRect(0, 0, getWidth(), 70, mRectPaint);
      mRectPaint.setColor(0xffffffff);
      memoryInfoArray = activityManager.getProcessMemoryInfo(pids);
      for (Debug.MemoryInfo pidMemoryInfo : memoryInfoArray) {
        canvas.drawText(
            "getTotalPrivateDirty: " + pidMemoryInfo.getTotalPrivateDirty(),
            0,
            debugTextSize,
            mRectPaint);
        canvas.drawText(
            "getTotalPss: " + pidMemoryInfo.getTotalPss(), 0, debugTextSize * 2, mRectPaint);
        canvas.drawText(
            "getTotalSharedDirty: " + pidMemoryInfo.getTotalSharedDirty(),
            0,
            debugTextSize * 3,
            mRectPaint);
      }
    }
  }
  @Override
  public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
    switch (code) {
      case SCHEDULE_PAUSE_ACTIVITY_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          IBinder b = data.readStrongBinder();
          boolean finished = data.readInt() != 0;
          boolean userLeaving = data.readInt() != 0;
          int configChanges = data.readInt();
          schedulePauseActivity(b, finished, userLeaving, configChanges);
          return true;
        }

      case SCHEDULE_STOP_ACTIVITY_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          IBinder b = data.readStrongBinder();
          boolean show = data.readInt() != 0;
          int configChanges = data.readInt();
          scheduleStopActivity(b, show, configChanges);
          return true;
        }

      case SCHEDULE_WINDOW_VISIBILITY_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          IBinder b = data.readStrongBinder();
          boolean show = data.readInt() != 0;
          scheduleWindowVisibility(b, show);
          return true;
        }

      case SCHEDULE_SLEEPING_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          IBinder b = data.readStrongBinder();
          boolean sleeping = data.readInt() != 0;
          scheduleSleeping(b, sleeping);
          return true;
        }

      case SCHEDULE_RESUME_ACTIVITY_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          IBinder b = data.readStrongBinder();
          boolean isForward = data.readInt() != 0;
          scheduleResumeActivity(b, isForward);
          return true;
        }

      case SCHEDULE_SEND_RESULT_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          IBinder b = data.readStrongBinder();
          List<ResultInfo> ri = data.createTypedArrayList(ResultInfo.CREATOR);
          scheduleSendResult(b, ri);
          return true;
        }

      case SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          Intent intent = Intent.CREATOR.createFromParcel(data);
          IBinder b = data.readStrongBinder();
          int ident = data.readInt();
          ActivityInfo info = ActivityInfo.CREATOR.createFromParcel(data);
          Configuration curConfig = Configuration.CREATOR.createFromParcel(data);
          CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
          Bundle state = data.readBundle();
          List<ResultInfo> ri = data.createTypedArrayList(ResultInfo.CREATOR);
          List<Intent> pi = data.createTypedArrayList(Intent.CREATOR);
          boolean notResumed = data.readInt() != 0;
          boolean isForward = data.readInt() != 0;
          String profileName = data.readString();
          ParcelFileDescriptor profileFd = data.readInt() != 0 ? data.readFileDescriptor() : null;
          boolean autoStopProfiler = data.readInt() != 0;
          scheduleLaunchActivity(
              intent,
              b,
              ident,
              info,
              curConfig,
              compatInfo,
              state,
              ri,
              pi,
              notResumed,
              isForward,
              profileName,
              profileFd,
              autoStopProfiler);
          return true;
        }

      case SCHEDULE_RELAUNCH_ACTIVITY_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          IBinder b = data.readStrongBinder();
          List<ResultInfo> ri = data.createTypedArrayList(ResultInfo.CREATOR);
          List<Intent> pi = data.createTypedArrayList(Intent.CREATOR);
          int configChanges = data.readInt();
          boolean notResumed = data.readInt() != 0;
          Configuration config = null;
          if (data.readInt() != 0) {
            config = Configuration.CREATOR.createFromParcel(data);
          }
          scheduleRelaunchActivity(b, ri, pi, configChanges, notResumed, config);
          return true;
        }

      case SCHEDULE_NEW_INTENT_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          List<Intent> pi = data.createTypedArrayList(Intent.CREATOR);
          IBinder b = data.readStrongBinder();
          scheduleNewIntent(pi, b);
          return true;
        }

      case SCHEDULE_FINISH_ACTIVITY_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          IBinder b = data.readStrongBinder();
          boolean finishing = data.readInt() != 0;
          int configChanges = data.readInt();
          scheduleDestroyActivity(b, finishing, configChanges);
          return true;
        }

      case SCHEDULE_RECEIVER_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          Intent intent = Intent.CREATOR.createFromParcel(data);
          ActivityInfo info = ActivityInfo.CREATOR.createFromParcel(data);
          CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
          int resultCode = data.readInt();
          String resultData = data.readString();
          Bundle resultExtras = data.readBundle();
          boolean sync = data.readInt() != 0;
          scheduleReceiver(intent, info, compatInfo, resultCode, resultData, resultExtras, sync);
          return true;
        }

      case SCHEDULE_CREATE_SERVICE_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          IBinder token = data.readStrongBinder();
          ServiceInfo info = ServiceInfo.CREATOR.createFromParcel(data);
          CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
          scheduleCreateService(token, info, compatInfo);
          return true;
        }

      case SCHEDULE_BIND_SERVICE_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          IBinder token = data.readStrongBinder();
          Intent intent = Intent.CREATOR.createFromParcel(data);
          boolean rebind = data.readInt() != 0;
          scheduleBindService(token, intent, rebind);
          return true;
        }

      case SCHEDULE_UNBIND_SERVICE_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          IBinder token = data.readStrongBinder();
          Intent intent = Intent.CREATOR.createFromParcel(data);
          scheduleUnbindService(token, intent);
          return true;
        }

      case SCHEDULE_SERVICE_ARGS_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          IBinder token = data.readStrongBinder();
          boolean taskRemoved = data.readInt() != 0;
          int startId = data.readInt();
          int fl = data.readInt();
          Intent args;
          if (data.readInt() != 0) {
            args = Intent.CREATOR.createFromParcel(data);
          } else {
            args = null;
          }
          scheduleServiceArgs(token, taskRemoved, startId, fl, args);
          return true;
        }

      case SCHEDULE_STOP_SERVICE_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          IBinder token = data.readStrongBinder();
          scheduleStopService(token);
          return true;
        }

      case BIND_APPLICATION_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          String packageName = data.readString();
          ApplicationInfo info = ApplicationInfo.CREATOR.createFromParcel(data);
          List<ProviderInfo> providers = data.createTypedArrayList(ProviderInfo.CREATOR);
          ComponentName testName = (data.readInt() != 0) ? new ComponentName(data) : null;
          String profileName = data.readString();
          ParcelFileDescriptor profileFd = data.readInt() != 0 ? data.readFileDescriptor() : null;
          boolean autoStopProfiler = data.readInt() != 0;
          Bundle testArgs = data.readBundle();
          IBinder binder = data.readStrongBinder();
          IInstrumentationWatcher testWatcher = IInstrumentationWatcher.Stub.asInterface(binder);
          int testMode = data.readInt();
          boolean restrictedBackupMode = (data.readInt() != 0);
          boolean persistent = (data.readInt() != 0);
          Configuration config = Configuration.CREATOR.createFromParcel(data);
          CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
          HashMap<String, IBinder> services = data.readHashMap(null);
          Bundle coreSettings = data.readBundle();
          bindApplication(
              packageName,
              info,
              providers,
              testName,
              profileName,
              profileFd,
              autoStopProfiler,
              testArgs,
              testWatcher,
              testMode,
              restrictedBackupMode,
              persistent,
              config,
              compatInfo,
              services,
              coreSettings);
          return true;
        }

      case SCHEDULE_EXIT_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          scheduleExit();
          return true;
        }

      case SCHEDULE_SUICIDE_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          scheduleSuicide();
          return true;
        }

      case REQUEST_THUMBNAIL_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          IBinder b = data.readStrongBinder();
          requestThumbnail(b);
          return true;
        }

      case SCHEDULE_CONFIGURATION_CHANGED_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          Configuration config = Configuration.CREATOR.createFromParcel(data);
          scheduleConfigurationChanged(config);
          return true;
        }

      case UPDATE_TIME_ZONE_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          updateTimeZone();
          return true;
        }

      case CLEAR_DNS_CACHE_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          clearDnsCache();
          return true;
        }

      case SET_HTTP_PROXY_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          final String proxy = data.readString();
          final String port = data.readString();
          final String exclList = data.readString();
          setHttpProxy(proxy, port, exclList);
          return true;
        }

      case PROCESS_IN_BACKGROUND_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          processInBackground();
          return true;
        }

      case DUMP_SERVICE_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          ParcelFileDescriptor fd = data.readFileDescriptor();
          final IBinder service = data.readStrongBinder();
          final String[] args = data.readStringArray();
          if (fd != null) {
            dumpService(fd.getFileDescriptor(), service, args);
            try {
              fd.close();
            } catch (IOException e) {
            }
          }
          return true;
        }

      case SCHEDULE_REGISTERED_RECEIVER_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          IIntentReceiver receiver = IIntentReceiver.Stub.asInterface(data.readStrongBinder());
          Intent intent = Intent.CREATOR.createFromParcel(data);
          int resultCode = data.readInt();
          String dataStr = data.readString();
          Bundle extras = data.readBundle();
          boolean ordered = data.readInt() != 0;
          boolean sticky = data.readInt() != 0;
          scheduleRegisteredReceiver(
              receiver, intent, resultCode, dataStr, extras, ordered, sticky);
          return true;
        }

      case SCHEDULE_LOW_MEMORY_TRANSACTION:
        {
          scheduleLowMemory();
          return true;
        }

      case SCHEDULE_ACTIVITY_CONFIGURATION_CHANGED_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          IBinder b = data.readStrongBinder();
          scheduleActivityConfigurationChanged(b);
          return true;
        }

      case PROFILER_CONTROL_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          boolean start = data.readInt() != 0;
          int profileType = data.readInt();
          String path = data.readString();
          ParcelFileDescriptor fd = data.readInt() != 0 ? data.readFileDescriptor() : null;
          profilerControl(start, path, fd, profileType);
          return true;
        }

      case SET_SCHEDULING_GROUP_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          int group = data.readInt();
          setSchedulingGroup(group);
          return true;
        }

      case SCHEDULE_CREATE_BACKUP_AGENT_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          ApplicationInfo appInfo = ApplicationInfo.CREATOR.createFromParcel(data);
          CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
          int backupMode = data.readInt();
          scheduleCreateBackupAgent(appInfo, compatInfo, backupMode);
          return true;
        }

      case SCHEDULE_DESTROY_BACKUP_AGENT_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          ApplicationInfo appInfo = ApplicationInfo.CREATOR.createFromParcel(data);
          CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
          scheduleDestroyBackupAgent(appInfo, compatInfo);
          return true;
        }

      case GET_MEMORY_INFO_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          Debug.MemoryInfo mi = new Debug.MemoryInfo();
          getMemoryInfo(mi);
          reply.writeNoException();
          mi.writeToParcel(reply, 0);
          return true;
        }

      case DISPATCH_PACKAGE_BROADCAST_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          int cmd = data.readInt();
          String[] packages = data.readStringArray();
          dispatchPackageBroadcast(cmd, packages);
          return true;
        }

      case SCHEDULE_CRASH_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          String msg = data.readString();
          scheduleCrash(msg);
          return true;
        }

      case DUMP_HEAP_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          boolean managed = data.readInt() != 0;
          String path = data.readString();
          ParcelFileDescriptor fd = data.readInt() != 0 ? data.readFileDescriptor() : null;
          dumpHeap(managed, path, fd);
          return true;
        }

      case DUMP_ACTIVITY_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          ParcelFileDescriptor fd = data.readFileDescriptor();
          final IBinder activity = data.readStrongBinder();
          final String prefix = data.readString();
          final String[] args = data.readStringArray();
          if (fd != null) {
            dumpActivity(fd.getFileDescriptor(), activity, prefix, args);
            try {
              fd.close();
            } catch (IOException e) {
            }
          }
          return true;
        }

      case SET_CORE_SETTINGS_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          Bundle settings = data.readBundle();
          setCoreSettings(settings);
          return true;
        }

      case UPDATE_PACKAGE_COMPATIBILITY_INFO_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          String pkg = data.readString();
          CompatibilityInfo compat = CompatibilityInfo.CREATOR.createFromParcel(data);
          updatePackageCompatibilityInfo(pkg, compat);
          return true;
        }

      case SCHEDULE_TRIM_MEMORY_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          int level = data.readInt();
          scheduleTrimMemory(level);
          return true;
        }

      case DUMP_MEM_INFO_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          ParcelFileDescriptor fd = data.readFileDescriptor();
          boolean checkin = data.readInt() != 0;
          boolean all = data.readInt() != 0;
          String[] args = data.readStringArray();
          Debug.MemoryInfo mi = null;
          if (fd != null) {
            try {
              mi = dumpMemInfo(fd.getFileDescriptor(), checkin, all, args);
            } finally {
              try {
                fd.close();
              } catch (IOException e) {
                // swallowed, not propagated back to the caller
              }
            }
          }
          reply.writeNoException();
          mi.writeToParcel(reply, 0);
          return true;
        }

      case DUMP_GFX_INFO_TRANSACTION:
        {
          data.enforceInterface(IApplicationThread.descriptor);
          ParcelFileDescriptor fd = data.readFileDescriptor();
          String[] args = data.readStringArray();
          if (fd != null) {
            try {
              dumpGfxInfo(fd.getFileDescriptor(), args);
            } finally {
              try {
                fd.close();
              } catch (IOException e) {
                // swallowed, not propagated back to the caller
              }
            }
          }
          reply.writeNoException();
          return true;
        }
    }

    return super.onTransact(code, data, reply, flags);
  }