diff --git a/Android.mk b/Android.mk
index 2644ca1..ceb61b8 100644
--- a/Android.mk
+++ b/Android.mk
@@ -68,6 +68,7 @@
 	core/java/android/app/IActivityContainer.aidl \
 	core/java/android/app/IActivityContainerCallback.aidl \
 	core/java/android/app/IActivityController.aidl \
+	core/java/android/app/IActivityManager.aidl \
 	core/java/android/app/IActivityPendingResult.aidl \
 	core/java/android/app/IAlarmCompleteListener.aidl \
 	core/java/android/app/IAlarmListener.aidl \
@@ -615,6 +616,7 @@
 	frameworks/base/core/java/android/os/DropBoxManager.aidl \
 	frameworks/base/core/java/android/os/Bundle.aidl \
 	frameworks/base/core/java/android/os/Debug.aidl \
+	frameworks/base/core/java/android/os/StrictMode.aidl \
 	frameworks/base/core/java/android/accessibilityservice/AccessibilityServiceInfo.aidl \
 	frameworks/base/core/java/android/net/Network.aidl \
 	frameworks/base/core/java/android/net/RouteInfo.aidl \
@@ -695,6 +697,7 @@
 	frameworks/base/core/java/android/content/pm/ApplicationInfo.aidl \
 	frameworks/base/core/java/android/content/pm/PermissionInfo.aidl \
 	frameworks/base/core/java/android/content/pm/ActivityInfo.aidl \
+	frameworks/base/core/java/android/content/pm/ConfigurationInfo.aidl \
 	frameworks/base/core/java/android/content/pm/PackageInfo.aidl \
 	frameworks/base/core/java/android/content/pm/ResolveInfo.aidl \
 	frameworks/base/core/java/android/content/pm/ProviderInfo.aidl \
diff --git a/cmds/content/src/com/android/commands/content/Content.java b/cmds/content/src/com/android/commands/content/Content.java
index c7474a11..132a4f8 100644
--- a/cmds/content/src/com/android/commands/content/Content.java
+++ b/cmds/content/src/com/android/commands/content/Content.java
@@ -17,8 +17,8 @@
 package com.android.commands.content;
 
 import android.app.ActivityManagerNative;
+import android.app.ContentProviderHolder;
 import android.app.IActivityManager;
-import android.app.IActivityManager.ContentProviderHolder;
 import android.content.ContentValues;
 import android.content.IContentProvider;
 import android.database.Cursor;
diff --git a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java
index cb39e37..8681166 100644
--- a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java
+++ b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java
@@ -17,8 +17,8 @@
 package com.android.uiautomator.core;
 
 import android.app.ActivityManagerNative;
+import android.app.ContentProviderHolder;
 import android.app.IActivityManager;
-import android.app.IActivityManager.ContentProviderHolder;
 import android.app.UiAutomation;
 import android.content.Context;
 import android.content.IContentProvider;
diff --git a/compiled-classes-phone b/compiled-classes-phone
index 661ff95..8428e41 100644
--- a/compiled-classes-phone
+++ b/compiled-classes-phone
@@ -245,6 +245,8 @@
 android.app.BackStackState
 android.app.BackStackState$1
 android.app.BroadcastOptions
+android.app.ContentProviderHolder
+android.app.ContentProviderHolder$1
 android.app.ContextImpl
 android.app.ContextImpl$1
 android.app.ContextImpl$ApplicationContentResolver
@@ -298,9 +300,8 @@
 android.app.IActivityContainerCallback
 android.app.IActivityController
 android.app.IActivityManager
-android.app.IActivityManager$ContentProviderHolder
-android.app.IActivityManager$ContentProviderHolder$1
-android.app.IActivityManager$WaitResult
+android.app.IActivityManager$Stub
+android.app.IActivityManager$Stub$Proxy
 android.app.IAlarmCompleteListener
 android.app.IAlarmCompleteListener$Stub
 android.app.IAlarmListener
@@ -521,6 +522,7 @@
 android.app.TimePickerDialog
 android.app.TimePickerDialog$OnTimeSetListener
 android.app.UiModeManager
+android.app.WaitResult;
 android.app.WallpaperInfo
 android.app.WallpaperManager
 android.app.WallpaperManager$Globals
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index cb3eba6..b3e2f57 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -6047,8 +6047,8 @@
         boolean drawComplete;
         try {
             mTranslucentCallback = callback;
-            mChangeCanvasToTranslucent =
-                    ActivityManagerNative.getDefault().convertToTranslucent(mToken, options);
+            mChangeCanvasToTranslucent = ActivityManagerNative.getDefault().convertToTranslucent(
+                    mToken, options == null ? null : options.toBundle());
             WindowManagerGlobal.getInstance().changeCanvasOpacity(mToken, false);
             drawComplete = true;
         } catch (RemoteException e) {
@@ -6092,7 +6092,8 @@
      */
     ActivityOptions getActivityOptions() {
         try {
-            return ActivityManagerNative.getDefault().getActivityOptions(mToken);
+            return ActivityOptions.fromBundle(
+                    ActivityManagerNative.getDefault().getActivityOptions(mToken));
         } catch (RemoteException e) {
         }
         return null;
@@ -6988,7 +6989,7 @@
      */
     public void startLockTask() {
         try {
-            ActivityManagerNative.getDefault().startLockTaskMode(mToken);
+            ActivityManagerNative.getDefault().startLockTaskModeByToken(mToken);
         } catch (RemoteException e) {
         }
     }
diff --git a/core/java/android/app/ActivityManager.aidl b/core/java/android/app/ActivityManager.aidl
index fa6481b..5672f6b 100644
--- a/core/java/android/app/ActivityManager.aidl
+++ b/core/java/android/app/ActivityManager.aidl
@@ -16,5 +16,14 @@
 
 package android.app;
 
+parcelable ActivityManager.MemoryInfo;
+parcelable ActivityManager.ProcessErrorStateInfo;
 parcelable ActivityManager.RecentTaskInfo;
 parcelable ActivityManager.TaskDescription;
+parcelable ActivityManager.RunningAppProcessInfo;
+parcelable ActivityManager.RunningServiceInfo;
+parcelable ActivityManager.RunningTaskInfo;
+/** @hide */
+parcelable ActivityManager.StackInfo;
+/** @hide */
+parcelable ActivityManager.TaskThumbnail;
\ No newline at end of file
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 4066f1c..bdca086 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -62,6 +62,7 @@
 import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.DisplayMetrics;
+import android.util.Singleton;
 import android.util.Size;
 
 import org.xmlpull.v1.XmlSerializer;
@@ -1687,7 +1688,7 @@
      */
     public List<ActivityManager.AppTask> getAppTasks() {
         ArrayList<AppTask> tasks = new ArrayList<AppTask>();
-        List<IAppTask> appTasks;
+        List<IBinder> appTasks;
         try {
             appTasks = ActivityManagerNative.getDefault().getAppTasks(mContext.getPackageName());
         } catch (RemoteException e) {
@@ -1695,7 +1696,7 @@
         }
         int numAppTasks = appTasks.size();
         for (int i = 0; i < numAppTasks; i++) {
-            tasks.add(new AppTask(appTasks.get(i)));
+            tasks.add(new AppTask(IAppTask.Stub.asInterface(appTasks.get(i))));
         }
         return tasks;
     }
@@ -3520,6 +3521,76 @@
         pw.flush();
     }
 
+    /**
+     * @hide
+     */
+    public static void broadcastStickyIntent(Intent intent, int userId) {
+        broadcastStickyIntent(intent, AppOpsManager.OP_NONE, userId);
+    }
+
+    /**
+     * Convenience for sending a sticky broadcast.  For internal use only.
+     *
+     * @hide
+     */
+    public static void broadcastStickyIntent(Intent intent, int appOp, int userId) {
+        try {
+            getService().broadcastIntent(
+                    null, intent, null, null, Activity.RESULT_OK, null, null,
+                    null /*permission*/, appOp, null, false, true, userId);
+        } catch (RemoteException ex) {
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public static void noteWakeupAlarm(PendingIntent ps, int sourceUid, String sourcePkg,
+            String tag) {
+        try {
+            getService().noteWakeupAlarm((ps != null) ? ps.getTarget() : null,
+                    sourceUid, sourcePkg, tag);
+        } catch (RemoteException ex) {
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public static void noteAlarmStart(PendingIntent ps, int sourceUid, String tag) {
+        try {
+            getService().noteAlarmStart((ps != null) ? ps.getTarget() : null, sourceUid, tag);
+        } catch (RemoteException ex) {
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public static void noteAlarmFinish(PendingIntent ps, int sourceUid, String tag) {
+        try {
+            getService().noteAlarmFinish((ps != null) ? ps.getTarget() : null, sourceUid, tag);
+        } catch (RemoteException ex) {
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public static IActivityManager getService() {
+        return IActivityManagerSingleton.get();
+    }
+
+    private static final Singleton<IActivityManager> IActivityManagerSingleton =
+            new Singleton<IActivityManager>() {
+                @Override
+                protected IActivityManager create() {
+                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
+                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
+                    return am;
+                }
+            };
+
     private static void dumpService(PrintWriter pw, FileDescriptor fd, String name, String[] args) {
         pw.print("DUMP OF SERVICE "); pw.print(name); pw.println(":");
         IBinder service = ServiceManager.checkService(name);
@@ -3593,7 +3664,7 @@
      */
     public void startLockTaskMode(int taskId) {
         try {
-            ActivityManagerNative.getDefault().startLockTaskMode(taskId);
+            ActivityManagerNative.getDefault().startLockTaskModeById(taskId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 1ee31d8..e56fe0f 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -189,4 +189,9 @@
      *                 guaranteed that all apps have their visibility updated accordingly.
      */
     public abstract void notifyKeyguardFlagsChanged(@Nullable Runnable callback);
+
+    /**
+     * @return {@code true} if system is ready, {@code false} otherwise.
+     */
+    public abstract boolean isSystemReady();
 }
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 141c899..10f0425 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -15,88 +15,52 @@
  */
 
 package android.app;
-
-import android.annotation.UserIdInt;
-import android.app.ActivityManager.StackInfo;
-import android.app.assist.AssistContent;
-import android.app.assist.AssistStructure;
-import android.content.ComponentName;
-import android.content.IIntentReceiver;
-import android.content.IIntentSender;
 import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.IntentSender;
-import android.content.UriPermission;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.ConfigurationInfo;
-import android.content.pm.IPackageDataObserver;
-import android.content.pm.ParceledListSlice;
-import android.content.pm.UserInfo;
-import android.content.res.Configuration;
-import android.graphics.Bitmap;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.net.Uri;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.Debug;
 import android.os.IBinder;
-import android.os.IProgressListener;
-import android.os.Parcel;
-import android.os.ParcelFileDescriptor;
-import android.os.Parcelable;
-import android.os.PersistableBundle;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.StrictMode;
-import android.service.voice.IVoiceInteractionSession;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.Singleton;
-import com.android.internal.app.IVoiceInteractor;
-import com.android.internal.os.IResultReceiver;
+import com.android.server.LocalServices;
 
-import java.util.ArrayList;
-import java.util.List;
-
-/** {@hide} */
-public abstract class ActivityManagerNative extends Binder implements IActivityManager
-{
+/**
+ * {@hide}
+ * @deprecated will be removed soon. See individual methods for alternatives.
+ */
+@Deprecated
+public abstract class ActivityManagerNative {
     /**
      * Cast a Binder object into an activity manager interface, generating
      * a proxy if needed.
+     *
+     * @deprecated use IActivityManager.Stub.asInterface instead.
      */
     static public IActivityManager asInterface(IBinder obj) {
-        if (obj == null) {
-            return null;
-        }
-        IActivityManager in =
-            (IActivityManager)obj.queryLocalInterface(descriptor);
-        if (in != null) {
-            return in;
-        }
-
-        return new ActivityManagerProxy(obj);
+        return IActivityManager.Stub.asInterface(obj);
     }
 
     /**
      * Retrieve the system's default/global activity manager.
+     *
+     * @deprecated use ActivityManager.getService instead.
      */
     static public IActivityManager getDefault() {
-        return gDefault.get();
+        return ActivityManager.getService();
     }
 
     /**
      * Convenience for checking whether the system is ready.  For internal use only.
+     *
+     * @deprecated use ActivityManagerInternal.isSystemReady instead.
      */
     static public boolean isSystemReady() {
         if (!sSystemReady) {
-            sSystemReady = getDefault().testIsSystemReady();
+            sSystemReady = LocalServices.getService(ActivityManagerInternal.class).isSystemReady();
         }
         return sSystemReady;
     }
+
     static volatile boolean sSystemReady = false;
 
+    /**
+     * @deprecated use ActivityManager.broadcastStickyIntent instead.
+     */
     static public void broadcastStickyIntent(Intent intent, String permission, int userId) {
         broadcastStickyIntent(intent, permission, AppOpsManager.OP_NONE, userId);
     }
@@ -104,7061 +68,33 @@
     /**
      * Convenience for sending a sticky broadcast.  For internal use only.
      * If you don't care about permission, use null.
+     *
+     * @deprecated use ActivityManager.broadcastStickyIntent instead.
      */
     static public void broadcastStickyIntent(Intent intent, String permission, int appOp,
             int userId) {
-        try {
-            getDefault().broadcastIntent(
-                    null, intent, null, null, Activity.RESULT_OK, null, null,
-                    null /*permission*/, appOp, null, false, true, userId);
-        } catch (RemoteException ex) {
-        }
+        ActivityManager.broadcastStickyIntent(intent, appOp, userId);
     }
 
+    /**
+     * @deprecated use ActivityManager.noteWakeupAlarm instead.
+     */
     static public void noteWakeupAlarm(PendingIntent ps, int sourceUid, String sourcePkg,
             String tag) {
-        try {
-            getDefault().noteWakeupAlarm((ps != null) ? ps.getTarget() : null,
-                    sourceUid, sourcePkg, tag);
-        } catch (RemoteException ex) {
-        }
+        ActivityManager.noteWakeupAlarm(ps, sourceUid, sourcePkg, tag);
     }
 
+    /**
+     * @deprecated use ActivityManager.noteAlarmStart instead.
+     */
     static public void noteAlarmStart(PendingIntent ps, int sourceUid, String tag) {
-        try {
-            getDefault().noteAlarmStart((ps != null) ? ps.getTarget() : null, sourceUid, tag);
-        } catch (RemoteException ex) {
-        }
+        ActivityManager.noteAlarmStart(ps, sourceUid, tag);
     }
 
+    /**
+     * @deprecated use ActivityManager.noteAlarmFinish instead.
+     */
     static public void noteAlarmFinish(PendingIntent ps, int sourceUid, String tag) {
-        try {
-            getDefault().noteAlarmFinish((ps != null) ? ps.getTarget() : null, sourceUid, tag);
-        } catch (RemoteException ex) {
-        }
+        ActivityManager.noteAlarmFinish(ps, sourceUid, tag);
     }
-
-    public ActivityManagerNative() {
-        attachInterface(this, descriptor);
-    }
-
-    @Override
-    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
-            throws RemoteException {
-        switch (code) {
-        case START_ACTIVITY_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
-            String callingPackage = data.readString();
-            Intent intent = Intent.CREATOR.createFromParcel(data);
-            String resolvedType = data.readString();
-            IBinder resultTo = data.readStrongBinder();
-            String resultWho = data.readString();
-            int requestCode = data.readInt();
-            int startFlags = data.readInt();
-            ProfilerInfo profilerInfo = data.readInt() != 0
-                    ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
-            Bundle options = data.readInt() != 0
-                    ? Bundle.CREATOR.createFromParcel(data) : null;
-            int result = startActivity(app, callingPackage, intent, resolvedType,
-                    resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
-            reply.writeNoException();
-            reply.writeInt(result);
-            return true;
-        }
-
-        case START_ACTIVITY_AS_USER_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
-            String callingPackage = data.readString();
-            Intent intent = Intent.CREATOR.createFromParcel(data);
-            String resolvedType = data.readString();
-            IBinder resultTo = data.readStrongBinder();
-            String resultWho = data.readString();
-            int requestCode = data.readInt();
-            int startFlags = data.readInt();
-            ProfilerInfo profilerInfo = data.readInt() != 0
-                    ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
-            Bundle options = data.readInt() != 0
-                    ? Bundle.CREATOR.createFromParcel(data) : null;
-            int userId = data.readInt();
-            int result = startActivityAsUser(app, callingPackage, intent, resolvedType,
-                    resultTo, resultWho, requestCode, startFlags, profilerInfo, options, userId);
-            reply.writeNoException();
-            reply.writeInt(result);
-            return true;
-        }
-
-        case START_ACTIVITY_AS_CALLER_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
-            String callingPackage = data.readString();
-            Intent intent = Intent.CREATOR.createFromParcel(data);
-            String resolvedType = data.readString();
-            IBinder resultTo = data.readStrongBinder();
-            String resultWho = data.readString();
-            int requestCode = data.readInt();
-            int startFlags = data.readInt();
-            ProfilerInfo profilerInfo = data.readInt() != 0
-                    ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
-            Bundle options = data.readInt() != 0
-                    ? Bundle.CREATOR.createFromParcel(data) : null;
-            boolean ignoreTargetSecurity = data.readInt() != 0;
-            int userId = data.readInt();
-            int result = startActivityAsCaller(app, callingPackage, intent, resolvedType,
-                    resultTo, resultWho, requestCode, startFlags, profilerInfo, options,
-                    ignoreTargetSecurity, userId);
-            reply.writeNoException();
-            reply.writeInt(result);
-            return true;
-        }
-
-        case START_ACTIVITY_AND_WAIT_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
-            String callingPackage = data.readString();
-            Intent intent = Intent.CREATOR.createFromParcel(data);
-            String resolvedType = data.readString();
-            IBinder resultTo = data.readStrongBinder();
-            String resultWho = data.readString();
-            int requestCode = data.readInt();
-            int startFlags = data.readInt();
-            ProfilerInfo profilerInfo = data.readInt() != 0
-                    ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
-            Bundle options = data.readInt() != 0
-                    ? Bundle.CREATOR.createFromParcel(data) : null;
-            int userId = data.readInt();
-            WaitResult result = startActivityAndWait(app, callingPackage, intent, resolvedType,
-                    resultTo, resultWho, requestCode, startFlags, profilerInfo, options, userId);
-            reply.writeNoException();
-            result.writeToParcel(reply, 0);
-            return true;
-        }
-
-        case START_ACTIVITY_WITH_CONFIG_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
-            String callingPackage = data.readString();
-            Intent intent = Intent.CREATOR.createFromParcel(data);
-            String resolvedType = data.readString();
-            IBinder resultTo = data.readStrongBinder();
-            String resultWho = data.readString();
-            int requestCode = data.readInt();
-            int startFlags = data.readInt();
-            Configuration config = Configuration.CREATOR.createFromParcel(data);
-            Bundle options = data.readInt() != 0
-                    ? Bundle.CREATOR.createFromParcel(data) : null;
-            int userId = data.readInt();
-            int result = startActivityWithConfig(app, callingPackage, intent, resolvedType,
-                    resultTo, resultWho, requestCode, startFlags, config, options, userId);
-            reply.writeNoException();
-            reply.writeInt(result);
-            return true;
-        }
-
-        case START_ACTIVITY_INTENT_SENDER_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
-            IntentSender intent = IntentSender.CREATOR.createFromParcel(data);
-            Intent fillInIntent = null;
-            if (data.readInt() != 0) {
-                fillInIntent = Intent.CREATOR.createFromParcel(data);
-            }
-            String resolvedType = data.readString();
-            IBinder resultTo = data.readStrongBinder();
-            String resultWho = data.readString();
-            int requestCode = data.readInt();
-            int flagsMask = data.readInt();
-            int flagsValues = data.readInt();
-            Bundle options = data.readInt() != 0
-                    ? Bundle.CREATOR.createFromParcel(data) : null;
-            int result = startActivityIntentSender(app, intent,
-                    fillInIntent, resolvedType, resultTo, resultWho,
-                    requestCode, flagsMask, flagsValues, options);
-            reply.writeNoException();
-            reply.writeInt(result);
-            return true;
-        }
-
-        case START_VOICE_ACTIVITY_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            String callingPackage = data.readString();
-            int callingPid = data.readInt();
-            int callingUid = data.readInt();
-            Intent intent = Intent.CREATOR.createFromParcel(data);
-            String resolvedType = data.readString();
-            IVoiceInteractionSession session = IVoiceInteractionSession.Stub.asInterface(
-                    data.readStrongBinder());
-            IVoiceInteractor interactor = IVoiceInteractor.Stub.asInterface(
-                    data.readStrongBinder());
-            int startFlags = data.readInt();
-            ProfilerInfo profilerInfo = data.readInt() != 0
-                    ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
-            Bundle options = data.readInt() != 0
-                    ? Bundle.CREATOR.createFromParcel(data) : null;
-            int userId = data.readInt();
-            int result = startVoiceActivity(callingPackage, callingPid, callingUid, intent,
-                    resolvedType, session, interactor, startFlags, profilerInfo, options, userId);
-            reply.writeNoException();
-            reply.writeInt(result);
-            return true;
-        }
-
-        case START_LOCAL_VOICE_INTERACTION_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            Bundle options = data.readBundle();
-            startLocalVoiceInteraction(token, options);
-            reply.writeNoException();
-            return true;
-        }
-
-        case STOP_LOCAL_VOICE_INTERACTION_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            stopLocalVoiceInteraction(token);
-            reply.writeNoException();
-            return true;
-        }
-
-        case SUPPORTS_LOCAL_VOICE_INTERACTION_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            boolean result = supportsLocalVoiceInteraction();
-            reply.writeNoException();
-            reply.writeInt(result? 1 : 0);
-            return true;
-        }
-
-        case START_NEXT_MATCHING_ACTIVITY_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder callingActivity = data.readStrongBinder();
-            Intent intent = Intent.CREATOR.createFromParcel(data);
-            Bundle options = data.readInt() != 0
-                    ? Bundle.CREATOR.createFromParcel(data) : null;
-            boolean result = startNextMatchingActivity(callingActivity, intent, options);
-            reply.writeNoException();
-            reply.writeInt(result ? 1 : 0);
-            return true;
-        }
-
-        case START_ACTIVITY_FROM_RECENTS_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            final int taskId = data.readInt();
-            final Bundle options =
-                    data.readInt() == 0 ? null : Bundle.CREATOR.createFromParcel(data);
-            final int result = startActivityFromRecents(taskId, options);
-            reply.writeNoException();
-            reply.writeInt(result);
-            return true;
-        }
-
-        case FINISH_ACTIVITY_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            Intent resultData = null;
-            int resultCode = data.readInt();
-            if (data.readInt() != 0) {
-                resultData = Intent.CREATOR.createFromParcel(data);
-            }
-            int finishTask = data.readInt();
-            boolean res = finishActivity(token, resultCode, resultData, finishTask);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case FINISH_SUB_ACTIVITY_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            String resultWho = data.readString();
-            int requestCode = data.readInt();
-            finishSubActivity(token, resultWho, requestCode);
-            reply.writeNoException();
-            return true;
-        }
-
-        case FINISH_ACTIVITY_AFFINITY_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            boolean res = finishActivityAffinity(token);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case FINISH_VOICE_TASK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IVoiceInteractionSession session = IVoiceInteractionSession.Stub.asInterface(
-                    data.readStrongBinder());
-            finishVoiceTask(session);
-            reply.writeNoException();
-            return true;
-        }
-
-        case REQUEST_ACTIVITY_RELAUNCH: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            requestActivityRelaunch(token);
-            reply.writeNoException();
-            return true;
-        }
-
-        case RELEASE_ACTIVITY_INSTANCE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            boolean res = releaseActivityInstance(token);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case RELEASE_SOME_ACTIVITIES_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IApplicationThread app = IApplicationThread.Stub.asInterface(data.readStrongBinder());
-            releaseSomeActivities(app);
-            reply.writeNoException();
-            return true;
-        }
-
-        case WILL_ACTIVITY_BE_VISIBLE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            boolean res = willActivityBeVisible(token);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case REGISTER_RECEIVER_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app =
-                b != null ? IApplicationThread.Stub.asInterface(b) : null;
-            String packageName = data.readString();
-            b = data.readStrongBinder();
-            IIntentReceiver rec
-                = b != null ? IIntentReceiver.Stub.asInterface(b) : null;
-            IntentFilter filter = IntentFilter.CREATOR.createFromParcel(data);
-            String perm = data.readString();
-            int userId = data.readInt();
-            Intent intent = registerReceiver(app, packageName, rec, filter, perm, userId);
-            reply.writeNoException();
-            if (intent != null) {
-                reply.writeInt(1);
-                intent.writeToParcel(reply, 0);
-            } else {
-                reply.writeInt(0);
-            }
-            return true;
-        }
-
-        case UNREGISTER_RECEIVER_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            if (b == null) {
-                return true;
-            }
-            IIntentReceiver rec = IIntentReceiver.Stub.asInterface(b);
-            unregisterReceiver(rec);
-            reply.writeNoException();
-            return true;
-        }
-
-        case BROADCAST_INTENT_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app =
-                b != null ? IApplicationThread.Stub.asInterface(b) : null;
-            Intent intent = Intent.CREATOR.createFromParcel(data);
-            String resolvedType = data.readString();
-            b = data.readStrongBinder();
-            IIntentReceiver resultTo =
-                b != null ? IIntentReceiver.Stub.asInterface(b) : null;
-            int resultCode = data.readInt();
-            String resultData = data.readString();
-            Bundle resultExtras = data.readBundle();
-            String[] perms = data.readStringArray();
-            int appOp = data.readInt();
-            Bundle options = data.readBundle();
-            boolean serialized = data.readInt() != 0;
-            boolean sticky = data.readInt() != 0;
-            int userId = data.readInt();
-            int res = broadcastIntent(app, intent, resolvedType, resultTo,
-                    resultCode, resultData, resultExtras, perms, appOp,
-                    options, serialized, sticky, userId);
-            reply.writeNoException();
-            reply.writeInt(res);
-            return true;
-        }
-
-        case UNBROADCAST_INTENT_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = b != null ? IApplicationThread.Stub.asInterface(b) : null;
-            Intent intent = Intent.CREATOR.createFromParcel(data);
-            int userId = data.readInt();
-            unbroadcastIntent(app, intent, userId);
-            reply.writeNoException();
-            return true;
-        }
-
-        case FINISH_RECEIVER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder who = data.readStrongBinder();
-            int resultCode = data.readInt();
-            String resultData = data.readString();
-            Bundle resultExtras = data.readBundle();
-            boolean resultAbort = data.readInt() != 0;
-            int intentFlags = data.readInt();
-            if (who != null) {
-                finishReceiver(who, resultCode, resultData, resultExtras, resultAbort, intentFlags);
-            }
-            reply.writeNoException();
-            return true;
-        }
-
-        case ATTACH_APPLICATION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IApplicationThread app = IApplicationThread.Stub.asInterface(
-                    data.readStrongBinder());
-            if (app != null) {
-                attachApplication(app);
-            }
-            reply.writeNoException();
-            return true;
-        }
-
-        case ACTIVITY_IDLE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            Configuration config = null;
-            if (data.readInt() != 0) {
-                config = Configuration.CREATOR.createFromParcel(data);
-            }
-            boolean stopProfiling = data.readInt() != 0;
-            if (token != null) {
-                activityIdle(token, config, stopProfiling);
-            }
-            reply.writeNoException();
-            return true;
-        }
-
-        case ACTIVITY_RESUMED_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            activityResumed(token);
-            reply.writeNoException();
-            return true;
-        }
-
-        case ACTIVITY_PAUSED_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            activityPaused(token);
-            reply.writeNoException();
-            return true;
-        }
-
-        case ACTIVITY_STOPPED_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            Bundle map = data.readBundle();
-            PersistableBundle persistentState = data.readPersistableBundle();
-            CharSequence description = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(data);
-            activityStopped(token, map, persistentState, description);
-            reply.writeNoException();
-            return true;
-        }
-
-        case ACTIVITY_SLEPT_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            activitySlept(token);
-            reply.writeNoException();
-            return true;
-        }
-
-        case ACTIVITY_DESTROYED_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            activityDestroyed(token);
-            reply.writeNoException();
-            return true;
-        }
-
-        case ACTIVITY_RELAUNCHED_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            activityRelaunched(token);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_CALLING_PACKAGE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            String res = token != null ? getCallingPackage(token) : null;
-            reply.writeNoException();
-            reply.writeString(res);
-            return true;
-        }
-
-        case GET_CALLING_ACTIVITY_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            ComponentName cn = getCallingActivity(token);
-            reply.writeNoException();
-            ComponentName.writeToParcel(cn, reply);
-            return true;
-        }
-
-        case GET_APP_TASKS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String callingPackage = data.readString();
-            List<IAppTask> list = getAppTasks(callingPackage);
-            reply.writeNoException();
-            int N = list != null ? list.size() : -1;
-            reply.writeInt(N);
-            int i;
-            for (i=0; i<N; i++) {
-                IAppTask task = list.get(i);
-                reply.writeStrongBinder(task.asBinder());
-            }
-            return true;
-        }
-
-        case ADD_APP_TASK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder activityToken = data.readStrongBinder();
-            Intent intent = Intent.CREATOR.createFromParcel(data);
-            ActivityManager.TaskDescription descr
-                    = ActivityManager.TaskDescription.CREATOR.createFromParcel(data);
-            Bitmap thumbnail = Bitmap.CREATOR.createFromParcel(data);
-            int res = addAppTask(activityToken, intent, descr, thumbnail);
-            reply.writeNoException();
-            reply.writeInt(res);
-            return true;
-        }
-
-        case GET_APP_TASK_THUMBNAIL_SIZE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            Point size = getAppTaskThumbnailSize();
-            reply.writeNoException();
-            size.writeToParcel(reply, 0);
-            return true;
-        }
-
-        case GET_TASKS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int maxNum = data.readInt();
-            int fl = data.readInt();
-            List<ActivityManager.RunningTaskInfo> list = getTasks(maxNum, fl);
-            reply.writeNoException();
-            int N = list != null ? list.size() : -1;
-            reply.writeInt(N);
-            int i;
-            for (i=0; i<N; i++) {
-                ActivityManager.RunningTaskInfo info = list.get(i);
-                info.writeToParcel(reply, 0);
-            }
-            return true;
-        }
-
-        case GET_RECENT_TASKS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int maxNum = data.readInt();
-            int fl = data.readInt();
-            int userId = data.readInt();
-            ParceledListSlice<ActivityManager.RecentTaskInfo> list = getRecentTasks(maxNum,
-                    fl, userId);
-            reply.writeNoException();
-            list.writeToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-            return true;
-        }
-
-        case GET_TASK_THUMBNAIL_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int id = data.readInt();
-            ActivityManager.TaskThumbnail taskThumbnail = getTaskThumbnail(id);
-            reply.writeNoException();
-            if (taskThumbnail != null) {
-                reply.writeInt(1);
-                taskThumbnail.writeToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-            } else {
-                reply.writeInt(0);
-            }
-            return true;
-        }
-
-        case GET_SERVICES_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int maxNum = data.readInt();
-            int fl = data.readInt();
-            List<ActivityManager.RunningServiceInfo> list = getServices(maxNum, fl);
-            reply.writeNoException();
-            int N = list != null ? list.size() : -1;
-            reply.writeInt(N);
-            int i;
-            for (i=0; i<N; i++) {
-                ActivityManager.RunningServiceInfo info = list.get(i);
-                info.writeToParcel(reply, 0);
-            }
-            return true;
-        }
-
-        case GET_PROCESSES_IN_ERROR_STATE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            List<ActivityManager.ProcessErrorStateInfo> list = getProcessesInErrorState();
-            reply.writeNoException();
-            reply.writeTypedList(list);
-            return true;
-        }
-
-        case GET_RUNNING_APP_PROCESSES_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            List<ActivityManager.RunningAppProcessInfo> list = getRunningAppProcesses();
-            reply.writeNoException();
-            reply.writeTypedList(list);
-            return true;
-        }
-
-        case GET_RUNNING_EXTERNAL_APPLICATIONS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            List<ApplicationInfo> list = getRunningExternalApplications();
-            reply.writeNoException();
-            reply.writeTypedList(list);
-            return true;
-        }
-
-        case MOVE_STACK_TO_DISPLAY_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int stackId = data.readInt();
-            int displayId = data.readInt();
-            moveStackToDisplay(stackId, displayId);
-            reply.writeNoException();
-            return true;
-        }
-
-        case MOVE_TASK_TO_FRONT_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int task = data.readInt();
-            int fl = data.readInt();
-            Bundle options = data.readInt() != 0
-                    ? Bundle.CREATOR.createFromParcel(data) : null;
-            moveTaskToFront(task, fl, options);
-            reply.writeNoException();
-            return true;
-        }
-
-        case MOVE_ACTIVITY_TASK_TO_BACK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            boolean nonRoot = data.readInt() != 0;
-            boolean res = moveActivityTaskToBack(token, nonRoot);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case MOVE_TASK_BACKWARDS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int task = data.readInt();
-            moveTaskBackwards(task);
-            reply.writeNoException();
-            return true;
-        }
-
-        case MOVE_TASK_TO_STACK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int taskId = data.readInt();
-            int stackId = data.readInt();
-            boolean toTop = data.readInt() != 0;
-            moveTaskToStack(taskId, stackId, toTop);
-            reply.writeNoException();
-            return true;
-        }
-
-        case MOVE_TASK_TO_DOCKED_STACK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int taskId = data.readInt();
-            int createMode = data.readInt();
-            boolean toTop = data.readInt() != 0;
-            boolean animate = data.readInt() != 0;
-            Rect bounds = null;
-            boolean hasBounds = data.readInt() != 0;
-            if (hasBounds) {
-                bounds = Rect.CREATOR.createFromParcel(data);
-            }
-            final boolean moveHomeStackFront = data.readInt() != 0;
-            final boolean res = moveTaskToDockedStack(
-                    taskId, createMode, toTop, animate, bounds, moveHomeStackFront);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case MOVE_TOP_ACTIVITY_TO_PINNED_STACK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final int stackId = data.readInt();
-            final Rect r = Rect.CREATOR.createFromParcel(data);
-            final boolean res = moveTopActivityToPinnedStack(stackId, r);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case RESIZE_STACK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final int stackId = data.readInt();
-            final boolean hasRect = data.readInt() != 0;
-            Rect r = null;
-            if (hasRect) {
-                r = Rect.CREATOR.createFromParcel(data);
-            }
-            final boolean allowResizeInDockedMode = data.readInt() == 1;
-            final boolean preserveWindows = data.readInt() == 1;
-            final boolean animate = data.readInt() == 1;
-            final int animationDuration = data.readInt();
-            resizeStack(stackId,
-                    r, allowResizeInDockedMode, preserveWindows, animate, animationDuration);
-            reply.writeNoException();
-            return true;
-        }
-        case RESIZE_PINNED_STACK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final boolean hasBounds = data.readInt() != 0;
-            Rect bounds = null;
-            if (hasBounds) {
-                bounds = Rect.CREATOR.createFromParcel(data);
-            }
-            final boolean hasTempPinnedTaskBounds = data.readInt() != 0;
-            Rect tempPinnedTaskBounds = null;
-            if (hasTempPinnedTaskBounds) {
-                tempPinnedTaskBounds = Rect.CREATOR.createFromParcel(data);
-            }
-            resizePinnedStack(bounds, tempPinnedTaskBounds);
-            return true;
-        }
-        case SWAP_DOCKED_AND_FULLSCREEN_STACK: {
-            data.enforceInterface(IActivityManager.descriptor);
-            swapDockedAndFullscreenStack();
-            reply.writeNoException();
-            return true;
-        }
-        case RESIZE_DOCKED_STACK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final boolean hasBounds = data.readInt() != 0;
-            Rect bounds = null;
-            if (hasBounds) {
-                bounds = Rect.CREATOR.createFromParcel(data);
-            }
-            final boolean hasTempDockedTaskBounds = data.readInt() != 0;
-            Rect tempDockedTaskBounds = null;
-            if (hasTempDockedTaskBounds) {
-                tempDockedTaskBounds = Rect.CREATOR.createFromParcel(data);
-            }
-            final boolean hasTempDockedTaskInsetBounds = data.readInt() != 0;
-            Rect tempDockedTaskInsetBounds = null;
-            if (hasTempDockedTaskInsetBounds) {
-                tempDockedTaskInsetBounds = Rect.CREATOR.createFromParcel(data);
-            }
-            final boolean hasTempOtherTaskBounds = data.readInt() != 0;
-            Rect tempOtherTaskBounds = null;
-            if (hasTempOtherTaskBounds) {
-                tempOtherTaskBounds = Rect.CREATOR.createFromParcel(data);
-            }
-            final boolean hasTempOtherTaskInsetBounds = data.readInt() != 0;
-            Rect tempOtherTaskInsetBounds = null;
-            if (hasTempOtherTaskInsetBounds) {
-                tempOtherTaskInsetBounds = Rect.CREATOR.createFromParcel(data);
-            }
-            resizeDockedStack(bounds, tempDockedTaskBounds, tempDockedTaskInsetBounds,
-                    tempOtherTaskBounds, tempOtherTaskInsetBounds);
-            reply.writeNoException();
-            return true;
-        }
-
-        case POSITION_TASK_IN_STACK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int taskId = data.readInt();
-            int stackId = data.readInt();
-            int position = data.readInt();
-            positionTaskInStack(taskId, stackId, position);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_ALL_STACK_INFOS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            List<StackInfo> list = getAllStackInfos();
-            reply.writeNoException();
-            reply.writeTypedList(list);
-            return true;
-        }
-
-        case GET_STACK_INFO_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int stackId = data.readInt();
-            StackInfo info = getStackInfo(stackId);
-            reply.writeNoException();
-            if (info != null) {
-                reply.writeInt(1);
-                info.writeToParcel(reply, 0);
-            } else {
-                reply.writeInt(0);
-            }
-            return true;
-        }
-
-        case IS_IN_HOME_STACK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int taskId = data.readInt();
-            boolean isInHomeStack = isInHomeStack(taskId);
-            reply.writeNoException();
-            reply.writeInt(isInHomeStack ? 1 : 0);
-            return true;
-        }
-
-        case SET_FOCUSED_STACK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int stackId = data.readInt();
-            setFocusedStack(stackId);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_FOCUSED_STACK_ID_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int focusedStackId = getFocusedStackId();
-            reply.writeNoException();
-            reply.writeInt(focusedStackId);
-            return true;
-        }
-
-        case SET_FOCUSED_TASK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int taskId = data.readInt();
-            setFocusedTask(taskId);
-            reply.writeNoException();
-            return true;
-        }
-
-        case REGISTER_TASK_STACK_LISTENER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            registerTaskStackListener(ITaskStackListener.Stub.asInterface(token));
-            reply.writeNoException();
-            return true;
-        }
-
-        case UNREGISTER_TASK_STACK_LISTENER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            unregisterTaskStackListener(ITaskStackListener.Stub.asInterface(token));
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_TASK_FOR_ACTIVITY_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            boolean onlyRoot = data.readInt() != 0;
-            int res = token != null
-                ? getTaskForActivity(token, onlyRoot) : -1;
-                reply.writeNoException();
-            reply.writeInt(res);
-            return true;
-        }
-
-        case GET_CONTENT_PROVIDER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
-            String name = data.readString();
-            int userId = data.readInt();
-            boolean stable = data.readInt() != 0;
-            ContentProviderHolder cph = getContentProvider(app, name, userId, stable);
-            reply.writeNoException();
-            if (cph != null) {
-                reply.writeInt(1);
-                cph.writeToParcel(reply, 0);
-            } else {
-                reply.writeInt(0);
-            }
-            return true;
-        }
-
-        case GET_CONTENT_PROVIDER_EXTERNAL_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String name = data.readString();
-            int userId = data.readInt();
-            IBinder token = data.readStrongBinder();
-            ContentProviderHolder cph = getContentProviderExternal(name, userId, token);
-            reply.writeNoException();
-            if (cph != null) {
-                reply.writeInt(1);
-                cph.writeToParcel(reply, 0);
-            } else {
-                reply.writeInt(0);
-            }
-            return true;
-        }
-
-        case PUBLISH_CONTENT_PROVIDERS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
-            ArrayList<ContentProviderHolder> providers =
-                data.createTypedArrayList(ContentProviderHolder.CREATOR);
-            publishContentProviders(app, providers);
-            reply.writeNoException();
-            return true;
-        }
-
-        case REF_CONTENT_PROVIDER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            int stable = data.readInt();
-            int unstable = data.readInt();
-            boolean res = refContentProvider(b, stable, unstable);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case UNSTABLE_PROVIDER_DIED_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            unstableProviderDied(b);
-            reply.writeNoException();
-            return true;
-        }
-
-        case APP_NOT_RESPONDING_VIA_PROVIDER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            appNotRespondingViaProvider(b);
-            reply.writeNoException();
-            return true;
-        }
-
-        case REMOVE_CONTENT_PROVIDER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            boolean stable = data.readInt() != 0;
-            removeContentProvider(b, stable);
-            reply.writeNoException();
-            return true;
-        }
-
-        case REMOVE_CONTENT_PROVIDER_EXTERNAL_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String name = data.readString();
-            IBinder token = data.readStrongBinder();
-            removeContentProviderExternal(name, token);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_RUNNING_SERVICE_CONTROL_PANEL_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            ComponentName comp = ComponentName.CREATOR.createFromParcel(data);
-            PendingIntent pi = getRunningServiceControlPanel(comp);
-            reply.writeNoException();
-            PendingIntent.writePendingIntentOrNullToParcel(pi, reply);
-            return true;
-        }
-
-        case START_SERVICE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
-            Intent service = Intent.CREATOR.createFromParcel(data);
-            String resolvedType = data.readString();
-            String callingPackage = data.readString();
-            int userId = data.readInt();
-            ComponentName cn = startService(app, service, resolvedType, callingPackage, userId);
-            reply.writeNoException();
-            ComponentName.writeToParcel(cn, reply);
-            return true;
-        }
-
-        case STOP_SERVICE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
-            Intent service = Intent.CREATOR.createFromParcel(data);
-            String resolvedType = data.readString();
-            int userId = data.readInt();
-            int res = stopService(app, service, resolvedType, userId);
-            reply.writeNoException();
-            reply.writeInt(res);
-            return true;
-        }
-
-        case STOP_SERVICE_TOKEN_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            ComponentName className = ComponentName.readFromParcel(data);
-            IBinder token = data.readStrongBinder();
-            int startId = data.readInt();
-            boolean res = stopServiceToken(className, token, startId);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case SET_SERVICE_FOREGROUND_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            ComponentName className = ComponentName.readFromParcel(data);
-            IBinder token = data.readStrongBinder();
-            int id = data.readInt();
-            Notification notification = null;
-            if (data.readInt() != 0) {
-                notification = Notification.CREATOR.createFromParcel(data);
-            }
-            int sflags = data.readInt();
-            setServiceForeground(className, token, id, notification, sflags);
-            reply.writeNoException();
-            return true;
-        }
-
-        case BIND_SERVICE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
-            IBinder token = data.readStrongBinder();
-            Intent service = Intent.CREATOR.createFromParcel(data);
-            String resolvedType = data.readString();
-            b = data.readStrongBinder();
-            int fl = data.readInt();
-            String callingPackage = data.readString();
-            int userId = data.readInt();
-            IServiceConnection conn = IServiceConnection.Stub.asInterface(b);
-            int res = bindService(app, token, service, resolvedType, conn, fl,
-                    callingPackage, userId);
-            reply.writeNoException();
-            reply.writeInt(res);
-            return true;
-        }
-
-        case UNBIND_SERVICE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IServiceConnection conn = IServiceConnection.Stub.asInterface(b);
-            boolean res = unbindService(conn);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case PUBLISH_SERVICE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            Intent intent = Intent.CREATOR.createFromParcel(data);
-            IBinder service = data.readStrongBinder();
-            publishService(token, intent, service);
-            reply.writeNoException();
-            return true;
-        }
-
-        case UNBIND_FINISHED_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            Intent intent = Intent.CREATOR.createFromParcel(data);
-            boolean doRebind = data.readInt() != 0;
-            unbindFinished(token, intent, doRebind);
-            reply.writeNoException();
-            return true;
-        }
-
-        case SERVICE_DONE_EXECUTING_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            int type = data.readInt();
-            int startId = data.readInt();
-            int res = data.readInt();
-            serviceDoneExecuting(token, type, startId, res);
-            reply.writeNoException();
-            return true;
-        }
-
-        case START_INSTRUMENTATION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            ComponentName className = ComponentName.readFromParcel(data);
-            String profileFile = data.readString();
-            int fl = data.readInt();
-            Bundle arguments = data.readBundle();
-            IBinder b = data.readStrongBinder();
-            IInstrumentationWatcher w = IInstrumentationWatcher.Stub.asInterface(b);
-            b = data.readStrongBinder();
-            IUiAutomationConnection c = IUiAutomationConnection.Stub.asInterface(b);
-            int userId = data.readInt();
-            String abiOverride = data.readString();
-            boolean res = startInstrumentation(className, profileFile, fl, arguments, w, c, userId,
-                    abiOverride);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-
-        case FINISH_INSTRUMENTATION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
-            int resultCode = data.readInt();
-            Bundle results = data.readBundle();
-            finishInstrumentation(app, resultCode, results);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_CONFIGURATION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            Configuration config = getConfiguration();
-            reply.writeNoException();
-            config.writeToParcel(reply, 0);
-            return true;
-        }
-
-        case UPDATE_CONFIGURATION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            Configuration config = Configuration.CREATOR.createFromParcel(data);
-            final boolean updated = updateConfiguration(config);
-            reply.writeNoException();
-            reply.writeInt(updated ? 1 : 0);
-            return true;
-        }
-
-        case UPDATE_DISPLAY_OVERRIDE_CONFIGURATION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final Configuration config = Configuration.CREATOR.createFromParcel(data);
-            final int displayId = data.readInt();
-            final boolean updated = updateDisplayOverrideConfiguration(config, displayId);
-            reply.writeNoException();
-            reply.writeInt(updated ? 1 : 0);
-            return true;
-        }
-
-        case SET_REQUESTED_ORIENTATION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            int requestedOrientation = data.readInt();
-            setRequestedOrientation(token, requestedOrientation);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_REQUESTED_ORIENTATION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            int req = getRequestedOrientation(token);
-            reply.writeNoException();
-            reply.writeInt(req);
-            return true;
-        }
-
-        case GET_ACTIVITY_CLASS_FOR_TOKEN_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            ComponentName cn = getActivityClassForToken(token);
-            reply.writeNoException();
-            ComponentName.writeToParcel(cn, reply);
-            return true;
-        }
-
-        case GET_PACKAGE_FOR_TOKEN_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            reply.writeNoException();
-            reply.writeString(getPackageForToken(token));
-            return true;
-        }
-
-        case GET_INTENT_SENDER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int type = data.readInt();
-            String packageName = data.readString();
-            IBinder token = data.readStrongBinder();
-            String resultWho = data.readString();
-            int requestCode = data.readInt();
-            Intent[] requestIntents;
-            String[] requestResolvedTypes;
-            if (data.readInt() != 0) {
-                requestIntents = data.createTypedArray(Intent.CREATOR);
-                requestResolvedTypes = data.createStringArray();
-            } else {
-                requestIntents = null;
-                requestResolvedTypes = null;
-            }
-            int fl = data.readInt();
-            Bundle options = data.readInt() != 0
-                    ? Bundle.CREATOR.createFromParcel(data) : null;
-            int userId = data.readInt();
-            IIntentSender res = getIntentSender(type, packageName, token,
-                    resultWho, requestCode, requestIntents,
-                    requestResolvedTypes, fl, options, userId);
-            reply.writeNoException();
-            reply.writeStrongBinder(res != null ? res.asBinder() : null);
-            return true;
-        }
-
-        case CANCEL_INTENT_SENDER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IIntentSender r = IIntentSender.Stub.asInterface(
-                data.readStrongBinder());
-            cancelIntentSender(r);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_PACKAGE_FOR_INTENT_SENDER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IIntentSender r = IIntentSender.Stub.asInterface(
-                data.readStrongBinder());
-            String res = getPackageForIntentSender(r);
-            reply.writeNoException();
-            reply.writeString(res);
-            return true;
-        }
-
-        case GET_UID_FOR_INTENT_SENDER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IIntentSender r = IIntentSender.Stub.asInterface(
-                data.readStrongBinder());
-            int res = getUidForIntentSender(r);
-            reply.writeNoException();
-            reply.writeInt(res);
-            return true;
-        }
-
-        case HANDLE_INCOMING_USER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int callingPid = data.readInt();
-            int callingUid = data.readInt();
-            int userId = data.readInt();
-            boolean allowAll = data.readInt() != 0 ;
-            boolean requireFull = data.readInt() != 0;
-            String name = data.readString();
-            String callerPackage = data.readString();
-            int res = handleIncomingUser(callingPid, callingUid, userId, allowAll,
-                    requireFull, name, callerPackage);
-            reply.writeNoException();
-            reply.writeInt(res);
-            return true;
-        }
-
-        case SET_PROCESS_LIMIT_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int max = data.readInt();
-            setProcessLimit(max);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_PROCESS_LIMIT_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int limit = getProcessLimit();
-            reply.writeNoException();
-            reply.writeInt(limit);
-            return true;
-        }
-
-        case SET_PROCESS_FOREGROUND_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            int pid = data.readInt();
-            boolean isForeground = data.readInt() != 0;
-            setProcessForeground(token, pid, isForeground);
-            reply.writeNoException();
-            return true;
-        }
-
-        case CHECK_PERMISSION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String perm = data.readString();
-            int pid = data.readInt();
-            int uid = data.readInt();
-            int res = checkPermission(perm, pid, uid);
-            reply.writeNoException();
-            reply.writeInt(res);
-            return true;
-        }
-
-        case CHECK_PERMISSION_WITH_TOKEN_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String perm = data.readString();
-            int pid = data.readInt();
-            int uid = data.readInt();
-            IBinder token = data.readStrongBinder();
-            int res = checkPermissionWithToken(perm, pid, uid, token);
-            reply.writeNoException();
-            reply.writeInt(res);
-            return true;
-        }
-
-        case CHECK_URI_PERMISSION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            Uri uri = Uri.CREATOR.createFromParcel(data);
-            int pid = data.readInt();
-            int uid = data.readInt();
-            int mode = data.readInt();
-            int userId = data.readInt();
-            IBinder callerToken = data.readStrongBinder();
-            int res = checkUriPermission(uri, pid, uid, mode, userId, callerToken);
-            reply.writeNoException();
-            reply.writeInt(res);
-            return true;
-        }
-
-        case CLEAR_APP_DATA_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String packageName = data.readString();
-            IPackageDataObserver observer = IPackageDataObserver.Stub.asInterface(
-                    data.readStrongBinder());
-            int userId = data.readInt();
-            boolean res = clearApplicationUserData(packageName, observer, userId);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case GRANT_URI_PERMISSION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
-            String targetPkg = data.readString();
-            Uri uri = Uri.CREATOR.createFromParcel(data);
-            int mode = data.readInt();
-            int userId = data.readInt();
-            grantUriPermission(app, targetPkg, uri, mode, userId);
-            reply.writeNoException();
-            return true;
-        }
-
-        case REVOKE_URI_PERMISSION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
-            Uri uri = Uri.CREATOR.createFromParcel(data);
-            int mode = data.readInt();
-            int userId = data.readInt();
-            revokeUriPermission(app, uri, mode, userId);
-            reply.writeNoException();
-            return true;
-        }
-
-        case TAKE_PERSISTABLE_URI_PERMISSION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            Uri uri = Uri.CREATOR.createFromParcel(data);
-            int mode = data.readInt();
-            int userId = data.readInt();
-            takePersistableUriPermission(uri, mode, userId);
-            reply.writeNoException();
-            return true;
-        }
-
-        case RELEASE_PERSISTABLE_URI_PERMISSION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            Uri uri = Uri.CREATOR.createFromParcel(data);
-            int mode = data.readInt();
-            int userId = data.readInt();
-            releasePersistableUriPermission(uri, mode, userId);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_PERSISTED_URI_PERMISSIONS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final String packageName = data.readString();
-            final boolean incoming = data.readInt() != 0;
-            final ParceledListSlice<UriPermission> perms = getPersistedUriPermissions(
-                    packageName, incoming);
-            reply.writeNoException();
-            perms.writeToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-            return true;
-        }
-
-        case GET_GRANTED_URI_PERMISSIONS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final String packageName = data.readString();
-            final int userId = data.readInt();
-            final ParceledListSlice<UriPermission> perms = getGrantedUriPermissions(packageName,
-                    userId);
-            reply.writeNoException();
-            perms.writeToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-            return true;
-        }
-
-        case CLEAR_GRANTED_URI_PERMISSIONS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final String packageName = data.readString();
-            final int userId = data.readInt();
-            clearGrantedUriPermissions(packageName, userId);
-            reply.writeNoException();
-            return true;
-        }
-
-        case SHOW_WAITING_FOR_DEBUGGER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
-            boolean waiting = data.readInt() != 0;
-            showWaitingForDebugger(app, waiting);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_MEMORY_INFO_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
-            getMemoryInfo(mi);
-            reply.writeNoException();
-            mi.writeToParcel(reply, 0);
-            return true;
-        }
-
-        case UNHANDLED_BACK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            unhandledBack();
-            reply.writeNoException();
-            return true;
-        }
-
-        case OPEN_CONTENT_URI_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            Uri uri = Uri.parse(data.readString());
-            ParcelFileDescriptor pfd = openContentUri(uri);
-            reply.writeNoException();
-            if (pfd != null) {
-                reply.writeInt(1);
-                pfd.writeToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-            } else {
-                reply.writeInt(0);
-            }
-            return true;
-        }
-
-        case SET_LOCK_SCREEN_SHOWN_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final boolean showing = data.readInt() != 0;
-            setLockScreenShown(showing);
-            reply.writeNoException();
-            return true;
-        }
-
-        case SET_DEBUG_APP_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String pn = data.readString();
-            boolean wfd = data.readInt() != 0;
-            boolean per = data.readInt() != 0;
-            setDebugApp(pn, wfd, per);
-            reply.writeNoException();
-            return true;
-        }
-
-        case SET_ALWAYS_FINISH_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            boolean enabled = data.readInt() != 0;
-            setAlwaysFinish(enabled);
-            reply.writeNoException();
-            return true;
-        }
-
-        case SET_ACTIVITY_CONTROLLER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IActivityController watcher = IActivityController.Stub.asInterface(
-                    data.readStrongBinder());
-            boolean imAMonkey = data.readInt() != 0;
-            setActivityController(watcher, imAMonkey);
-            reply.writeNoException();
-            return true;
-        }
-
-        case SET_LENIENT_BACKGROUND_CHECK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            boolean enabled = data.readInt() != 0;
-            setLenientBackgroundCheck(enabled);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_MEMORY_TRIM_LEVEL_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int level = getMemoryTrimLevel();
-            reply.writeNoException();
-            reply.writeInt(level);
-            return true;
-        }
-
-        case ENTER_SAFE_MODE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            enterSafeMode();
-            reply.writeNoException();
-            return true;
-        }
-
-        case NOTE_WAKEUP_ALARM_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IIntentSender is = IIntentSender.Stub.asInterface(
-                    data.readStrongBinder());
-            int sourceUid = data.readInt();
-            String sourcePkg = data.readString();
-            String tag = data.readString();
-            noteWakeupAlarm(is, sourceUid, sourcePkg, tag);
-            reply.writeNoException();
-            return true;
-        }
-
-        case NOTE_ALARM_START_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IIntentSender is = IIntentSender.Stub.asInterface(
-                    data.readStrongBinder());
-            int sourceUid = data.readInt();
-            String tag = data.readString();
-            noteAlarmStart(is, sourceUid, tag);
-            reply.writeNoException();
-            return true;
-        }
-
-        case NOTE_ALARM_FINISH_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IIntentSender is = IIntentSender.Stub.asInterface(
-                    data.readStrongBinder());
-            int sourceUid = data.readInt();
-            String tag = data.readString();
-            noteAlarmFinish(is, sourceUid, tag);
-            reply.writeNoException();
-            return true;
-        }
-
-        case KILL_PIDS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int[] pids = data.createIntArray();
-            String reason = data.readString();
-            boolean secure = data.readInt() != 0;
-            boolean res = killPids(pids, reason, secure);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case KILL_PROCESSES_BELOW_FOREGROUND_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String reason = data.readString();
-            boolean res = killProcessesBelowForeground(reason);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case HANDLE_APPLICATION_CRASH_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder app = data.readStrongBinder();
-            ApplicationErrorReport.CrashInfo ci = new ApplicationErrorReport.CrashInfo(data);
-            handleApplicationCrash(app, ci);
-            reply.writeNoException();
-            return true;
-        }
-
-        case HANDLE_APPLICATION_WTF_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder app = data.readStrongBinder();
-            String tag = data.readString();
-            boolean system = data.readInt() != 0;
-            ApplicationErrorReport.CrashInfo ci = new ApplicationErrorReport.CrashInfo(data);
-            boolean res = handleApplicationWtf(app, tag, system, ci);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case HANDLE_APPLICATION_STRICT_MODE_VIOLATION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder app = data.readStrongBinder();
-            int violationMask = data.readInt();
-            StrictMode.ViolationInfo info = new StrictMode.ViolationInfo(data);
-            handleApplicationStrictModeViolation(app, violationMask, info);
-            reply.writeNoException();
-            return true;
-        }
-
-        case SIGNAL_PERSISTENT_PROCESSES_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int sig = data.readInt();
-            signalPersistentProcesses(sig);
-            reply.writeNoException();
-            return true;
-        }
-
-        case KILL_BACKGROUND_PROCESSES_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String packageName = data.readString();
-            int userId = data.readInt();
-            killBackgroundProcesses(packageName, userId);
-            reply.writeNoException();
-            return true;
-        }
-
-        case KILL_ALL_BACKGROUND_PROCESSES_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            killAllBackgroundProcesses();
-            reply.writeNoException();
-            return true;
-        }
-
-        case KILL_PACKAGE_DEPENDENTS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String packageName = data.readString();
-            int userId = data.readInt();
-            killPackageDependents(packageName, userId);
-            reply.writeNoException();
-            return true;
-        }
-
-        case FORCE_STOP_PACKAGE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String packageName = data.readString();
-            int userId = data.readInt();
-            forceStopPackage(packageName, userId);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_MY_MEMORY_STATE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            ActivityManager.RunningAppProcessInfo info =
-                    new ActivityManager.RunningAppProcessInfo();
-            getMyMemoryState(info);
-            reply.writeNoException();
-            info.writeToParcel(reply, 0);
-            return true;
-        }
-
-        case GET_DEVICE_CONFIGURATION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            ConfigurationInfo config = getDeviceConfigurationInfo();
-            reply.writeNoException();
-            config.writeToParcel(reply, 0);
-            return true;
-        }
-
-        case PROFILE_CONTROL_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String process = data.readString();
-            int userId = data.readInt();
-            boolean start = data.readInt() != 0;
-            int profileType = data.readInt();
-            ProfilerInfo profilerInfo = data.readInt() != 0
-                    ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
-            boolean res = profileControl(process, userId, start, profilerInfo, profileType);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case SHUTDOWN_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            boolean res = shutdown(data.readInt());
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case STOP_APP_SWITCHES_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            stopAppSwitches();
-            reply.writeNoException();
-            return true;
-        }
-
-        case RESUME_APP_SWITCHES_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            resumeAppSwitches();
-            reply.writeNoException();
-            return true;
-        }
-
-        case PEEK_SERVICE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            Intent service = Intent.CREATOR.createFromParcel(data);
-            String resolvedType = data.readString();
-            String callingPackage = data.readString();
-            IBinder binder = peekService(service, resolvedType, callingPackage);
-            reply.writeNoException();
-            reply.writeStrongBinder(binder);
-            return true;
-        }
-
-        case START_BACKUP_AGENT_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String packageName = data.readString();
-            int backupRestoreMode = data.readInt();
-            int userId = data.readInt();
-            boolean success = bindBackupAgent(packageName, backupRestoreMode, userId);
-            reply.writeNoException();
-            reply.writeInt(success ? 1 : 0);
-            return true;
-        }
-
-        case BACKUP_AGENT_CREATED_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String packageName = data.readString();
-            IBinder agent = data.readStrongBinder();
-            backupAgentCreated(packageName, agent);
-            reply.writeNoException();
-            return true;
-        }
-
-        case UNBIND_BACKUP_AGENT_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            ApplicationInfo info = ApplicationInfo.CREATOR.createFromParcel(data);
-            unbindBackupAgent(info);
-            reply.writeNoException();
-            return true;
-        }
-
-        case ADD_PACKAGE_DEPENDENCY_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String packageName = data.readString();
-            addPackageDependency(packageName);
-            reply.writeNoException();
-            return true;
-        }
-
-        case KILL_APPLICATION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String pkg = data.readString();
-            int appId = data.readInt();
-            int userId = data.readInt();
-            String reason = data.readString();
-            killApplication(pkg, appId, userId, reason);
-            reply.writeNoException();
-            return true;
-        }
-
-        case CLOSE_SYSTEM_DIALOGS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String reason = data.readString();
-            closeSystemDialogs(reason);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_PROCESS_MEMORY_INFO_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int[] pids = data.createIntArray();
-            Debug.MemoryInfo[] res =  getProcessMemoryInfo(pids);
-            reply.writeNoException();
-            reply.writeTypedArray(res, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-            return true;
-        }
-
-        case KILL_APPLICATION_PROCESS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String processName = data.readString();
-            int uid = data.readInt();
-            killApplicationProcess(processName, uid);
-            reply.writeNoException();
-            return true;
-        }
-
-        case OVERRIDE_PENDING_TRANSITION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            String packageName = data.readString();
-            int enterAnim = data.readInt();
-            int exitAnim = data.readInt();
-            overridePendingTransition(token, packageName, enterAnim, exitAnim);
-            reply.writeNoException();
-            return true;
-        }
-
-        case IS_USER_A_MONKEY_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            boolean areThey = isUserAMonkey();
-            reply.writeNoException();
-            reply.writeInt(areThey ? 1 : 0);
-            return true;
-        }
-
-        case SET_USER_IS_MONKEY_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final boolean monkey = (data.readInt() == 1);
-            setUserIsMonkey(monkey);
-            reply.writeNoException();
-            return true;
-        }
-
-        case FINISH_HEAVY_WEIGHT_APP_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            finishHeavyWeightApp();
-            reply.writeNoException();
-            return true;
-        }
-
-        case IS_IMMERSIVE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            boolean isit = isImmersive(token);
-            reply.writeNoException();
-            reply.writeInt(isit ? 1 : 0);
-            return true;
-        }
-
-        case IS_TOP_OF_TASK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            final boolean isTopOfTask = isTopOfTask(token);
-            reply.writeNoException();
-            reply.writeInt(isTopOfTask ? 1 : 0);
-            return true;
-        }
-
-        case CONVERT_FROM_TRANSLUCENT_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            boolean converted = convertFromTranslucent(token);
-            reply.writeNoException();
-            reply.writeInt(converted ? 1 : 0);
-            return true;
-        }
-
-        case CONVERT_TO_TRANSLUCENT_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            final Bundle bundle;
-            if (data.readInt() == 0) {
-                bundle = null;
-            } else {
-                bundle = data.readBundle();
-            }
-            final ActivityOptions options = ActivityOptions.fromBundle(bundle);
-            boolean converted = convertToTranslucent(token, options);
-            reply.writeNoException();
-            reply.writeInt(converted ? 1 : 0);
-            return true;
-        }
-
-        case GET_ACTIVITY_OPTIONS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            final ActivityOptions options = getActivityOptions(token);
-            reply.writeNoException();
-            reply.writeBundle(options == null ? null : options.toBundle());
-            return true;
-        }
-
-        case SET_IMMERSIVE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            boolean imm = data.readInt() == 1;
-            setImmersive(token, imm);
-            reply.writeNoException();
-            return true;
-        }
-
-        case IS_TOP_ACTIVITY_IMMERSIVE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            boolean isit = isTopActivityImmersive();
-            reply.writeNoException();
-            reply.writeInt(isit ? 1 : 0);
-            return true;
-        }
-
-        case CRASH_APPLICATION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int uid = data.readInt();
-            int initialPid = data.readInt();
-            String packageName = data.readString();
-            String message = data.readString();
-            crashApplication(uid, initialPid, packageName, message);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_PROVIDER_MIME_TYPE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            Uri uri = Uri.CREATOR.createFromParcel(data);
-            int userId = data.readInt();
-            String type = getProviderMimeType(uri, userId);
-            reply.writeNoException();
-            reply.writeString(type);
-            return true;
-        }
-
-        case NEW_URI_PERMISSION_OWNER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String name = data.readString();
-            IBinder perm = newUriPermissionOwner(name);
-            reply.writeNoException();
-            reply.writeStrongBinder(perm);
-            return true;
-        }
-
-        case GET_URI_PERMISSION_OWNER_FOR_ACTIVITY_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder activityToken = data.readStrongBinder();
-            IBinder perm = getUriPermissionOwnerForActivity(activityToken);
-            reply.writeNoException();
-            reply.writeStrongBinder(perm);
-            return true;
-        }
-
-        case GRANT_URI_PERMISSION_FROM_OWNER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder owner = data.readStrongBinder();
-            int fromUid = data.readInt();
-            String targetPkg = data.readString();
-            Uri uri = Uri.CREATOR.createFromParcel(data);
-            int mode = data.readInt();
-            int sourceUserId = data.readInt();
-            int targetUserId = data.readInt();
-            grantUriPermissionFromOwner(owner, fromUid, targetPkg, uri, mode, sourceUserId,
-                    targetUserId);
-            reply.writeNoException();
-            return true;
-        }
-
-        case REVOKE_URI_PERMISSION_FROM_OWNER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder owner = data.readStrongBinder();
-            Uri uri = null;
-            if (data.readInt() != 0) {
-                uri = Uri.CREATOR.createFromParcel(data);
-            }
-            int mode = data.readInt();
-            int userId = data.readInt();
-            revokeUriPermissionFromOwner(owner, uri, mode, userId);
-            reply.writeNoException();
-            return true;
-        }
-
-        case CHECK_GRANT_URI_PERMISSION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int callingUid = data.readInt();
-            String targetPkg = data.readString();
-            Uri uri = Uri.CREATOR.createFromParcel(data);
-            int modeFlags = data.readInt();
-            int userId = data.readInt();
-            int res = checkGrantUriPermission(callingUid, targetPkg, uri, modeFlags, userId);
-            reply.writeNoException();
-            reply.writeInt(res);
-            return true;
-        }
-
-        case DUMP_HEAP_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String process = data.readString();
-            int userId = data.readInt();
-            boolean managed = data.readInt() != 0;
-            String path = data.readString();
-            ParcelFileDescriptor fd = data.readInt() != 0
-                    ? ParcelFileDescriptor.CREATOR.createFromParcel(data) : null;
-            boolean res = dumpHeap(process, userId, managed, path, fd);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case START_ACTIVITIES_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
-            String callingPackage = data.readString();
-            Intent[] intents = data.createTypedArray(Intent.CREATOR);
-            String[] resolvedTypes = data.createStringArray();
-            IBinder resultTo = data.readStrongBinder();
-            Bundle options = data.readInt() != 0
-                    ? Bundle.CREATOR.createFromParcel(data) : null;
-            int userId = data.readInt();
-            int result = startActivities(app, callingPackage, intents, resolvedTypes, resultTo,
-                    options, userId);
-            reply.writeNoException();
-            reply.writeInt(result);
-            return true;
-        }
-
-        case GET_FRONT_ACTIVITY_SCREEN_COMPAT_MODE_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            int mode = getFrontActivityScreenCompatMode();
-            reply.writeNoException();
-            reply.writeInt(mode);
-            return true;
-        }
-
-        case SET_FRONT_ACTIVITY_SCREEN_COMPAT_MODE_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            int mode = data.readInt();
-            setFrontActivityScreenCompatMode(mode);
-            reply.writeNoException();
-            reply.writeInt(mode);
-            return true;
-        }
-
-        case GET_PACKAGE_SCREEN_COMPAT_MODE_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            String pkg = data.readString();
-            int mode = getPackageScreenCompatMode(pkg);
-            reply.writeNoException();
-            reply.writeInt(mode);
-            return true;
-        }
-
-        case SET_PACKAGE_SCREEN_COMPAT_MODE_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            String pkg = data.readString();
-            int mode = data.readInt();
-            setPackageScreenCompatMode(pkg, mode);
-            reply.writeNoException();
-            return true;
-        }
-
-        case SWITCH_USER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int userid = data.readInt();
-            boolean result = switchUser(userid);
-            reply.writeNoException();
-            reply.writeInt(result ? 1 : 0);
-            return true;
-        }
-
-        case START_USER_IN_BACKGROUND_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int userid = data.readInt();
-            boolean result = startUserInBackground(userid);
-            reply.writeNoException();
-            reply.writeInt(result ? 1 : 0);
-            return true;
-        }
-
-        case UNLOCK_USER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int userId = data.readInt();
-            byte[] token = data.createByteArray();
-            byte[] secret = data.createByteArray();
-            IProgressListener listener = IProgressListener.Stub
-                    .asInterface(data.readStrongBinder());
-            boolean result = unlockUser(userId, token, secret, listener);
-            reply.writeNoException();
-            reply.writeInt(result ? 1 : 0);
-            return true;
-        }
-
-        case STOP_USER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int userid = data.readInt();
-            boolean force = data.readInt() != 0;
-            IStopUserCallback callback = IStopUserCallback.Stub.asInterface(
-                    data.readStrongBinder());
-            int result = stopUser(userid, force, callback);
-            reply.writeNoException();
-            reply.writeInt(result);
-            return true;
-        }
-
-        case GET_CURRENT_USER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            UserInfo userInfo = getCurrentUser();
-            reply.writeNoException();
-            userInfo.writeToParcel(reply, 0);
-            return true;
-        }
-
-        case IS_USER_RUNNING_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int userid = data.readInt();
-            int _flags = data.readInt();
-            boolean result = isUserRunning(userid, _flags);
-            reply.writeNoException();
-            reply.writeInt(result ? 1 : 0);
-            return true;
-        }
-
-        case GET_RUNNING_USER_IDS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int[] result = getRunningUserIds();
-            reply.writeNoException();
-            reply.writeIntArray(result);
-            return true;
-        }
-
-        case REMOVE_TASK_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            int taskId = data.readInt();
-            boolean result = removeTask(taskId);
-            reply.writeNoException();
-            reply.writeInt(result ? 1 : 0);
-            return true;
-        }
-
-        case REGISTER_PROCESS_OBSERVER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IProcessObserver observer = IProcessObserver.Stub.asInterface(
-                    data.readStrongBinder());
-            registerProcessObserver(observer);
-            return true;
-        }
-
-        case UNREGISTER_PROCESS_OBSERVER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IProcessObserver observer = IProcessObserver.Stub.asInterface(
-                    data.readStrongBinder());
-            unregisterProcessObserver(observer);
-            return true;
-        }
-
-        case REGISTER_UID_OBSERVER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IUidObserver observer = IUidObserver.Stub.asInterface(
-                    data.readStrongBinder());
-            int which = data.readInt();
-            registerUidObserver(observer, which);
-            return true;
-        }
-
-        case UNREGISTER_UID_OBSERVER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IUidObserver observer = IUidObserver.Stub.asInterface(
-                    data.readStrongBinder());
-            unregisterUidObserver(observer);
-            return true;
-        }
-
-        case GET_PACKAGE_ASK_SCREEN_COMPAT_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            String pkg = data.readString();
-            boolean ask = getPackageAskScreenCompat(pkg);
-            reply.writeNoException();
-            reply.writeInt(ask ? 1 : 0);
-            return true;
-        }
-
-        case SET_PACKAGE_ASK_SCREEN_COMPAT_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            String pkg = data.readString();
-            boolean ask = data.readInt() != 0;
-            setPackageAskScreenCompat(pkg, ask);
-            reply.writeNoException();
-            return true;
-        }
-
-        case IS_INTENT_SENDER_TARGETED_TO_PACKAGE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IIntentSender r = IIntentSender.Stub.asInterface(
-                    data.readStrongBinder());
-            boolean res = isIntentSenderTargetedToPackage(r);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case IS_INTENT_SENDER_AN_ACTIVITY_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IIntentSender r = IIntentSender.Stub.asInterface(
-                data.readStrongBinder());
-            boolean res = isIntentSenderAnActivity(r);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case GET_INTENT_FOR_INTENT_SENDER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IIntentSender r = IIntentSender.Stub.asInterface(
-                data.readStrongBinder());
-            Intent intent = getIntentForIntentSender(r);
-            reply.writeNoException();
-            if (intent != null) {
-                reply.writeInt(1);
-                intent.writeToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-            } else {
-                reply.writeInt(0);
-            }
-            return true;
-        }
-
-        case GET_TAG_FOR_INTENT_SENDER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IIntentSender r = IIntentSender.Stub.asInterface(
-                data.readStrongBinder());
-            String prefix = data.readString();
-            String tag = getTagForIntentSender(r, prefix);
-            reply.writeNoException();
-            reply.writeString(tag);
-            return true;
-        }
-
-        case UPDATE_PERSISTENT_CONFIGURATION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            Configuration config = Configuration.CREATOR.createFromParcel(data);
-            updatePersistentConfiguration(config);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_PROCESS_PSS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int[] pids = data.createIntArray();
-            long[] pss = getProcessPss(pids);
-            reply.writeNoException();
-            reply.writeLongArray(pss);
-            return true;
-        }
-
-        case SHOW_BOOT_MESSAGE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            CharSequence msg = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(data);
-            boolean always = data.readInt() != 0;
-            showBootMessage(msg, always);
-            reply.writeNoException();
-            return true;
-        }
-
-        case KEYGUARD_GOING_AWAY_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            keyguardGoingAway(data.readInt());
-            reply.writeNoException();
-            return true;
-        }
-
-        case SHOULD_UP_RECREATE_TASK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            String destAffinity = data.readString();
-            boolean res = shouldUpRecreateTask(token, destAffinity);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case NAVIGATE_UP_TO_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            Intent target = Intent.CREATOR.createFromParcel(data);
-            int resultCode = data.readInt();
-            Intent resultData = null;
-            if (data.readInt() != 0) {
-                resultData = Intent.CREATOR.createFromParcel(data);
-            }
-            boolean res = navigateUpTo(token, target, resultCode, resultData);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case GET_LAUNCHED_FROM_UID_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            int res = getLaunchedFromUid(token);
-            reply.writeNoException();
-            reply.writeInt(res);
-            return true;
-        }
-
-        case GET_LAUNCHED_FROM_PACKAGE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            String res = getLaunchedFromPackage(token);
-            reply.writeNoException();
-            reply.writeString(res);
-            return true;
-        }
-
-        case REGISTER_USER_SWITCH_OBSERVER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IUserSwitchObserver observer = IUserSwitchObserver.Stub.asInterface(
-                    data.readStrongBinder());
-            String name = data.readString();
-            registerUserSwitchObserver(observer, name);
-            reply.writeNoException();
-            return true;
-        }
-
-        case UNREGISTER_USER_SWITCH_OBSERVER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IUserSwitchObserver observer = IUserSwitchObserver.Stub.asInterface(
-                    data.readStrongBinder());
-            unregisterUserSwitchObserver(observer);
-            reply.writeNoException();
-            return true;
-        }
-
-        case REQUEST_BUG_REPORT_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int bugreportType = data.readInt();
-            requestBugReport(bugreportType);
-            reply.writeNoException();
-            return true;
-        }
-
-        case INPUT_DISPATCHING_TIMED_OUT_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int pid = data.readInt();
-            boolean aboveSystem = data.readInt() != 0;
-            String reason = data.readString();
-            long res = inputDispatchingTimedOut(pid, aboveSystem, reason);
-            reply.writeNoException();
-            reply.writeLong(res);
-            return true;
-        }
-
-        case GET_ASSIST_CONTEXT_EXTRAS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int requestType = data.readInt();
-            Bundle res = getAssistContextExtras(requestType);
-            reply.writeNoException();
-            reply.writeBundle(res);
-            return true;
-        }
-
-        case REQUEST_ASSIST_CONTEXT_EXTRAS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int requestType = data.readInt();
-            IResultReceiver receiver = IResultReceiver.Stub.asInterface(data.readStrongBinder());
-            Bundle receiverExtras = data.readBundle();
-            IBinder activityToken = data.readStrongBinder();
-            boolean focused = data.readInt() == 1;
-            boolean newSessionId = data.readInt() == 1;
-            boolean res = requestAssistContextExtras(requestType, receiver, receiverExtras,
-                    activityToken, focused, newSessionId);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case REPORT_ASSIST_CONTEXT_EXTRAS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            Bundle extras = data.readBundle();
-            AssistStructure structure = AssistStructure.CREATOR.createFromParcel(data);
-            AssistContent content = AssistContent.CREATOR.createFromParcel(data);
-            Uri referrer = data.readInt() != 0 ? Uri.CREATOR.createFromParcel(data) : null;
-            reportAssistContextExtras(token, extras, structure, content, referrer);
-            reply.writeNoException();
-            return true;
-        }
-
-        case LAUNCH_ASSIST_INTENT_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            Intent intent = Intent.CREATOR.createFromParcel(data);
-            int requestType = data.readInt();
-            String hint = data.readString();
-            int userHandle = data.readInt();
-            Bundle args = data.readBundle();
-            boolean res = launchAssistIntent(intent, requestType, hint, userHandle, args);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case IS_SCREEN_CAPTURE_ALLOWED_ON_CURRENT_ACTIVITY_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            boolean res = isAssistDataAllowedOnCurrentActivity();
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case SHOW_ASSIST_FROM_ACTIVITY_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            Bundle args = data.readBundle();
-            boolean res = showAssistFromActivity(token, args);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case KILL_UID_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int appId = data.readInt();
-            int userId = data.readInt();
-            String reason = data.readString();
-            killUid(appId, userId, reason);
-            reply.writeNoException();
-            return true;
-        }
-
-        case HANG_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder who = data.readStrongBinder();
-            boolean allowRestart = data.readInt() != 0;
-            hang(who, allowRestart);
-            reply.writeNoException();
-            return true;
-        }
-
-        case REPORT_ACTIVITY_FULLY_DRAWN_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            reportActivityFullyDrawn(token);
-            reply.writeNoException();
-            return true;
-        }
-
-        case NOTIFY_ACTIVITY_DRAWN_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            notifyActivityDrawn(token);
-            reply.writeNoException();
-            return true;
-        }
-
-        case RESTART_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            restart();
-            reply.writeNoException();
-            return true;
-        }
-
-        case PERFORM_IDLE_MAINTENANCE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            performIdleMaintenance();
-            reply.writeNoException();
-            return true;
-        }
-
-        case CREATE_VIRTUAL_ACTIVITY_CONTAINER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder parentActivityToken = data.readStrongBinder();
-            IActivityContainerCallback callback =
-                    IActivityContainerCallback.Stub.asInterface(data.readStrongBinder());
-            IActivityContainer activityContainer =
-                    createVirtualActivityContainer(parentActivityToken, callback);
-            reply.writeNoException();
-            if (activityContainer != null) {
-                reply.writeInt(1);
-                reply.writeStrongBinder(activityContainer.asBinder());
-            } else {
-                reply.writeInt(0);
-            }
-            return true;
-        }
-
-        case CREATE_STACK_ON_DISPLAY: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int displayId = data.readInt();
-            IActivityContainer activityContainer = createStackOnDisplay(displayId);
-            reply.writeNoException();
-            if (activityContainer != null) {
-                reply.writeInt(1);
-                reply.writeStrongBinder(activityContainer.asBinder());
-            } else {
-                reply.writeInt(0);
-            }
-            return true;
-        }
-
-        case GET_ACTIVITY_DISPLAY_ID_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder activityToken = data.readStrongBinder();
-            int displayId = getActivityDisplayId(activityToken);
-            reply.writeNoException();
-            reply.writeInt(displayId);
-            return true;
-        }
-
-        case START_LOCK_TASK_BY_TASK_ID_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final int taskId = data.readInt();
-            startLockTaskMode(taskId);
-            reply.writeNoException();
-            return true;
-        }
-
-        case START_LOCK_TASK_BY_TOKEN_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            startLockTaskMode(token);
-            reply.writeNoException();
-            return true;
-        }
-
-        case START_SYSTEM_LOCK_TASK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int taskId = data.readInt();
-            startSystemLockTaskMode(taskId);
-            reply.writeNoException();
-            return true;
-        }
-
-        case STOP_LOCK_TASK_MODE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            stopLockTaskMode();
-            reply.writeNoException();
-            return true;
-        }
-
-        case STOP_SYSTEM_LOCK_TASK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            stopSystemLockTaskMode();
-            reply.writeNoException();
-            return true;
-        }
-
-        case IS_IN_LOCK_TASK_MODE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final boolean isInLockTaskMode = isInLockTaskMode();
-            reply.writeNoException();
-            reply.writeInt(isInLockTaskMode ? 1 : 0);
-            return true;
-        }
-
-        case GET_LOCK_TASK_MODE_STATE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final int lockTaskModeState = getLockTaskModeState();
-            reply.writeNoException();
-            reply.writeInt(lockTaskModeState);
-            return true;
-        }
-
-        case SHOW_LOCK_TASK_ESCAPE_MESSAGE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final IBinder token = data.readStrongBinder();
-            showLockTaskEscapeMessage(token);
-            reply.writeNoException();
-            return true;
-        }
-
-        case SET_TASK_DESCRIPTION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            ActivityManager.TaskDescription values =
-                    ActivityManager.TaskDescription.CREATOR.createFromParcel(data);
-            setTaskDescription(token, values);
-            reply.writeNoException();
-            return true;
-        }
-
-        case SET_TASK_RESIZEABLE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final int taskId = data.readInt();
-            final int resizeableMode = data.readInt();
-            setTaskResizeable(taskId, resizeableMode);
-            reply.writeNoException();
-            return true;
-        }
-
-        case RESIZE_TASK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int taskId = data.readInt();
-            int resizeMode = data.readInt();
-            Rect r = Rect.CREATOR.createFromParcel(data);
-            resizeTask(taskId, r, resizeMode);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_TASK_BOUNDS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int taskId = data.readInt();
-            Rect r = getTaskBounds(taskId);
-            reply.writeNoException();
-            r.writeToParcel(reply, 0);
-            return true;
-        }
-
-        case GET_TASK_DESCRIPTION_ICON_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String filename = data.readString();
-            int userId = data.readInt();
-            Bitmap icon = getTaskDescriptionIcon(filename, userId);
-            reply.writeNoException();
-            if (icon == null) {
-                reply.writeInt(0);
-            } else {
-                reply.writeInt(1);
-                icon.writeToParcel(reply, 0);
-            }
-            return true;
-        }
-
-        case START_IN_PLACE_ANIMATION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final Bundle bundle;
-            if (data.readInt() == 0) {
-                bundle = null;
-            } else {
-                bundle = data.readBundle();
-            }
-            final ActivityOptions options = ActivityOptions.fromBundle(bundle);
-            startInPlaceAnimationOnFrontMostApplication(options);
-            reply.writeNoException();
-            return true;
-        }
-
-        case REQUEST_VISIBLE_BEHIND_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            boolean enable = data.readInt() > 0;
-            boolean success = requestVisibleBehind(token, enable);
-            reply.writeNoException();
-            reply.writeInt(success ? 1 : 0);
-            return true;
-        }
-
-        case IS_BACKGROUND_VISIBLE_BEHIND_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            final boolean enabled = isBackgroundVisibleBehind(token);
-            reply.writeNoException();
-            reply.writeInt(enabled ? 1 : 0);
-            return true;
-        }
-
-        case BACKGROUND_RESOURCES_RELEASED_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            backgroundResourcesReleased(token);
-            reply.writeNoException();
-            return true;
-        }
-
-        case NOTIFY_LAUNCH_TASK_BEHIND_COMPLETE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            notifyLaunchTaskBehindComplete(token);
-            reply.writeNoException();
-            return true;
-        }
-
-        case NOTIFY_ENTER_ANIMATION_COMPLETE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            notifyEnterAnimationComplete(token);
-            reply.writeNoException();
-            return true;
-        }
-
-        case BOOT_ANIMATION_COMPLETE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            bootAnimationComplete();
-            reply.writeNoException();
-            return true;
-        }
-
-        case NOTIFY_CLEARTEXT_NETWORK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final int uid = data.readInt();
-            final byte[] firstPacket = data.createByteArray();
-            notifyCleartextNetwork(uid, firstPacket);
-            reply.writeNoException();
-            return true;
-        }
-
-        case SET_DUMP_HEAP_DEBUG_LIMIT_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String procName = data.readString();
-            int uid = data.readInt();
-            long maxMemSize = data.readLong();
-            String reportPackage = data.readString();
-            setDumpHeapDebugLimit(procName, uid, maxMemSize, reportPackage);
-            reply.writeNoException();
-            return true;
-        }
-
-        case DUMP_HEAP_FINISHED_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String path = data.readString();
-            dumpHeapFinished(path);
-            reply.writeNoException();
-            return true;
-        }
-
-        case SET_VOICE_KEEP_AWAKE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IVoiceInteractionSession session = IVoiceInteractionSession.Stub.asInterface(
-                    data.readStrongBinder());
-            boolean keepAwake = data.readInt() != 0;
-            setVoiceKeepAwake(session, keepAwake);
-            reply.writeNoException();
-            return true;
-        }
-
-        case UPDATE_LOCK_TASK_PACKAGES_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int userId = data.readInt();
-            String[] packages = data.readStringArray();
-            updateLockTaskPackages(userId, packages);
-            reply.writeNoException();
-            return true;
-        }
-
-        case UPDATE_DEVICE_OWNER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String packageName = data.readString();
-            updateDeviceOwner(packageName);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_PACKAGE_PROCESS_STATE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String pkg = data.readString();
-            String callingPackage = data.readString();
-            int res = getPackageProcessState(pkg, callingPackage);
-            reply.writeNoException();
-            reply.writeInt(res);
-            return true;
-        }
-
-        case SET_PROCESS_MEMORY_TRIM_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String process = data.readString();
-            int userId = data.readInt();
-            int level = data.readInt();
-            boolean res = setProcessMemoryTrimLevel(process, userId, level);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case IS_ROOT_VOICE_INTERACTION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            boolean res = isRootVoiceInteraction(token);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case START_BINDER_TRACKING_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            boolean res = startBinderTracking();
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case STOP_BINDER_TRACKING_AND_DUMP_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            ParcelFileDescriptor fd = data.readInt() != 0
-                    ? ParcelFileDescriptor.CREATOR.createFromParcel(data) : null;
-            boolean res = stopBinderTrackingAndDump(fd);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-        case GET_ACTIVITY_STACK_ID_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            int stackId = getActivityStackId(token);
-            reply.writeNoException();
-            reply.writeInt(stackId);
-            return true;
-        }
-        case EXIT_FREEFORM_MODE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            exitFreeformMode(token);
-            reply.writeNoException();
-            return true;
-        }
-        case REPORT_SIZE_CONFIGURATIONS: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            int[] horizontal = readIntArray(data);
-            int[] vertical = readIntArray(data);
-            int[] smallest = readIntArray(data);
-            reportSizeConfigurations(token, horizontal, vertical, smallest);
-            return true;
-        }
-        case SUPPRESS_RESIZE_CONFIG_CHANGES_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final boolean suppress = data.readInt() == 1;
-            suppressResizeConfigChanges(suppress);
-            reply.writeNoException();
-            return true;
-        }
-        case MOVE_TASKS_TO_FULLSCREEN_STACK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final int stackId = data.readInt();
-            final boolean onTop = data.readInt() == 1;
-            moveTasksToFullscreenStack(stackId, onTop);
-            reply.writeNoException();
-            return true;
-        }
-        case GET_APP_START_MODE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final int uid = data.readInt();
-            final String pkg = data.readString();
-            int res = getAppStartMode(uid, pkg);
-            reply.writeNoException();
-            reply.writeInt(res);
-            return true;
-        }
-        case IN_MULTI_WINDOW_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final IBinder token = data.readStrongBinder();
-            final boolean inMultiWindow = isInMultiWindowMode(token);
-            reply.writeNoException();
-            reply.writeInt(inMultiWindow ? 1 : 0);
-            return true;
-        }
-        case IN_PICTURE_IN_PICTURE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final IBinder token = data.readStrongBinder();
-            final boolean inPip = isInPictureInPictureMode(token);
-            reply.writeNoException();
-            reply.writeInt(inPip ? 1 : 0);
-            return true;
-        }
-        case ENTER_PICTURE_IN_PICTURE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final IBinder token = data.readStrongBinder();
-            enterPictureInPictureMode(token);
-            reply.writeNoException();
-            return true;
-        }
-        case SET_VR_MODE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final IBinder token = data.readStrongBinder();
-            final boolean enable = data.readInt() == 1;
-            final ComponentName packageName = ComponentName.CREATOR.createFromParcel(data);
-            int res = setVrMode(token, enable, packageName);
-            reply.writeNoException();
-            reply.writeInt(res);
-            return true;
-        }
-        case IS_VR_PACKAGE_ENABLED_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final ComponentName packageName = ComponentName.CREATOR.createFromParcel(data);
-            boolean res = isVrModePackageEnabled(packageName);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-        case IS_APP_FOREGROUND_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final int userHandle = data.readInt();
-            final boolean isForeground = isAppForeground(userHandle);
-            reply.writeNoException();
-            reply.writeInt(isForeground ? 1 : 0);
-            return true;
-        }
-        case NOTIFY_PINNED_STACK_ANIMATION_ENDED_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            reply.writeNoException();
-            return true;
-        }
-        case REMOVE_STACK: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final int stackId = data.readInt();
-            removeStack(stackId);
-            reply.writeNoException();
-            return true;
-        }
-        case NOTIFY_LOCKED_PROFILE: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final int userId = data.readInt();
-            notifyLockedProfile(userId);
-            reply.writeNoException();
-            return true;
-        }
-        case START_CONFIRM_DEVICE_CREDENTIAL_INTENT: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final Intent intent = Intent.CREATOR.createFromParcel(data);
-            startConfirmDeviceCredentialIntent(intent);
-            reply.writeNoException();
-            return true;
-        }
-        case SEND_IDLE_JOB_TRIGGER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            sendIdleJobTrigger();
-            reply.writeNoException();
-            return true;
-        }
-        case SEND_INTENT_SENDER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IIntentSender sender = IIntentSender.Stub.asInterface(data.readStrongBinder());
-            int scode = data.readInt();
-            Intent intent = data.readInt() != 0 ? Intent.CREATOR.createFromParcel(data) : null;
-            String resolvedType = data.readString();
-            IIntentReceiver finishedReceiver = IIntentReceiver.Stub.asInterface(
-                    data.readStrongBinder());
-            String requiredPermission = data.readString();
-            Bundle options = data.readInt() != 0 ? Bundle.CREATOR.createFromParcel(data) : null;
-            int result = sendIntentSender(sender, scode, intent, resolvedType, finishedReceiver,
-                    requiredPermission, options);
-            reply.writeNoException();
-            reply.writeInt(result);
-            return true;
-        }
-        case SET_VR_THREAD_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final int tid = data.readInt();
-            setVrThread(tid);
-            reply.writeNoException();
-            return true;
-        }
-        case SET_RENDER_THREAD_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final int tid = data.readInt();
-            setRenderThread(tid);
-            reply.writeNoException();
-            return true;
-        }
-        case SET_HAS_TOP_UI: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final boolean hasTopUi = data.readInt() != 0;
-            setHasTopUi(hasTopUi);
-            reply.writeNoException();
-            return true;
-        }
-        case CAN_BYPASS_WORK_CHALLENGE: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final PendingIntent intent = PendingIntent.CREATOR.createFromParcel(data);
-            final boolean result = canBypassWorkChallenge(intent);
-            reply.writeNoException();
-            reply.writeInt(result ? 1 : 0);
-            return true;
-        }
-        }
-
-        return super.onTransact(code, data, reply, flags);
-    }
-
-    private int[] readIntArray(Parcel data) {
-        int[] smallest = null;
-        int smallestSize = data.readInt();
-        if (smallestSize > 0) {
-            smallest = new int[smallestSize];
-            data.readIntArray(smallest);
-        }
-        return smallest;
-    }
-
-    public IBinder asBinder() {
-        return this;
-    }
-
-    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
-        protected IActivityManager create() {
-            IBinder b = ServiceManager.getService("activity");
-            if (false) {
-                Log.v("ActivityManager", "default service binder = " + b);
-            }
-            IActivityManager am = asInterface(b);
-            if (false) {
-                Log.v("ActivityManager", "default service = " + am);
-            }
-            return am;
-        }
-    };
-}
-
-class ActivityManagerProxy implements IActivityManager
-{
-    public ActivityManagerProxy(IBinder remote)
-    {
-        mRemote = remote;
-    }
-
-    public IBinder asBinder()
-    {
-        return mRemote;
-    }
-
-    public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
-            String resolvedType, IBinder resultTo, String resultWho, int requestCode,
-            int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
-        data.writeString(callingPackage);
-        intent.writeToParcel(data, 0);
-        data.writeString(resolvedType);
-        data.writeStrongBinder(resultTo);
-        data.writeString(resultWho);
-        data.writeInt(requestCode);
-        data.writeInt(startFlags);
-        if (profilerInfo != null) {
-            data.writeInt(1);
-            profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-        } else {
-            data.writeInt(0);
-        }
-        if (options != null) {
-            data.writeInt(1);
-            options.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int result = reply.readInt();
-        reply.recycle();
-        data.recycle();
-        return result;
-    }
-
-    public int startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent,
-            String resolvedType, IBinder resultTo, String resultWho, int requestCode,
-            int startFlags, ProfilerInfo profilerInfo, Bundle options,
-            int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
-        data.writeString(callingPackage);
-        intent.writeToParcel(data, 0);
-        data.writeString(resolvedType);
-        data.writeStrongBinder(resultTo);
-        data.writeString(resultWho);
-        data.writeInt(requestCode);
-        data.writeInt(startFlags);
-        if (profilerInfo != null) {
-            data.writeInt(1);
-            profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-        } else {
-            data.writeInt(0);
-        }
-        if (options != null) {
-            data.writeInt(1);
-            options.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        data.writeInt(userId);
-        mRemote.transact(START_ACTIVITY_AS_USER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int result = reply.readInt();
-        reply.recycle();
-        data.recycle();
-        return result;
-    }
-    public int startActivityAsCaller(IApplicationThread caller, String callingPackage,
-            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
-            int startFlags, ProfilerInfo profilerInfo, Bundle options, boolean ignoreTargetSecurity,
-            int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
-        data.writeString(callingPackage);
-        intent.writeToParcel(data, 0);
-        data.writeString(resolvedType);
-        data.writeStrongBinder(resultTo);
-        data.writeString(resultWho);
-        data.writeInt(requestCode);
-        data.writeInt(startFlags);
-        if (profilerInfo != null) {
-            data.writeInt(1);
-            profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-        } else {
-            data.writeInt(0);
-        }
-        if (options != null) {
-            data.writeInt(1);
-            options.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        data.writeInt(ignoreTargetSecurity ? 1 : 0);
-        data.writeInt(userId);
-        mRemote.transact(START_ACTIVITY_AS_CALLER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int result = reply.readInt();
-        reply.recycle();
-        data.recycle();
-        return result;
-    }
-    public WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
-            Intent intent, String resolvedType, IBinder resultTo, String resultWho,
-            int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle options,
-            int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
-        data.writeString(callingPackage);
-        intent.writeToParcel(data, 0);
-        data.writeString(resolvedType);
-        data.writeStrongBinder(resultTo);
-        data.writeString(resultWho);
-        data.writeInt(requestCode);
-        data.writeInt(startFlags);
-        if (profilerInfo != null) {
-            data.writeInt(1);
-            profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-        } else {
-            data.writeInt(0);
-        }
-        if (options != null) {
-            data.writeInt(1);
-            options.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        data.writeInt(userId);
-        mRemote.transact(START_ACTIVITY_AND_WAIT_TRANSACTION, data, reply, 0);
-        reply.readException();
-        WaitResult result = WaitResult.CREATOR.createFromParcel(reply);
-        reply.recycle();
-        data.recycle();
-        return result;
-    }
-    public int startActivityWithConfig(IApplicationThread caller, String callingPackage,
-            Intent intent, String resolvedType, IBinder resultTo, String resultWho,
-            int requestCode, int startFlags, Configuration config,
-            Bundle options, int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
-        data.writeString(callingPackage);
-        intent.writeToParcel(data, 0);
-        data.writeString(resolvedType);
-        data.writeStrongBinder(resultTo);
-        data.writeString(resultWho);
-        data.writeInt(requestCode);
-        data.writeInt(startFlags);
-        config.writeToParcel(data, 0);
-        if (options != null) {
-            data.writeInt(1);
-            options.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        data.writeInt(userId);
-        mRemote.transact(START_ACTIVITY_WITH_CONFIG_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int result = reply.readInt();
-        reply.recycle();
-        data.recycle();
-        return result;
-    }
-    public int startActivityIntentSender(IApplicationThread caller,
-            IntentSender intent, Intent fillInIntent, String resolvedType,
-            IBinder resultTo, String resultWho, int requestCode,
-            int flagsMask, int flagsValues, Bundle options) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
-        intent.writeToParcel(data, 0);
-        if (fillInIntent != null) {
-            data.writeInt(1);
-            fillInIntent.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        data.writeString(resolvedType);
-        data.writeStrongBinder(resultTo);
-        data.writeString(resultWho);
-        data.writeInt(requestCode);
-        data.writeInt(flagsMask);
-        data.writeInt(flagsValues);
-        if (options != null) {
-            data.writeInt(1);
-            options.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        mRemote.transact(START_ACTIVITY_INTENT_SENDER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int result = reply.readInt();
-        reply.recycle();
-        data.recycle();
-        return result;
-    }
-    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
-            Intent intent, String resolvedType, IVoiceInteractionSession session,
-            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
-            Bundle options, int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(callingPackage);
-        data.writeInt(callingPid);
-        data.writeInt(callingUid);
-        intent.writeToParcel(data, 0);
-        data.writeString(resolvedType);
-        data.writeStrongBinder(session.asBinder());
-        data.writeStrongBinder(interactor.asBinder());
-        data.writeInt(startFlags);
-        if (profilerInfo != null) {
-            data.writeInt(1);
-            profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-        } else {
-            data.writeInt(0);
-        }
-        if (options != null) {
-            data.writeInt(1);
-            options.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        data.writeInt(userId);
-        mRemote.transact(START_VOICE_ACTIVITY_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int result = reply.readInt();
-        reply.recycle();
-        data.recycle();
-        return result;
-    }
-
-    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(callingActivity);
-        data.writeBundle(options);
-        mRemote.transact(START_LOCAL_VOICE_INTERACTION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        reply.recycle();
-        data.recycle();
-    }
-
-    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(callingActivity);
-        mRemote.transact(STOP_LOCAL_VOICE_INTERACTION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        reply.recycle();
-        data.recycle();
-    }
-
-    public boolean supportsLocalVoiceInteraction() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(SUPPORTS_LOCAL_VOICE_INTERACTION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int result = reply.readInt();
-        reply.recycle();
-        data.recycle();
-        return result != 0;
-    }
-
-    public boolean startNextMatchingActivity(IBinder callingActivity,
-            Intent intent, Bundle options) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(callingActivity);
-        intent.writeToParcel(data, 0);
-        if (options != null) {
-            data.writeInt(1);
-            options.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        mRemote.transact(START_NEXT_MATCHING_ACTIVITY_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int result = reply.readInt();
-        reply.recycle();
-        data.recycle();
-        return result != 0;
-    }
-    public int startActivityFromRecents(int taskId, Bundle options)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(taskId);
-        if (options == null) {
-            data.writeInt(0);
-        } else {
-            data.writeInt(1);
-            options.writeToParcel(data, 0);
-        }
-        mRemote.transact(START_ACTIVITY_FROM_RECENTS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int result = reply.readInt();
-        reply.recycle();
-        data.recycle();
-        return result;
-    }
-    public boolean finishActivity(IBinder token, int resultCode, Intent resultData, int finishTask)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        data.writeInt(resultCode);
-        if (resultData != null) {
-            data.writeInt(1);
-            resultData.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        data.writeInt(finishTask);
-        mRemote.transact(FINISH_ACTIVITY_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public void finishSubActivity(IBinder token, String resultWho, int requestCode) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        data.writeString(resultWho);
-        data.writeInt(requestCode);
-        mRemote.transact(FINISH_SUB_ACTIVITY_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public boolean finishActivityAffinity(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(FINISH_ACTIVITY_AFFINITY_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public void finishVoiceTask(IVoiceInteractionSession session) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(session.asBinder());
-        mRemote.transact(FINISH_VOICE_TASK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public void requestActivityRelaunch(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(REQUEST_ACTIVITY_RELAUNCH, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public boolean releaseActivityInstance(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(RELEASE_ACTIVITY_INSTANCE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public void releaseSomeActivities(IApplicationThread app) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(app.asBinder());
-        mRemote.transact(RELEASE_SOME_ACTIVITIES_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public boolean willActivityBeVisible(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(WILL_ACTIVITY_BE_VISIBLE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public Intent registerReceiver(IApplicationThread caller, String packageName,
-            IIntentReceiver receiver,
-            IntentFilter filter, String perm, int userId) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
-        data.writeString(packageName);
-        data.writeStrongBinder(receiver != null ? receiver.asBinder() : null);
-        filter.writeToParcel(data, 0);
-        data.writeString(perm);
-        data.writeInt(userId);
-        mRemote.transact(REGISTER_RECEIVER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        Intent intent = null;
-        int haveIntent = reply.readInt();
-        if (haveIntent != 0) {
-            intent = Intent.CREATOR.createFromParcel(reply);
-        }
-        reply.recycle();
-        data.recycle();
-        return intent;
-    }
-    public void unregisterReceiver(IIntentReceiver receiver) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(receiver.asBinder());
-        mRemote.transact(UNREGISTER_RECEIVER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public int broadcastIntent(IApplicationThread caller,
-            Intent intent, String resolvedType, IIntentReceiver resultTo,
-            int resultCode, String resultData, Bundle map,
-            String[] requiredPermissions, int appOp, Bundle options, boolean serialized,
-            boolean sticky, int userId) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
-        intent.writeToParcel(data, 0);
-        data.writeString(resolvedType);
-        data.writeStrongBinder(resultTo != null ? resultTo.asBinder() : null);
-        data.writeInt(resultCode);
-        data.writeString(resultData);
-        data.writeBundle(map);
-        data.writeStringArray(requiredPermissions);
-        data.writeInt(appOp);
-        data.writeBundle(options);
-        data.writeInt(serialized ? 1 : 0);
-        data.writeInt(sticky ? 1 : 0);
-        data.writeInt(userId);
-        mRemote.transact(BROADCAST_INTENT_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        reply.recycle();
-        data.recycle();
-        return res;
-    }
-    public void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId)
-            throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
-        intent.writeToParcel(data, 0);
-        data.writeInt(userId);
-        mRemote.transact(UNBROADCAST_INTENT_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public void finishReceiver(IBinder who, int resultCode, String resultData, Bundle map,
-            boolean abortBroadcast, int flags) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(who);
-        data.writeInt(resultCode);
-        data.writeString(resultData);
-        data.writeBundle(map);
-        data.writeInt(abortBroadcast ? 1 : 0);
-        data.writeInt(flags);
-        mRemote.transact(FINISH_RECEIVER_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public void attachApplication(IApplicationThread app) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(app.asBinder());
-        mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public void activityIdle(IBinder token, Configuration config, boolean stopProfiling)
-            throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        if (config != null) {
-            data.writeInt(1);
-            config.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        data.writeInt(stopProfiling ? 1 : 0);
-        mRemote.transact(ACTIVITY_IDLE_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public void activityResumed(IBinder token) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(ACTIVITY_RESUMED_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public void activityPaused(IBinder token) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(ACTIVITY_PAUSED_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public void activityStopped(IBinder token, Bundle state,
-            PersistableBundle persistentState, CharSequence description) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        data.writeBundle(state);
-        data.writePersistableBundle(persistentState);
-        TextUtils.writeToParcel(description, data, 0);
-        mRemote.transact(ACTIVITY_STOPPED_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public void activitySlept(IBinder token) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(ACTIVITY_SLEPT_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public void activityDestroyed(IBinder token) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(ACTIVITY_DESTROYED_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public void activityRelaunched(IBinder token) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(ACTIVITY_RELAUNCHED_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public String getCallingPackage(IBinder token) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(GET_CALLING_PACKAGE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        String res = reply.readString();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public ComponentName getCallingActivity(IBinder token)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(GET_CALLING_ACTIVITY_TRANSACTION, data, reply, 0);
-        reply.readException();
-        ComponentName res = ComponentName.readFromParcel(reply);
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public List<IAppTask> getAppTasks(String callingPackage) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(callingPackage);
-        mRemote.transact(GET_APP_TASKS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        ArrayList<IAppTask> list = null;
-        int N = reply.readInt();
-        if (N >= 0) {
-            list = new ArrayList<>();
-            while (N > 0) {
-                IAppTask task = IAppTask.Stub.asInterface(reply.readStrongBinder());
-                list.add(task);
-                N--;
-            }
-        }
-        data.recycle();
-        reply.recycle();
-        return list;
-    }
-    public int addAppTask(IBinder activityToken, Intent intent,
-            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(activityToken);
-        intent.writeToParcel(data, 0);
-        description.writeToParcel(data, 0);
-        thumbnail.writeToParcel(data, 0);
-        mRemote.transact(ADD_APP_TASK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public Point getAppTaskThumbnailSize() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_APP_TASK_THUMBNAIL_SIZE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        Point size = Point.CREATOR.createFromParcel(reply);
-        data.recycle();
-        reply.recycle();
-        return size;
-    }
-    public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum, int flags)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(maxNum);
-        data.writeInt(flags);
-        mRemote.transact(GET_TASKS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        ArrayList<ActivityManager.RunningTaskInfo> list = null;
-        int N = reply.readInt();
-        if (N >= 0) {
-            list = new ArrayList<>();
-            while (N > 0) {
-                ActivityManager.RunningTaskInfo info =
-                        ActivityManager.RunningTaskInfo.CREATOR
-                                .createFromParcel(reply);
-                list.add(info);
-                N--;
-            }
-        }
-        data.recycle();
-        reply.recycle();
-        return list;
-    }
-    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
-            int flags, int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(maxNum);
-        data.writeInt(flags);
-        data.writeInt(userId);
-        mRemote.transact(GET_RECENT_TASKS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        final ParceledListSlice<ActivityManager.RecentTaskInfo> list = ParceledListSlice.CREATOR
-                .createFromParcel(reply);
-        data.recycle();
-        reply.recycle();
-        return list;
-    }
-    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(id);
-        mRemote.transact(GET_TASK_THUMBNAIL_TRANSACTION, data, reply, 0);
-        reply.readException();
-        ActivityManager.TaskThumbnail taskThumbnail = null;
-        if (reply.readInt() != 0) {
-            taskThumbnail = ActivityManager.TaskThumbnail.CREATOR.createFromParcel(reply);
-        }
-        data.recycle();
-        reply.recycle();
-        return taskThumbnail;
-    }
-    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, int flags)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(maxNum);
-        data.writeInt(flags);
-        mRemote.transact(GET_SERVICES_TRANSACTION, data, reply, 0);
-        reply.readException();
-        ArrayList<ActivityManager.RunningServiceInfo> list = null;
-        int N = reply.readInt();
-        if (N >= 0) {
-            list = new ArrayList<>();
-            while (N > 0) {
-                ActivityManager.RunningServiceInfo info =
-                        ActivityManager.RunningServiceInfo.CREATOR
-                        .createFromParcel(reply);
-                list.add(info);
-                N--;
-            }
-        }
-        data.recycle();
-        reply.recycle();
-        return list;
-    }
-    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState()
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_PROCESSES_IN_ERROR_STATE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        ArrayList<ActivityManager.ProcessErrorStateInfo> list
-            = reply.createTypedArrayList(ActivityManager.ProcessErrorStateInfo.CREATOR);
-        data.recycle();
-        reply.recycle();
-        return list;
-    }
-    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses()
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_RUNNING_APP_PROCESSES_TRANSACTION, data, reply, 0);
-        reply.readException();
-        ArrayList<ActivityManager.RunningAppProcessInfo> list
-        = reply.createTypedArrayList(ActivityManager.RunningAppProcessInfo.CREATOR);
-        data.recycle();
-        reply.recycle();
-        return list;
-    }
-    public List<ApplicationInfo> getRunningExternalApplications()
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_RUNNING_EXTERNAL_APPLICATIONS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        ArrayList<ApplicationInfo> list
-        = reply.createTypedArrayList(ApplicationInfo.CREATOR);
-        data.recycle();
-        reply.recycle();
-        return list;
-    }
-    public void moveStackToDisplay(int stackId, int displayId) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(stackId);
-        data.writeInt(displayId);
-        mRemote.transact(MOVE_STACK_TO_DISPLAY_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    @Override
-    public void moveTaskToFront(int task, int flags, Bundle options) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(task);
-        data.writeInt(flags);
-        if (options != null) {
-            data.writeInt(1);
-            options.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        mRemote.transact(MOVE_TASK_TO_FRONT_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        data.writeInt(nonRoot ? 1 : 0);
-        mRemote.transact(MOVE_ACTIVITY_TASK_TO_BACK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public void moveTaskBackwards(int task) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(task);
-        mRemote.transact(MOVE_TASK_BACKWARDS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    @Override
-    public void moveTaskToStack(int taskId, int stackId, boolean toTop) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(taskId);
-        data.writeInt(stackId);
-        data.writeInt(toTop ? 1 : 0);
-        mRemote.transact(MOVE_TASK_TO_STACK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    @Override
-    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
-            Rect initialBounds, boolean moveHomeStackFront) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(taskId);
-        data.writeInt(createMode);
-        data.writeInt(toTop ? 1 : 0);
-        data.writeInt(animate ? 1 : 0);
-        if (initialBounds != null) {
-            data.writeInt(1);
-            initialBounds.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        data.writeInt(moveHomeStackFront ? 1 : 0);
-        mRemote.transact(MOVE_TASK_TO_DOCKED_STACK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() > 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    @Override
-    public boolean moveTopActivityToPinnedStack(int stackId, Rect r)
-        throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(stackId);
-        r.writeToParcel(data, 0);
-        mRemote.transact(MOVE_TOP_ACTIVITY_TO_PINNED_STACK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        final boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    @Override
-    public void resizeStack(int stackId, Rect r, boolean allowResizeInDockedMode,
-            boolean preserveWindows, boolean animate, int animationDuration)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(stackId);
-        if (r != null) {
-            data.writeInt(1);
-            r.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        data.writeInt(allowResizeInDockedMode ? 1 : 0);
-        data.writeInt(preserveWindows ? 1 : 0);
-        data.writeInt(animate ? 1 : 0);
-        data.writeInt(animationDuration);
-        mRemote.transact(RESIZE_STACK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    @Override
-    public void swapDockedAndFullscreenStack() throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(SWAP_DOCKED_AND_FULLSCREEN_STACK, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    @Override
-    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
-            Rect tempDockedTaskInsetBounds,
-            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds)
-            throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        if (dockedBounds != null) {
-            data.writeInt(1);
-            dockedBounds.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        if (tempDockedTaskBounds != null) {
-            data.writeInt(1);
-            tempDockedTaskBounds.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        if (tempDockedTaskInsetBounds != null) {
-            data.writeInt(1);
-            tempDockedTaskInsetBounds.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        if (tempOtherTaskBounds != null) {
-            data.writeInt(1);
-            tempOtherTaskBounds.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        if (tempOtherTaskInsetBounds != null) {
-            data.writeInt(1);
-            tempOtherTaskInsetBounds.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        mRemote.transact(RESIZE_DOCKED_STACK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        if (pinnedBounds != null) {
-            data.writeInt(1);
-            pinnedBounds.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        if (tempPinnedTaskBounds != null) {
-            data.writeInt(1);
-            tempPinnedTaskBounds.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        mRemote.transact(RESIZE_PINNED_STACK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void positionTaskInStack(int taskId, int stackId, int position) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(taskId);
-        data.writeInt(stackId);
-        data.writeInt(position);
-        mRemote.transact(POSITION_TASK_IN_STACK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    @Override
-    public List<StackInfo> getAllStackInfos() throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_ALL_STACK_INFOS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        ArrayList<StackInfo> list = reply.createTypedArrayList(StackInfo.CREATOR);
-        data.recycle();
-        reply.recycle();
-        return list;
-    }
-    @Override
-    public StackInfo getStackInfo(int stackId) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(stackId);
-        mRemote.transact(GET_STACK_INFO_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        StackInfo info = null;
-        if (res != 0) {
-            info = StackInfo.CREATOR.createFromParcel(reply);
-        }
-        data.recycle();
-        reply.recycle();
-        return info;
-    }
-    @Override
-    public boolean isInHomeStack(int taskId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(taskId);
-        mRemote.transact(IS_IN_HOME_STACK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean isInHomeStack = reply.readInt() > 0;
-        data.recycle();
-        reply.recycle();
-        return isInHomeStack;
-    }
-    @Override
-    public void setFocusedStack(int stackId) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(stackId);
-        mRemote.transact(SET_FOCUSED_STACK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    @Override
-    public int getFocusedStackId() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_FOCUSED_STACK_ID_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int focusedStackId = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return focusedStackId;
-    }
-    @Override
-    public void setFocusedTask(int taskId) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(taskId);
-        mRemote.transact(SET_FOCUSED_TASK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    @Override
-    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(listener.asBinder());
-        mRemote.transact(REGISTER_TASK_STACK_LISTENER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    @Override
-    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(listener.asBinder());
-        mRemote.transact(UNREGISTER_TASK_STACK_LISTENER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public int getTaskForActivity(IBinder token, boolean onlyRoot) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        data.writeInt(onlyRoot ? 1 : 0);
-        mRemote.transact(GET_TASK_FOR_ACTIVITY_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public ContentProviderHolder getContentProvider(IApplicationThread caller,
-            String name, int userId, boolean stable) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
-        data.writeString(name);
-        data.writeInt(userId);
-        data.writeInt(stable ? 1 : 0);
-        mRemote.transact(GET_CONTENT_PROVIDER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        ContentProviderHolder cph = null;
-        if (res != 0) {
-            cph = ContentProviderHolder.CREATOR.createFromParcel(reply);
-        }
-        data.recycle();
-        reply.recycle();
-        return cph;
-    }
-    public ContentProviderHolder getContentProviderExternal(String name, int userId, IBinder token)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(name);
-        data.writeInt(userId);
-        data.writeStrongBinder(token);
-        mRemote.transact(GET_CONTENT_PROVIDER_EXTERNAL_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        ContentProviderHolder cph = null;
-        if (res != 0) {
-            cph = ContentProviderHolder.CREATOR.createFromParcel(reply);
-        }
-        data.recycle();
-        reply.recycle();
-        return cph;
-    }
-    public void publishContentProviders(IApplicationThread caller,
-            List<ContentProviderHolder> providers) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
-        data.writeTypedList(providers);
-        mRemote.transact(PUBLISH_CONTENT_PROVIDERS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public boolean refContentProvider(IBinder connection, int stable, int unstable)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(connection);
-        data.writeInt(stable);
-        data.writeInt(unstable);
-        mRemote.transact(REF_CONTENT_PROVIDER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public void unstableProviderDied(IBinder connection) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(connection);
-        mRemote.transact(UNSTABLE_PROVIDER_DIED_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void appNotRespondingViaProvider(IBinder connection) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(connection);
-        mRemote.transact(APP_NOT_RESPONDING_VIA_PROVIDER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void removeContentProvider(IBinder connection, boolean stable) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(connection);
-        data.writeInt(stable ? 1 : 0);
-        mRemote.transact(REMOVE_CONTENT_PROVIDER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void removeContentProviderExternal(String name, IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(name);
-        data.writeStrongBinder(token);
-        mRemote.transact(REMOVE_CONTENT_PROVIDER_EXTERNAL_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public PendingIntent getRunningServiceControlPanel(ComponentName service)
-            throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        service.writeToParcel(data, 0);
-        mRemote.transact(GET_RUNNING_SERVICE_CONTROL_PANEL_TRANSACTION, data, reply, 0);
-        reply.readException();
-        PendingIntent res = PendingIntent.readPendingIntentOrNullFromParcel(reply);
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public ComponentName startService(IApplicationThread caller, Intent service,
-            String resolvedType, String callingPackage, int userId) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
-        service.writeToParcel(data, 0);
-        data.writeString(resolvedType);
-        data.writeString(callingPackage);
-        data.writeInt(userId);
-        mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        ComponentName res = ComponentName.readFromParcel(reply);
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public int stopService(IApplicationThread caller, Intent service,
-            String resolvedType, int userId) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
-        service.writeToParcel(data, 0);
-        data.writeString(resolvedType);
-        data.writeInt(userId);
-        mRemote.transact(STOP_SERVICE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        reply.recycle();
-        data.recycle();
-        return res;
-    }
-    public boolean stopServiceToken(ComponentName className, IBinder token,
-            int startId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        ComponentName.writeToParcel(className, data);
-        data.writeStrongBinder(token);
-        data.writeInt(startId);
-        mRemote.transact(STOP_SERVICE_TOKEN_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public void setServiceForeground(ComponentName className, IBinder token,
-            int id, Notification notification, int flags) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        ComponentName.writeToParcel(className, data);
-        data.writeStrongBinder(token);
-        data.writeInt(id);
-        if (notification != null) {
-            data.writeInt(1);
-            notification.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        data.writeInt(flags);
-        mRemote.transact(SET_SERVICE_FOREGROUND_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public int bindService(IApplicationThread caller, IBinder token,
-            Intent service, String resolvedType, IServiceConnection connection,
-            int flags,  String callingPackage, int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
-        data.writeStrongBinder(token);
-        service.writeToParcel(data, 0);
-        data.writeString(resolvedType);
-        data.writeStrongBinder(connection.asBinder());
-        data.writeInt(flags);
-        data.writeString(callingPackage);
-        data.writeInt(userId);
-        mRemote.transact(BIND_SERVICE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public boolean unbindService(IServiceConnection connection) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(connection.asBinder());
-        mRemote.transact(UNBIND_SERVICE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public void publishService(IBinder token,
-            Intent intent, IBinder service) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        intent.writeToParcel(data, 0);
-        data.writeStrongBinder(service);
-        mRemote.transact(PUBLISH_SERVICE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void unbindFinished(IBinder token, Intent intent, boolean doRebind)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        intent.writeToParcel(data, 0);
-        data.writeInt(doRebind ? 1 : 0);
-        mRemote.transact(UNBIND_FINISHED_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void serviceDoneExecuting(IBinder token, int type, int startId,
-            int res) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        data.writeInt(type);
-        data.writeInt(startId);
-        data.writeInt(res);
-        mRemote.transact(SERVICE_DONE_EXECUTING_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public IBinder peekService(Intent service, String resolvedType, String callingPackage)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        service.writeToParcel(data, 0);
-        data.writeString(resolvedType);
-        data.writeString(callingPackage);
-        mRemote.transact(PEEK_SERVICE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        IBinder binder = reply.readStrongBinder();
-        reply.recycle();
-        data.recycle();
-        return binder;
-    }
-
-    public boolean bindBackupAgent(String packageName, int backupRestoreMode, int userId)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        data.writeInt(backupRestoreMode);
-        data.writeInt(userId);
-        mRemote.transact(START_BACKUP_AGENT_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean success = reply.readInt() != 0;
-        reply.recycle();
-        data.recycle();
-        return success;
-    }
-
-    public void clearPendingBackup() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(CLEAR_PENDING_BACKUP_TRANSACTION, data, reply, 0);
-        reply.recycle();
-        data.recycle();
-    }
-
-    public void backupAgentCreated(String packageName, IBinder agent) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        data.writeStrongBinder(agent);
-        mRemote.transact(BACKUP_AGENT_CREATED_TRANSACTION, data, reply, 0);
-        reply.recycle();
-        data.recycle();
-    }
-
-    public void unbindBackupAgent(ApplicationInfo app) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        app.writeToParcel(data, 0);
-        mRemote.transact(UNBIND_BACKUP_AGENT_TRANSACTION, data, reply, 0);
-        reply.readException();
-        reply.recycle();
-        data.recycle();
-    }
-
-    public boolean startInstrumentation(ComponentName className, String profileFile,
-            int flags, Bundle arguments, IInstrumentationWatcher watcher,
-            IUiAutomationConnection connection, int userId, String instructionSet)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        ComponentName.writeToParcel(className, data);
-        data.writeString(profileFile);
-        data.writeInt(flags);
-        data.writeBundle(arguments);
-        data.writeStrongBinder(watcher != null ? watcher.asBinder() : null);
-        data.writeStrongBinder(connection != null ? connection.asBinder() : null);
-        data.writeInt(userId);
-        data.writeString(instructionSet);
-        mRemote.transact(START_INSTRUMENTATION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        reply.recycle();
-        data.recycle();
-        return res;
-    }
-
-    public void finishInstrumentation(IApplicationThread target,
-            int resultCode, Bundle results) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(target != null ? target.asBinder() : null);
-        data.writeInt(resultCode);
-        data.writeBundle(results);
-        mRemote.transact(FINISH_INSTRUMENTATION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public Configuration getConfiguration() throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_CONFIGURATION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        Configuration res = Configuration.CREATOR.createFromParcel(reply);
-        reply.recycle();
-        data.recycle();
-        return res;
-    }
-    public boolean updateConfiguration(Configuration values) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        values.writeToParcel(data, 0);
-        mRemote.transact(UPDATE_CONFIGURATION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean updated = reply.readInt() == 1;
-        data.recycle();
-        reply.recycle();
-        return updated;
-    }
-    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        values.writeToParcel(data, 0);
-        data.writeInt(displayId);
-        mRemote.transact(UPDATE_DISPLAY_OVERRIDE_CONFIGURATION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean updated = reply.readInt() == 1;
-        data.recycle();
-        reply.recycle();
-        return updated;
-    }
-    public void setRequestedOrientation(IBinder token, int requestedOrientation)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        data.writeInt(requestedOrientation);
-        mRemote.transact(SET_REQUESTED_ORIENTATION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public int getRequestedOrientation(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(GET_REQUESTED_ORIENTATION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public ComponentName getActivityClassForToken(IBinder token)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(GET_ACTIVITY_CLASS_FOR_TOKEN_TRANSACTION, data, reply, 0);
-        reply.readException();
-        ComponentName res = ComponentName.readFromParcel(reply);
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public String getPackageForToken(IBinder token) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(GET_PACKAGE_FOR_TOKEN_TRANSACTION, data, reply, 0);
-        reply.readException();
-        String res = reply.readString();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public IIntentSender getIntentSender(int type,
-            String packageName, IBinder token, String resultWho,
-            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
-            Bundle options, int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(type);
-        data.writeString(packageName);
-        data.writeStrongBinder(token);
-        data.writeString(resultWho);
-        data.writeInt(requestCode);
-        if (intents != null) {
-            data.writeInt(1);
-            data.writeTypedArray(intents, 0);
-            data.writeStringArray(resolvedTypes);
-        } else {
-            data.writeInt(0);
-        }
-        data.writeInt(flags);
-        if (options != null) {
-            data.writeInt(1);
-            options.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        data.writeInt(userId);
-        mRemote.transact(GET_INTENT_SENDER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        IIntentSender res = IIntentSender.Stub.asInterface(
-                reply.readStrongBinder());
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public void cancelIntentSender(IIntentSender sender) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(sender.asBinder());
-        mRemote.transact(CANCEL_INTENT_SENDER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public String getPackageForIntentSender(IIntentSender sender) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(sender.asBinder());
-        mRemote.transact(GET_PACKAGE_FOR_INTENT_SENDER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        String res = reply.readString();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public int getUidForIntentSender(IIntentSender sender) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(sender.asBinder());
-        mRemote.transact(GET_UID_FOR_INTENT_SENDER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
-            boolean requireFull, String name, String callerPackage) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(callingPid);
-        data.writeInt(callingUid);
-        data.writeInt(userId);
-        data.writeInt(allowAll ? 1 : 0);
-        data.writeInt(requireFull ? 1 : 0);
-        data.writeString(name);
-        data.writeString(callerPackage);
-        mRemote.transact(HANDLE_INCOMING_USER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public void setProcessLimit(int max) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(max);
-        mRemote.transact(SET_PROCESS_LIMIT_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public int getProcessLimit() throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_PROCESS_LIMIT_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public void setProcessForeground(IBinder token, int pid,
-            boolean isForeground) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        data.writeInt(pid);
-        data.writeInt(isForeground ? 1 : 0);
-        mRemote.transact(SET_PROCESS_FOREGROUND_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public int checkPermission(String permission, int pid, int uid)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(permission);
-        data.writeInt(pid);
-        data.writeInt(uid);
-        mRemote.transact(CHECK_PERMISSION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(permission);
-        data.writeInt(pid);
-        data.writeInt(uid);
-        data.writeStrongBinder(callerToken);
-        mRemote.transact(CHECK_PERMISSION_WITH_TOKEN_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public boolean clearApplicationUserData(final String packageName,
-            final IPackageDataObserver observer, final int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        data.writeStrongBinder((observer != null) ? observer.asBinder() : null);
-        data.writeInt(userId);
-        mRemote.transact(CLEAR_APP_DATA_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public int checkUriPermission(Uri uri, int pid, int uid, int mode, int userId,
-            IBinder callerToken) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        uri.writeToParcel(data, 0);
-        data.writeInt(pid);
-        data.writeInt(uid);
-        data.writeInt(mode);
-        data.writeInt(userId);
-        data.writeStrongBinder(callerToken);
-        mRemote.transact(CHECK_URI_PERMISSION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public void grantUriPermission(IApplicationThread caller, String targetPkg,
-            Uri uri, int mode, int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller.asBinder());
-        data.writeString(targetPkg);
-        uri.writeToParcel(data, 0);
-        data.writeInt(mode);
-        data.writeInt(userId);
-        mRemote.transact(GRANT_URI_PERMISSION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public void revokeUriPermission(IApplicationThread caller, Uri uri,
-            int mode, int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller.asBinder());
-        uri.writeToParcel(data, 0);
-        data.writeInt(mode);
-        data.writeInt(userId);
-        mRemote.transact(REVOKE_URI_PERMISSION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void takePersistableUriPermission(Uri uri, int mode, int userId)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        uri.writeToParcel(data, 0);
-        data.writeInt(mode);
-        data.writeInt(userId);
-        mRemote.transact(TAKE_PERSISTABLE_URI_PERMISSION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void releasePersistableUriPermission(Uri uri, int mode, int userId)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        uri.writeToParcel(data, 0);
-        data.writeInt(mode);
-        data.writeInt(userId);
-        mRemote.transact(RELEASE_PERSISTABLE_URI_PERMISSION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public ParceledListSlice<UriPermission> getPersistedUriPermissions(
-            String packageName, boolean incoming) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        data.writeInt(incoming ? 1 : 0);
-        mRemote.transact(GET_PERSISTED_URI_PERMISSIONS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        @SuppressWarnings("unchecked")
-        final ParceledListSlice<UriPermission> perms = ParceledListSlice.CREATOR.createFromParcel(
-                reply);
-        data.recycle();
-        reply.recycle();
-        return perms;
-    }
-
-    @Override
-    public ParceledListSlice<UriPermission> getGrantedUriPermissions(String packageName, int userId)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        data.writeInt(userId);
-        mRemote.transact(GET_GRANTED_URI_PERMISSIONS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        @SuppressWarnings("unchecked")
-        final ParceledListSlice<UriPermission> perms = ParceledListSlice.CREATOR.createFromParcel(
-                reply);
-        data.recycle();
-        reply.recycle();
-        return perms;
-    }
-
-    @Override
-    public void clearGrantedUriPermissions(String packageName, int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        data.writeInt(userId);
-        mRemote.transact(CLEAR_GRANTED_URI_PERMISSIONS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void showWaitingForDebugger(IApplicationThread who, boolean waiting)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(who.asBinder());
-        data.writeInt(waiting ? 1 : 0);
-        mRemote.transact(SHOW_WAITING_FOR_DEBUGGER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_MEMORY_INFO_TRANSACTION, data, reply, 0);
-        reply.readException();
-        outInfo.readFromParcel(reply);
-        data.recycle();
-        reply.recycle();
-    }
-    public void unhandledBack() throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(UNHANDLED_BACK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(OPEN_CONTENT_URI_TRANSACTION, data, reply, 0);
-        reply.readException();
-        ParcelFileDescriptor pfd = null;
-        if (reply.readInt() != 0) {
-            pfd = ParcelFileDescriptor.CREATOR.createFromParcel(reply);
-        }
-        data.recycle();
-        reply.recycle();
-        return pfd;
-    }
-    public void setLockScreenShown(boolean showing) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(showing ? 1 : 0);
-        mRemote.transact(SET_LOCK_SCREEN_SHOWN_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public void setDebugApp(
-        String packageName, boolean waitForDebugger, boolean persistent)
-        throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        data.writeInt(waitForDebugger ? 1 : 0);
-        data.writeInt(persistent ? 1 : 0);
-        mRemote.transact(SET_DEBUG_APP_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public void setAlwaysFinish(boolean enabled) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(enabled ? 1 : 0);
-        mRemote.transact(SET_ALWAYS_FINISH_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public void setActivityController(IActivityController watcher, boolean imAMonkey)
-            throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(watcher != null ? watcher.asBinder() : null);
-        data.writeInt(imAMonkey ? 1 : 0);
-        mRemote.transact(SET_ACTIVITY_CONTROLLER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public void setLenientBackgroundCheck(boolean enabled) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(enabled ? 1 : 0);
-        mRemote.transact(SET_LENIENT_BACKGROUND_CHECK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public int getMemoryTrimLevel() throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_MEMORY_TRIM_LEVEL_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int level = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return level;
-    }
-    public void enterSafeMode() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(ENTER_SAFE_MODE_TRANSACTION, data, null, 0);
-        data.recycle();
-    }
-    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(sender.asBinder());
-        data.writeInt(sourceUid);
-        data.writeString(sourcePkg);
-        data.writeString(tag);
-        mRemote.transact(NOTE_WAKEUP_ALARM_TRANSACTION, data, null, 0);
-        data.recycle();
-    }
-    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(sender.asBinder());
-        data.writeInt(sourceUid);
-        data.writeString(tag);
-        mRemote.transact(NOTE_ALARM_START_TRANSACTION, data, null, 0);
-        data.recycle();
-    }
-    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(sender.asBinder());
-        data.writeInt(sourceUid);
-        data.writeString(tag);
-        mRemote.transact(NOTE_ALARM_FINISH_TRANSACTION, data, null, 0);
-        data.recycle();
-    }
-    public boolean killPids(int[] pids, String reason, boolean secure) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeIntArray(pids);
-        data.writeString(reason);
-        data.writeInt(secure ? 1 : 0);
-        mRemote.transact(KILL_PIDS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    @Override
-    public boolean killProcessesBelowForeground(String reason) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(reason);
-        mRemote.transact(KILL_PROCESSES_BELOW_FOREGROUND_TRANSACTION, data, reply, 0);
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public boolean testIsSystemReady()
-    {
-        /* this base class version is never called */
-        return true;
-    }
-    public void handleApplicationCrash(IBinder app,
-            ApplicationErrorReport.CrashInfo crashInfo) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(app);
-        crashInfo.writeToParcel(data, 0);
-        mRemote.transact(HANDLE_APPLICATION_CRASH_TRANSACTION, data, reply, 0);
-        reply.readException();
-        reply.recycle();
-        data.recycle();
-    }
-
-    public boolean handleApplicationWtf(IBinder app, String tag, boolean system,
-            ApplicationErrorReport.CrashInfo crashInfo) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(app);
-        data.writeString(tag);
-        data.writeInt(system ? 1 : 0);
-        crashInfo.writeToParcel(data, 0);
-        mRemote.transact(HANDLE_APPLICATION_WTF_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        reply.recycle();
-        data.recycle();
-        return res;
-    }
-
-    public void handleApplicationStrictModeViolation(IBinder app,
-            int violationMask,
-            StrictMode.ViolationInfo info) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(app);
-        data.writeInt(violationMask);
-        info.writeToParcel(data, 0);
-        mRemote.transact(HANDLE_APPLICATION_STRICT_MODE_VIOLATION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        reply.recycle();
-        data.recycle();
-    }
-
-    public void signalPersistentProcesses(int sig) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(sig);
-        mRemote.transact(SIGNAL_PERSISTENT_PROCESSES_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void killBackgroundProcesses(String packageName, int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        data.writeInt(userId);
-        mRemote.transact(KILL_BACKGROUND_PROCESSES_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void killAllBackgroundProcesses() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(KILL_ALL_BACKGROUND_PROCESSES_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void killPackageDependents(String packageName, int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        data.writeInt(userId);
-        mRemote.transact(KILL_PACKAGE_DEPENDENTS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void forceStopPackage(String packageName, int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        data.writeInt(userId);
-        mRemote.transact(FORCE_STOP_PACKAGE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo)
-            throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_MY_MEMORY_STATE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        outInfo.readFromParcel(reply);
-        reply.recycle();
-        data.recycle();
-    }
-
-    public ConfigurationInfo getDeviceConfigurationInfo() throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_DEVICE_CONFIGURATION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        ConfigurationInfo res = ConfigurationInfo.CREATOR.createFromParcel(reply);
-        reply.recycle();
-        data.recycle();
-        return res;
-    }
-
-    public boolean profileControl(String process, int userId, boolean start,
-            ProfilerInfo profilerInfo, int profileType) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(process);
-        data.writeInt(userId);
-        data.writeInt(start ? 1 : 0);
-        data.writeInt(profileType);
-        if (profilerInfo != null) {
-            data.writeInt(1);
-            profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-        } else {
-            data.writeInt(0);
-        }
-        mRemote.transact(PROFILE_CONTROL_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        reply.recycle();
-        data.recycle();
-        return res;
-    }
-
-    public boolean shutdown(int timeout) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(timeout);
-        mRemote.transact(SHUTDOWN_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        reply.recycle();
-        data.recycle();
-        return res;
-    }
-
-    public void stopAppSwitches() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(STOP_APP_SWITCHES_TRANSACTION, data, reply, 0);
-        reply.readException();
-        reply.recycle();
-        data.recycle();
-    }
-
-    public void resumeAppSwitches() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(RESUME_APP_SWITCHES_TRANSACTION, data, reply, 0);
-        reply.readException();
-        reply.recycle();
-        data.recycle();
-    }
-
-    public void addPackageDependency(String packageName) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        mRemote.transact(ADD_PACKAGE_DEPENDENCY_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void killApplication(String pkg, int appId, int userId, String reason)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(pkg);
-        data.writeInt(appId);
-        data.writeInt(userId);
-        data.writeString(reason);
-        mRemote.transact(KILL_APPLICATION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void closeSystemDialogs(String reason) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(reason);
-        mRemote.transact(CLOSE_SYSTEM_DIALOGS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeIntArray(pids);
-        mRemote.transact(GET_PROCESS_MEMORY_INFO_TRANSACTION, data, reply, 0);
-        reply.readException();
-        Debug.MemoryInfo[] res = reply.createTypedArray(Debug.MemoryInfo.CREATOR);
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public void killApplicationProcess(String processName, int uid) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(processName);
-        data.writeInt(uid);
-        mRemote.transact(KILL_APPLICATION_PROCESS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void overridePendingTransition(IBinder token, String packageName,
-            int enterAnim, int exitAnim) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        data.writeString(packageName);
-        data.writeInt(enterAnim);
-        data.writeInt(exitAnim);
-        mRemote.transact(OVERRIDE_PENDING_TRANSITION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public boolean isUserAMonkey() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(IS_USER_A_MONKEY_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public void setUserIsMonkey(boolean monkey) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(monkey ? 1 : 0);
-        mRemote.transact(SET_USER_IS_MONKEY_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void finishHeavyWeightApp() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(FINISH_HEAVY_WEIGHT_APP_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public boolean convertFromTranslucent(IBinder token)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(CONVERT_FROM_TRANSLUCENT_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public boolean convertToTranslucent(IBinder token, ActivityOptions options)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        if (options == null) {
-            data.writeInt(0);
-        } else {
-            data.writeInt(1);
-            data.writeBundle(options.toBundle());
-        }
-        mRemote.transact(CONVERT_TO_TRANSLUCENT_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public ActivityOptions getActivityOptions(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(GET_ACTIVITY_OPTIONS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        ActivityOptions options = ActivityOptions.fromBundle(reply.readBundle());
-        data.recycle();
-        reply.recycle();
-        return options;
-    }
-
-    public void setImmersive(IBinder token, boolean immersive)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        data.writeInt(immersive ? 1 : 0);
-        mRemote.transact(SET_IMMERSIVE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public boolean isImmersive(IBinder token)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(IS_IMMERSIVE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() == 1;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public boolean isTopOfTask(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(IS_TOP_OF_TASK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() == 1;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public boolean isTopActivityImmersive()
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(IS_TOP_ACTIVITY_IMMERSIVE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() == 1;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public void crashApplication(int uid, int initialPid, String packageName,
-            String message) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(uid);
-        data.writeInt(initialPid);
-        data.writeString(packageName);
-        data.writeString(message);
-        mRemote.transact(CRASH_APPLICATION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public String getProviderMimeType(Uri uri, int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        uri.writeToParcel(data, 0);
-        data.writeInt(userId);
-        mRemote.transact(GET_PROVIDER_MIME_TYPE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        String res = reply.readString();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public IBinder newUriPermissionOwner(String name)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(name);
-        mRemote.transact(NEW_URI_PERMISSION_OWNER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        IBinder res = reply.readStrongBinder();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(activityToken);
-        mRemote.transact(GET_URI_PERMISSION_OWNER_FOR_ACTIVITY_TRANSACTION, data, reply, 0);
-        reply.readException();
-        IBinder res = reply.readStrongBinder();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public void grantUriPermissionFromOwner(IBinder owner, int fromUid, String targetPkg,
-            Uri uri, int mode, int sourceUserId, int targetUserId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(owner);
-        data.writeInt(fromUid);
-        data.writeString(targetPkg);
-        uri.writeToParcel(data, 0);
-        data.writeInt(mode);
-        data.writeInt(sourceUserId);
-        data.writeInt(targetUserId);
-        mRemote.transact(GRANT_URI_PERMISSION_FROM_OWNER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void revokeUriPermissionFromOwner(IBinder owner, Uri uri,
-            int mode, int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(owner);
-        if (uri != null) {
-            data.writeInt(1);
-            uri.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        data.writeInt(mode);
-        data.writeInt(userId);
-        mRemote.transact(REVOKE_URI_PERMISSION_FROM_OWNER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public int checkGrantUriPermission(int callingUid, String targetPkg,
-            Uri uri, int modeFlags, int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(callingUid);
-        data.writeString(targetPkg);
-        uri.writeToParcel(data, 0);
-        data.writeInt(modeFlags);
-        data.writeInt(userId);
-        mRemote.transact(CHECK_GRANT_URI_PERMISSION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public boolean dumpHeap(String process, int userId, boolean managed,
-            String path, ParcelFileDescriptor fd) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(process);
-        data.writeInt(userId);
-        data.writeInt(managed ? 1 : 0);
-        data.writeString(path);
-        if (fd != null) {
-            data.writeInt(1);
-            fd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-        } else {
-            data.writeInt(0);
-        }
-        mRemote.transact(DUMP_HEAP_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        reply.recycle();
-        data.recycle();
-        return res;
-    }
-
-    public int startActivities(IApplicationThread caller, String callingPackage,
-            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
-            Bundle options, int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
-        data.writeString(callingPackage);
-        data.writeTypedArray(intents, 0);
-        data.writeStringArray(resolvedTypes);
-        data.writeStrongBinder(resultTo);
-        if (options != null) {
-            data.writeInt(1);
-            options.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        data.writeInt(userId);
-        mRemote.transact(START_ACTIVITIES_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int result = reply.readInt();
-        reply.recycle();
-        data.recycle();
-        return result;
-    }
-
-    public int getFrontActivityScreenCompatMode() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_FRONT_ACTIVITY_SCREEN_COMPAT_MODE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int mode = reply.readInt();
-        reply.recycle();
-        data.recycle();
-        return mode;
-    }
-
-    public void setFrontActivityScreenCompatMode(int mode) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(mode);
-        mRemote.transact(SET_FRONT_ACTIVITY_SCREEN_COMPAT_MODE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        reply.recycle();
-        data.recycle();
-    }
-
-    public int getPackageScreenCompatMode(String packageName) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        mRemote.transact(GET_PACKAGE_SCREEN_COMPAT_MODE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int mode = reply.readInt();
-        reply.recycle();
-        data.recycle();
-        return mode;
-    }
-
-    public void setPackageScreenCompatMode(String packageName, int mode)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        data.writeInt(mode);
-        mRemote.transact(SET_PACKAGE_SCREEN_COMPAT_MODE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        reply.recycle();
-        data.recycle();
-    }
-
-    public boolean getPackageAskScreenCompat(String packageName) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        mRemote.transact(GET_PACKAGE_ASK_SCREEN_COMPAT_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean ask = reply.readInt() != 0;
-        reply.recycle();
-        data.recycle();
-        return ask;
-    }
-
-    public void setPackageAskScreenCompat(String packageName, boolean ask)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        data.writeInt(ask ? 1 : 0);
-        mRemote.transact(SET_PACKAGE_ASK_SCREEN_COMPAT_TRANSACTION, data, reply, 0);
-        reply.readException();
-        reply.recycle();
-        data.recycle();
-    }
-
-    public boolean switchUser(int userid) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(userid);
-        mRemote.transact(SWITCH_USER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean result = reply.readInt() != 0;
-        reply.recycle();
-        data.recycle();
-        return result;
-    }
-
-    public boolean startUserInBackground(int userid) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(userid);
-        mRemote.transact(START_USER_IN_BACKGROUND_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean result = reply.readInt() != 0;
-        reply.recycle();
-        data.recycle();
-        return result;
-    }
-
-    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(userId);
-        data.writeByteArray(token);
-        data.writeByteArray(secret);
-        data.writeStrongInterface(listener);
-        mRemote.transact(IActivityManager.UNLOCK_USER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean result = reply.readInt() != 0;
-        reply.recycle();
-        data.recycle();
-        return result;
-    }
-
-    public int stopUser(int userid, boolean force, IStopUserCallback callback)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(userid);
-        data.writeInt(force ? 1 : 0);
-        data.writeStrongInterface(callback);
-        mRemote.transact(STOP_USER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int result = reply.readInt();
-        reply.recycle();
-        data.recycle();
-        return result;
-    }
-
-    public UserInfo getCurrentUser() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_CURRENT_USER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        UserInfo userInfo = UserInfo.CREATOR.createFromParcel(reply);
-        reply.recycle();
-        data.recycle();
-        return userInfo;
-    }
-
-    public boolean isUserRunning(int userid, int flags) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(userid);
-        data.writeInt(flags);
-        mRemote.transact(IS_USER_RUNNING_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean result = reply.readInt() != 0;
-        reply.recycle();
-        data.recycle();
-        return result;
-    }
-
-    public int[] getRunningUserIds() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_RUNNING_USER_IDS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int[] result = reply.createIntArray();
-        reply.recycle();
-        data.recycle();
-        return result;
-    }
-
-    public boolean removeTask(int taskId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(taskId);
-        mRemote.transact(REMOVE_TASK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean result = reply.readInt() != 0;
-        reply.recycle();
-        data.recycle();
-        return result;
-    }
-
-    public void registerProcessObserver(IProcessObserver observer) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(observer != null ? observer.asBinder() : null);
-        mRemote.transact(REGISTER_PROCESS_OBSERVER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void unregisterProcessObserver(IProcessObserver observer) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(observer != null ? observer.asBinder() : null);
-        mRemote.transact(UNREGISTER_PROCESS_OBSERVER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void registerUidObserver(IUidObserver observer, int which) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(observer != null ? observer.asBinder() : null);
-        data.writeInt(which);
-        mRemote.transact(REGISTER_UID_OBSERVER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void unregisterUidObserver(IUidObserver observer) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(observer != null ? observer.asBinder() : null);
-        mRemote.transact(UNREGISTER_UID_OBSERVER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public boolean isIntentSenderTargetedToPackage(IIntentSender sender) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(sender.asBinder());
-        mRemote.transact(IS_INTENT_SENDER_TARGETED_TO_PACKAGE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public boolean isIntentSenderAnActivity(IIntentSender sender) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(sender.asBinder());
-        mRemote.transact(IS_INTENT_SENDER_AN_ACTIVITY_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public Intent getIntentForIntentSender(IIntentSender sender) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(sender.asBinder());
-        mRemote.transact(GET_INTENT_FOR_INTENT_SENDER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        Intent res = reply.readInt() != 0
-                ? Intent.CREATOR.createFromParcel(reply) : null;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public String getTagForIntentSender(IIntentSender sender, String prefix)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(sender.asBinder());
-        data.writeString(prefix);
-        mRemote.transact(GET_TAG_FOR_INTENT_SENDER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        String res = reply.readString();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public void updatePersistentConfiguration(Configuration values) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        values.writeToParcel(data, 0);
-        mRemote.transact(UPDATE_PERSISTENT_CONFIGURATION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public long[] getProcessPss(int[] pids) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeIntArray(pids);
-        mRemote.transact(GET_PROCESS_PSS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        long[] res = reply.createLongArray();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public void showBootMessage(CharSequence msg, boolean always) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        TextUtils.writeToParcel(msg, data, 0);
-        data.writeInt(always ? 1 : 0);
-        mRemote.transact(SHOW_BOOT_MESSAGE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void keyguardGoingAway(int flags)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(flags);
-        mRemote.transact(KEYGUARD_GOING_AWAY_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public boolean shouldUpRecreateTask(IBinder token, String destAffinity)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        data.writeString(destAffinity);
-        mRemote.transact(SHOULD_UP_RECREATE_TASK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean result = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return result;
-    }
-
-    public boolean navigateUpTo(IBinder token, Intent target, int resultCode, Intent resultData)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        target.writeToParcel(data, 0);
-        data.writeInt(resultCode);
-        if (resultData != null) {
-            data.writeInt(1);
-            resultData.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        mRemote.transact(NAVIGATE_UP_TO_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean result = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return result;
-    }
-
-    public int getLaunchedFromUid(IBinder activityToken) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(activityToken);
-        mRemote.transact(GET_LAUNCHED_FROM_UID_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int result = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return result;
-    }
-
-    public String getLaunchedFromPackage(IBinder activityToken) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(activityToken);
-        mRemote.transact(GET_LAUNCHED_FROM_PACKAGE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        String result = reply.readString();
-        data.recycle();
-        reply.recycle();
-        return result;
-    }
-
-    public void registerUserSwitchObserver(IUserSwitchObserver observer,
-            String name) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(observer != null ? observer.asBinder() : null);
-        data.writeString(name);
-        mRemote.transact(REGISTER_USER_SWITCH_OBSERVER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(observer != null ? observer.asBinder() : null);
-        mRemote.transact(UNREGISTER_USER_SWITCH_OBSERVER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void requestBugReport(@ActivityManager.BugreportMode int bugreportType)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(bugreportType);
-        mRemote.transact(REQUEST_BUG_REPORT_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(pid);
-        data.writeInt(aboveSystem ? 1 : 0);
-        data.writeString(reason);
-        mRemote.transact(INPUT_DISPATCHING_TIMED_OUT_TRANSACTION, data, reply, 0);
-        reply.readException();
-        long res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public Bundle getAssistContextExtras(int requestType) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(requestType);
-        mRemote.transact(GET_ASSIST_CONTEXT_EXTRAS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        Bundle res = reply.readBundle();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
-            Bundle receiverExtras,
-            IBinder activityToken, boolean focused, boolean newSessionId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(requestType);
-        data.writeStrongBinder(receiver.asBinder());
-        data.writeBundle(receiverExtras);
-        data.writeStrongBinder(activityToken);
-        data.writeInt(focused ? 1 : 0);
-        data.writeInt(newSessionId ? 1 : 0);
-        mRemote.transact(REQUEST_ASSIST_CONTEXT_EXTRAS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
-            AssistContent content, Uri referrer) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        data.writeBundle(extras);
-        structure.writeToParcel(data, 0);
-        content.writeToParcel(data, 0);
-        if (referrer != null) {
-            data.writeInt(1);
-            referrer.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        mRemote.transact(REPORT_ASSIST_CONTEXT_EXTRAS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
-            Bundle args) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        intent.writeToParcel(data, 0);
-        data.writeInt(requestType);
-        data.writeString(hint);
-        data.writeInt(userHandle);
-        data.writeBundle(args);
-        mRemote.transact(LAUNCH_ASSIST_INTENT_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public boolean isAssistDataAllowedOnCurrentActivity() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(IS_SCREEN_CAPTURE_ALLOWED_ON_CURRENT_ACTIVITY_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public boolean showAssistFromActivity(IBinder token, Bundle args) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        data.writeBundle(args);
-        mRemote.transact(SHOW_ASSIST_FROM_ACTIVITY_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public void killUid(int appId, int userId, String reason) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(appId);
-        data.writeInt(userId);
-        data.writeString(reason);
-        mRemote.transact(KILL_UID_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void hang(IBinder who, boolean allowRestart) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(who);
-        data.writeInt(allowRestart ? 1 : 0);
-        mRemote.transact(HANG_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void reportActivityFullyDrawn(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(REPORT_ACTIVITY_FULLY_DRAWN_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void notifyActivityDrawn(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(NOTIFY_ACTIVITY_DRAWN_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void restart() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(RESTART_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void performIdleMaintenance() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(PERFORM_IDLE_MAINTENANCE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void sendIdleJobTrigger() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(SEND_IDLE_JOB_TRIGGER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
-            IActivityContainerCallback callback) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(parentActivityToken);
-        data.writeStrongBinder(callback == null ? null : callback.asBinder());
-        mRemote.transact(CREATE_VIRTUAL_ACTIVITY_CONTAINER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        final int result = reply.readInt();
-        final IActivityContainer res;
-        if (result == 1) {
-            res = IActivityContainer.Stub.asInterface(reply.readStrongBinder());
-        } else {
-            res = null;
-        }
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public boolean startBinderTracking() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(START_BINDER_TRACKING_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        reply.recycle();
-        data.recycle();
-        return res;
-    }
-
-    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        if (fd != null) {
-            data.writeInt(1);
-            fd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-        } else {
-            data.writeInt(0);
-        }
-        mRemote.transact(STOP_BINDER_TRACKING_AND_DUMP_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        reply.recycle();
-        data.recycle();
-        return res;
-    }
-
-    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        data.writeInt(enabled ? 1 : 0);
-        packageName.writeToParcel(data, 0);
-        mRemote.transact(SET_VR_MODE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public boolean isVrModePackageEnabled(ComponentName packageName)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        packageName.writeToParcel(data, 0);
-        mRemote.transact(IS_VR_PACKAGE_ENABLED_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res == 1;
-    }
-
-    @Override
-    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(displayId);
-        mRemote.transact(CREATE_STACK_ON_DISPLAY, data, reply, 0);
-        reply.readException();
-        final int result = reply.readInt();
-        final IActivityContainer res;
-        if (result == 1) {
-            res = IActivityContainer.Stub.asInterface(reply.readStrongBinder());
-        } else {
-            res = null;
-        }
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    @Override
-    public int getActivityDisplayId(IBinder activityToken)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(activityToken);
-        mRemote.transact(GET_ACTIVITY_DISPLAY_ID_TRANSACTION, data, reply, 0);
-        reply.readException();
-        final int displayId = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return displayId;
-    }
-
-    @Override
-    public void startLockTaskMode(int taskId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(taskId);
-        mRemote.transact(START_LOCK_TASK_BY_TASK_ID_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void startLockTaskMode(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(START_LOCK_TASK_BY_TOKEN_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void startSystemLockTaskMode(int taskId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(taskId);
-        mRemote.transact(START_SYSTEM_LOCK_TASK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void stopLockTaskMode() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(STOP_LOCK_TASK_MODE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void stopSystemLockTaskMode() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(STOP_SYSTEM_LOCK_TASK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public boolean isInLockTaskMode() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(IS_IN_LOCK_TASK_MODE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean isInLockTaskMode = reply.readInt() == 1;
-        data.recycle();
-        reply.recycle();
-        return isInLockTaskMode;
-    }
-
-    @Override
-    public int getLockTaskModeState() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_LOCK_TASK_MODE_STATE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int lockTaskModeState = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return lockTaskModeState;
-    }
-
-    @Override
-    public void showLockTaskEscapeMessage(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(SHOW_LOCK_TASK_ESCAPE_MESSAGE_TRANSACTION, data, reply,
-                IBinder.FLAG_ONEWAY);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription values)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        values.writeToParcel(data, 0);
-        mRemote.transact(SET_TASK_DESCRIPTION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void setTaskResizeable(int taskId, int resizeableMode) throws  RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(taskId);
-        data.writeInt(resizeableMode);
-        mRemote.transact(SET_TASK_RESIZEABLE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void resizeTask(int taskId, Rect r, int resizeMode) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(taskId);
-        data.writeInt(resizeMode);
-        r.writeToParcel(data, 0);
-        mRemote.transact(RESIZE_TASK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public Rect getTaskBounds(int taskId) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(taskId);
-        mRemote.transact(GET_TASK_BOUNDS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        Rect rect = Rect.CREATOR.createFromParcel(reply);
-        data.recycle();
-        reply.recycle();
-        return rect;
-    }
-
-    @Override
-    public Bitmap getTaskDescriptionIcon(String filename, int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(filename);
-        data.writeInt(userId);
-        mRemote.transact(GET_TASK_DESCRIPTION_ICON_TRANSACTION, data, reply, 0);
-        reply.readException();
-        final Bitmap icon = reply.readInt() == 0 ? null : Bitmap.CREATOR.createFromParcel(reply);
-        data.recycle();
-        reply.recycle();
-        return icon;
-    }
-
-    @Override
-    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions options)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        if (options == null) {
-            data.writeInt(0);
-        } else {
-            data.writeInt(1);
-            data.writeBundle(options.toBundle());
-        }
-        mRemote.transact(START_IN_PLACE_ANIMATION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public boolean requestVisibleBehind(IBinder token, boolean visible) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        data.writeInt(visible ? 1 : 0);
-        mRemote.transact(REQUEST_VISIBLE_BEHIND_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean success = reply.readInt() > 0;
-        data.recycle();
-        reply.recycle();
-        return success;
-    }
-
-    @Override
-    public boolean isBackgroundVisibleBehind(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(IS_BACKGROUND_VISIBLE_BEHIND_TRANSACTION, data, reply, 0);
-        reply.readException();
-        final boolean visible = reply.readInt() > 0;
-        data.recycle();
-        reply.recycle();
-        return visible;
-    }
-
-    @Override
-    public void backgroundResourcesReleased(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(BACKGROUND_RESOURCES_RELEASED_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void notifyLaunchTaskBehindComplete(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(NOTIFY_LAUNCH_TASK_BEHIND_COMPLETE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void notifyEnterAnimationComplete(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(NOTIFY_ENTER_ANIMATION_COMPLETE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void bootAnimationComplete() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(BOOT_ANIMATION_COMPLETE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void notifyCleartextNetwork(int uid, byte[] firstPacket) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(uid);
-        data.writeByteArray(firstPacket);
-        mRemote.transact(NOTIFY_CLEARTEXT_NETWORK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
-            String reportPackage) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(processName);
-        data.writeInt(uid);
-        data.writeLong(maxMemSize);
-        data.writeString(reportPackage);
-        mRemote.transact(SET_DUMP_HEAP_DEBUG_LIMIT_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void dumpHeapFinished(String path) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(path);
-        mRemote.transact(DUMP_HEAP_FINISHED_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(session.asBinder());
-        data.writeInt(keepAwake ? 1 : 0);
-        mRemote.transact(SET_VOICE_KEEP_AWAKE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void updateLockTaskPackages(int userId, String[] packages) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(userId);
-        data.writeStringArray(packages);
-        mRemote.transact(UPDATE_LOCK_TASK_PACKAGES_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void updateDeviceOwner(String packageName) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        mRemote.transact(UPDATE_DEVICE_OWNER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public int getPackageProcessState(String packageName, String callingPackage)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        data.writeString(callingPackage);
-        mRemote.transact(GET_PACKAGE_PROCESS_STATE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    @Override
-    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(process);
-        data.writeInt(userId);
-        data.writeInt(level);
-        mRemote.transact(SET_PROCESS_MEMORY_TRIM_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res != 0;
-    }
-
-    @Override
-    public boolean isRootVoiceInteraction(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(IS_ROOT_VOICE_INTERACTION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res != 0;
-    }
-
-    @Override
-    public void exitFreeformMode(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(EXIT_FREEFORM_MODE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public int getActivityStackId(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(GET_ACTIVITY_STACK_ID_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int stackId = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return stackId;
-    }
-
-    @Override
-    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
-            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        writeIntArray(horizontalSizeConfiguration, data);
-        writeIntArray(verticalSizeConfigurations, data);
-        writeIntArray(smallestSizeConfigurations, data);
-        mRemote.transact(REPORT_SIZE_CONFIGURATIONS, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    private static void writeIntArray(int[] array, Parcel data) {
-        if (array == null) {
-            data.writeInt(0);
-        } else {
-            data.writeInt(array.length);
-            data.writeIntArray(array);
-        }
-    }
-
-    @Override
-    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(suppress ? 1 : 0);
-        mRemote.transact(SUPPRESS_RESIZE_CONFIG_CHANGES_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(fromStackId);
-        data.writeInt(onTop ? 1 : 0);
-        mRemote.transact(MOVE_TASKS_TO_FULLSCREEN_STACK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public int getAppStartMode(int uid, String packageName) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(uid);
-        data.writeString(packageName);
-        mRemote.transact(GET_APP_START_MODE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    @Override
-    public boolean isInMultiWindowMode(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(IN_MULTI_WINDOW_TRANSACTION, data, reply, 0);
-        reply.readException();
-        final boolean multiWindowMode = reply.readInt() == 1 ? true : false;
-        data.recycle();
-        reply.recycle();
-        return multiWindowMode;
-    }
-
-    @Override
-    public boolean isInPictureInPictureMode(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(IN_PICTURE_IN_PICTURE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        final boolean pipMode = reply.readInt() == 1 ? true : false;
-        data.recycle();
-        reply.recycle();
-        return pipMode;
-    }
-
-    @Override
-    public void enterPictureInPictureMode(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(ENTER_PICTURE_IN_PICTURE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public boolean isAppForeground(int uid) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(uid);
-        mRemote.transact(IS_APP_FOREGROUND_TRANSACTION, data, reply, 0);
-        final boolean isForeground = reply.readInt() == 1 ? true : false;
-        data.recycle();
-        reply.recycle();
-        return isForeground;
-    };
-
-    @Override
-    public void notifyPinnedStackAnimationEnded() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(NOTIFY_PINNED_STACK_ANIMATION_ENDED_TRANSACTION, data, reply, 0);
-        data.recycle();
-        reply.recycle();
-    };
-
-    @Override
-    public void removeStack(int stackId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(stackId);
-        mRemote.transact(REMOVE_STACK, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void notifyLockedProfile(@UserIdInt int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(userId);
-        mRemote.transact(NOTIFY_LOCKED_PROFILE, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void startConfirmDeviceCredentialIntent(Intent intent) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        intent.writeToParcel(data, 0);
-        mRemote.transact(START_CONFIRM_DEVICE_CREDENTIAL_INTENT, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
-            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(target.asBinder());
-        data.writeInt(code);
-        if ((intent!=null)) {
-            data.writeInt(1);
-            intent.writeToParcel(data, 0);
-        }
-        else {
-            data.writeInt(0);
-        }
-        data.writeString(resolvedType);
-        data.writeStrongBinder((((finishedReceiver!=null))?(finishedReceiver.asBinder()):(null)));
-        data.writeString(requiredPermission);
-        if ((options!=null)) {
-            data.writeInt(1);
-            options.writeToParcel(data, 0);
-        }
-        else {
-            data.writeInt(0);
-        }
-        mRemote.transact(SEND_INTENT_SENDER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        final int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    @Override
-    public void setVrThread(int tid)
-        throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(tid);
-        mRemote.transact(SET_VR_THREAD_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-        return;
-    }
-
-    public void setRenderThread(int tid)
-        throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(tid);
-        mRemote.transact(SET_RENDER_THREAD_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-        return;
-    }
-
-    public void setHasTopUi(boolean hasTopUi)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(hasTopUi ? 1 : 0);
-        mRemote.transact(SET_HAS_TOP_UI, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-        return;
-    }
-    @Override
-    public boolean canBypassWorkChallenge(PendingIntent intent)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        intent.writeToParcel(data, 0);
-        mRemote.transact(CAN_BYPASS_WORK_CHALLENGE, data, reply, 0);
-        reply.readException();
-        final int result = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return result != 0;
-    }
-
-    private IBinder mRemote;
-}
+}
\ No newline at end of file
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index e9a200f..3e8d90b 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -421,11 +421,10 @@
         final String[] mNames;
         final IContentProvider mProvider;
         final ContentProvider mLocalProvider;
-        final IActivityManager.ContentProviderHolder mHolder;
+        final ContentProviderHolder mHolder;
 
         ProviderClientRecord(String[] names, IContentProvider provider,
-                ContentProvider localProvider,
-                IActivityManager.ContentProviderHolder holder) {
+                ContentProvider localProvider, ContentProviderHolder holder) {
             mNames = names;
             mProvider = provider;
             mLocalProvider = localProvider;
@@ -3825,7 +3824,7 @@
     }
 
     private static final class ProviderRefCount {
-        public final IActivityManager.ContentProviderHolder holder;
+        public final ContentProviderHolder holder;
         public final ProviderClientRecord client;
         public int stableCount;
         public int unstableCount;
@@ -3837,7 +3836,7 @@
         // here.
         public boolean removePending;
 
-        ProviderRefCount(IActivityManager.ContentProviderHolder inHolder,
+        ProviderRefCount(ContentProviderHolder inHolder,
                 ProviderClientRecord inClient, int sCount, int uCount) {
             holder = inHolder;
             client = inClient;
@@ -5480,8 +5479,7 @@
 
     private void installContentProviders(
             Context context, List<ProviderInfo> providers) {
-        final ArrayList<IActivityManager.ContentProviderHolder> results =
-            new ArrayList<IActivityManager.ContentProviderHolder>();
+        final ArrayList<ContentProviderHolder> results = new ArrayList<>();
 
         for (ProviderInfo cpi : providers) {
             if (DEBUG_PROVIDER) {
@@ -5492,7 +5490,7 @@
                 buf.append(cpi.name);
                 Log.i(TAG, buf.toString());
             }
-            IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi,
+            ContentProviderHolder cph = installProvider(context, null, cpi,
                     false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
             if (cph != null) {
                 cph.noReleaseNeeded = true;
@@ -5521,7 +5519,7 @@
         // Note that we cannot hold the lock while acquiring and installing the
         // provider since it might take a long time to run and it could also potentially
         // be re-entrant in the case where the provider is in the same process.
-        IActivityManager.ContentProviderHolder holder = null;
+        ContentProviderHolder holder = null;
         try {
             holder = ActivityManagerNative.getDefault().getContentProvider(
                     getApplicationThread(), auth, userId, stable);
@@ -5821,7 +5819,7 @@
     }
 
     private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider,
-            ContentProvider localProvider, IActivityManager.ContentProviderHolder holder) {
+            ContentProvider localProvider, ContentProviderHolder holder) {
         final String auths[] = holder.info.authority.split(";");
         final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid);
 
@@ -5854,8 +5852,8 @@
      * and returns the existing provider.  This can happen due to concurrent
      * attempts to acquire the same provider.
      */
-    private IActivityManager.ContentProviderHolder installProvider(Context context,
-            IActivityManager.ContentProviderHolder holder, ProviderInfo info,
+    private ContentProviderHolder installProvider(Context context,
+            ContentProviderHolder holder, ProviderInfo info,
             boolean noisy, boolean noReleaseNeeded, boolean stable) {
         ContentProvider localProvider = null;
         IContentProvider provider;
@@ -5915,7 +5913,7 @@
                     + info.name);
         }
 
-        IActivityManager.ContentProviderHolder retHolder;
+        ContentProviderHolder retHolder;
 
         synchronized (mProviderMap) {
             if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider
@@ -5931,7 +5929,7 @@
                     }
                     provider = pr.mProvider;
                 } else {
-                    holder = new IActivityManager.ContentProviderHolder(info);
+                    holder = new ContentProviderHolder(info);
                     holder.provider = provider;
                     holder.noReleaseNeeded = true;
                     pr = installProviderAuthoritiesLocked(provider, localProvider, holder);
diff --git a/core/java/android/app/ApplicationErrorReport.aidl b/core/java/android/app/ApplicationErrorReport.aidl
new file mode 100644
index 0000000..5b57457
--- /dev/null
+++ b/core/java/android/app/ApplicationErrorReport.aidl
@@ -0,0 +1,20 @@
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+/** @hide */
+parcelable ApplicationErrorReport.ParcelableCrashInfo;
\ No newline at end of file
diff --git a/core/java/android/app/ApplicationErrorReport.java b/core/java/android/app/ApplicationErrorReport.java
index 9fa8a5d..6cfa362 100644
--- a/core/java/android/app/ApplicationErrorReport.java
+++ b/core/java/android/app/ApplicationErrorReport.java
@@ -451,6 +451,47 @@
     }
 
     /**
+     * Parcelable version of {@link CrashInfo}
+     *
+     * @hide
+     */
+    public static class ParcelableCrashInfo extends CrashInfo implements Parcelable {
+        /**
+         * Create an uninitialized instance of CrashInfo.
+         */
+        public ParcelableCrashInfo() {
+        }
+
+        /**
+         * Create an instance of CrashInfo initialized from an exception.
+         */
+        public ParcelableCrashInfo(Throwable tr) {
+            super(tr);
+        }
+
+        public ParcelableCrashInfo(Parcel in) {
+            super(in);
+        }
+
+        public int describeContents() {
+            return 0;
+        }
+
+        public static final Parcelable.Creator<ParcelableCrashInfo> CREATOR =
+                new Parcelable.Creator<ParcelableCrashInfo>() {
+                    @Override
+                    public ParcelableCrashInfo createFromParcel(Parcel in) {
+                        return new ParcelableCrashInfo(in);
+                    }
+
+                    @Override
+                    public ParcelableCrashInfo[] newArray(int size) {
+                        return new ParcelableCrashInfo[size];
+                    }
+                };
+    }
+
+    /**
      * Describes an application not responding error.
      */
     public static class AnrInfo {
diff --git a/core/java/android/app/ContentProviderHolder.aidl b/core/java/android/app/ContentProviderHolder.aidl
new file mode 100644
index 0000000..bd56775
--- /dev/null
+++ b/core/java/android/app/ContentProviderHolder.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+/** @hide */
+parcelable ContentProviderHolder;
\ No newline at end of file
diff --git a/core/java/android/app/ContentProviderHolder.java b/core/java/android/app/ContentProviderHolder.java
new file mode 100644
index 0000000..f9998f4
--- /dev/null
+++ b/core/java/android/app/ContentProviderHolder.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import android.content.ContentProviderNative;
+import android.content.IContentProvider;
+import android.content.pm.ProviderInfo;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Information you can retrieve about a particular application.
+ *
+ * @hide
+ */
+public class ContentProviderHolder implements Parcelable {
+    public final ProviderInfo info;
+    public IContentProvider provider;
+    public IBinder connection;
+    public boolean noReleaseNeeded;
+
+    public ContentProviderHolder(ProviderInfo _info) {
+        info = _info;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        info.writeToParcel(dest, 0);
+        if (provider != null) {
+            dest.writeStrongBinder(provider.asBinder());
+        } else {
+            dest.writeStrongBinder(null);
+        }
+        dest.writeStrongBinder(connection);
+        dest.writeInt(noReleaseNeeded ? 1 : 0);
+    }
+
+    public static final Parcelable.Creator<ContentProviderHolder> CREATOR
+            = new Parcelable.Creator<ContentProviderHolder>() {
+        @Override
+        public ContentProviderHolder createFromParcel(Parcel source) {
+            return new ContentProviderHolder(source);
+        }
+
+        @Override
+        public ContentProviderHolder[] newArray(int size) {
+            return new ContentProviderHolder[size];
+        }
+    };
+
+    private ContentProviderHolder(Parcel source) {
+        info = ProviderInfo.CREATOR.createFromParcel(source);
+        provider = ContentProviderNative.asInterface(
+                source.readStrongBinder());
+        connection = source.readStrongBinder();
+        noReleaseNeeded = source.readInt() != 0;
+    }
+}
\ No newline at end of file
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
new file mode 100644
index 0000000..2498459
--- /dev/null
+++ b/core/java/android/app/IActivityManager.aidl
@@ -0,0 +1,567 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import android.app.ActivityManager;
+import android.app.ApplicationErrorReport;
+import android.app.ContentProviderHolder;
+import android.app.IApplicationThread;
+import android.app.IActivityContainer;
+import android.app.IActivityContainerCallback;
+import android.app.IActivityController;
+import android.app.IAppTask;
+import android.app.IInstrumentationWatcher;
+import android.app.IProcessObserver;
+import android.app.IServiceConnection;
+import android.app.IStopUserCallback;
+import android.app.ITaskStackListener;
+import android.app.IUiAutomationConnection;
+import android.app.IUidObserver;
+import android.app.IUserSwitchObserver;
+import android.app.Notification;
+import android.app.PendingIntent;
+import android.app.ProfilerInfo;
+import android.app.WaitResult;
+import android.app.assist.AssistContent;
+import android.app.assist.AssistStructure;
+import android.content.ComponentName;
+import android.content.IIntentReceiver;
+import android.content.IIntentSender;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.IntentSender;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.ConfigurationInfo;
+import android.content.pm.IPackageDataObserver;
+import android.content.pm.ParceledListSlice;
+import android.content.pm.ProviderInfo;
+import android.content.pm.UserInfo;
+import android.content.res.Configuration;
+import android.graphics.Bitmap;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Debug;
+import android.os.IBinder;
+import android.os.IProgressListener;
+import android.os.ParcelFileDescriptor;
+import android.os.PersistableBundle;
+import android.os.StrictMode;
+import android.service.voice.IVoiceInteractionSession;
+import com.android.internal.app.IVoiceInteractor;
+import com.android.internal.os.IResultReceiver;
+
+import java.util.List;
+
+/**
+ * System private API for talking with the activity manager service.  This
+ * provides calls from the application back to the activity manager.
+ *
+ * {@hide}
+ */
+interface IActivityManager {
+    // Please keep these transaction codes the same -- they are also
+    // sent by C++ code. when a new method is added, use the next available transaction id.
+
+    // Special low-level communication with activity manager.
+    void handleApplicationCrash(in IBinder app,
+            in ApplicationErrorReport.ParcelableCrashInfo crashInfo) = 1;
+    int startActivity(in IApplicationThread caller, in String callingPackage, in Intent intent,
+            in String resolvedType, in IBinder resultTo, in String resultWho, int requestCode,
+            int flags, in ProfilerInfo profilerInfo, in Bundle options) = 2;
+    void unhandledBack() = 3;
+    ParcelFileDescriptor openContentUri(in String uriString) = 4;
+
+    boolean finishActivity(in IBinder token, int code, in Intent data, int finishTask) = 10;
+    Intent registerReceiver(in IApplicationThread caller, in String callerPackage,
+            in IIntentReceiver receiver, in IntentFilter filter,
+            in String requiredPermission, int userId) = 11;
+    void unregisterReceiver(in IIntentReceiver receiver) = 12;
+    int broadcastIntent(in IApplicationThread caller, in Intent intent,
+            in String resolvedType, in IIntentReceiver resultTo, int resultCode,
+            in String resultData, in Bundle map, in String[] requiredPermissions,
+            int appOp, in Bundle options, boolean serialized, boolean sticky, int userId) = 13;
+    void unbroadcastIntent(in IApplicationThread caller, in Intent intent, int userId) = 14;
+    oneway void finishReceiver(in IBinder who, int resultCode, in String resultData, in Bundle map,
+            boolean abortBroadcast, int flags) = 15;
+    void attachApplication(in IApplicationThread app) = 16;
+    oneway void activityIdle(in IBinder token, in Configuration config,
+            in boolean stopProfiling) = 17;
+    void activityPaused(in IBinder token) = 18;
+    oneway void activityStopped(in IBinder token, in Bundle state,
+            in PersistableBundle persistentState, in CharSequence description) = 19;
+    String getCallingPackage(in IBinder token) = 20;
+    ComponentName getCallingActivity(in IBinder token) = 21;
+    List<ActivityManager.RunningTaskInfo> getTasks(int maxNum, int flags) = 22;
+    void moveTaskToFront(int task, int flags, in Bundle options) = 23;
+    void moveTaskBackwards(int task) = 25;
+    int getTaskForActivity(in IBinder token, in boolean onlyRoot) = 26;
+    ContentProviderHolder getContentProvider(in IApplicationThread caller,
+            in String name, int userId, boolean stable) = 28;
+    void publishContentProviders(in IApplicationThread caller,
+            in List<ContentProviderHolder> providers) = 29;
+    boolean refContentProvider(in IBinder connection, int stableDelta, int unstableDelta) = 30;
+    void finishSubActivity(in IBinder token, in String resultWho, int requestCode) = 31;
+    PendingIntent getRunningServiceControlPanel(in ComponentName service) = 32;
+    ComponentName startService(in IApplicationThread caller, in Intent service,
+            in String resolvedType, in String callingPackage, int userId) = 33;
+    int stopService(in IApplicationThread caller, in Intent service,
+            in String resolvedType, int userId) = 34;
+    int bindService(in IApplicationThread caller, in IBinder token, in Intent service,
+            in String resolvedType, in IServiceConnection connection, int flags,
+            in String callingPackage, int userId) = 35;
+    boolean unbindService(in IServiceConnection connection) = 36;
+    void publishService(in IBinder token, in Intent intent, in IBinder service) = 37;
+    void activityResumed(in IBinder token) = 38;
+    void setDebugApp(in String packageName, boolean waitForDebugger, boolean persistent) = 41;
+    void setAlwaysFinish(boolean enabled) = 42;
+    boolean startInstrumentation(in ComponentName className, in String profileFile,
+            int flags, in Bundle arguments, in IInstrumentationWatcher watcher,
+            in IUiAutomationConnection connection, int userId,
+            in String abiOverride) = 43;
+    void finishInstrumentation(in IApplicationThread target, int resultCode,
+            in Bundle results) = 44;
+    /**
+     * @return A copy of global {@link Configuration}, contains general settings for the entire
+     *         system. Corresponds to the configuration of the default display.
+     * @throws RemoteException
+     */
+    Configuration getConfiguration() = 45;
+    /**
+     * Updates global configuration and applies changes to the entire system.
+     * @param values Update values for global configuration. If null is passed it will request the
+     *               Window Manager to compute new config for the default display.
+     * @throws RemoteException
+     * @return Returns true if the configuration was updated.
+     */
+    boolean updateConfiguration(in Configuration values) = 46;
+    boolean stopServiceToken(in ComponentName className, in IBinder token, int startId) = 47;
+    ComponentName getActivityClassForToken(in IBinder token) = 48;
+    String getPackageForToken(in IBinder token) = 49;
+    void setProcessLimit(int max) = 50;
+    int getProcessLimit() = 51;
+    int checkPermission(in String permission, int pid, int uid) = 52;
+    int checkUriPermission(in Uri uri, int pid, int uid, int mode, int userId,
+            in IBinder callerToken) = 53;
+    void grantUriPermission(in IApplicationThread caller, in String targetPkg, in Uri uri,
+            int mode, int userId) = 54;
+    void revokeUriPermission(in IApplicationThread caller, in Uri uri, int mode, int userId) = 55;
+    void setActivityController(in IActivityController watcher, boolean imAMonkey) = 56;
+    void showWaitingForDebugger(in IApplicationThread who, boolean waiting) = 57;
+    /*
+     * This will deliver the specified signal to all the persistent processes. Currently only
+     * SIGUSR1 is delivered. All others are ignored.
+     */
+    void signalPersistentProcesses(int signal) = 58;
+    ParceledListSlice getRecentTasks(int maxNum,
+            int flags, int userId) = 59;
+    oneway void serviceDoneExecuting(in IBinder token, int type, int startId, int res) = 60;
+    oneway void activityDestroyed(in IBinder token) = 61;
+    IIntentSender getIntentSender(int type, in String packageName, in IBinder token,
+            in String resultWho, int requestCode, in Intent[] intents, in String[] resolvedTypes,
+            int flags, in Bundle options, int userId) = 62;
+    void cancelIntentSender(in IIntentSender sender) = 63;
+    String getPackageForIntentSender(in IIntentSender sender) = 64;
+    void enterSafeMode() = 65;
+    boolean startNextMatchingActivity(in IBinder callingActivity,
+            in Intent intent, in Bundle options) = 66;
+    void noteWakeupAlarm(in IIntentSender sender, int sourceUid,
+            in String sourcePkg, in String tag) = 67;
+    void removeContentProvider(in IBinder connection, boolean stable) = 68;
+    void setRequestedOrientation(in IBinder token, int requestedOrientation) = 69;
+    int getRequestedOrientation(in IBinder token) = 70;
+    void unbindFinished(in IBinder token, in Intent service, boolean doRebind) = 71;
+    void setProcessForeground(in IBinder token, int pid, boolean isForeground) = 72;
+    void setServiceForeground(in ComponentName className, in IBinder token,
+            int id, in Notification notification, int flags) = 73;
+    boolean moveActivityTaskToBack(in IBinder token, boolean nonRoot) = 74;
+    void getMemoryInfo(out ActivityManager.MemoryInfo outInfo) = 75;
+    List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() = 76;
+    boolean clearApplicationUserData(in String packageName,
+            in IPackageDataObserver observer, int userId) = 77;
+    void forceStopPackage(in String packageName, int userId) = 78;
+    boolean killPids(in int[] pids, in String reason, boolean secure) = 79;
+    List<ActivityManager.RunningServiceInfo> getServices(int maxNum, int flags) = 80;
+    ActivityManager.TaskThumbnail getTaskThumbnail(int taskId) = 81;
+    // Retrieve running application processes in the system
+    List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() = 82;
+    // Get device configuration
+    ConfigurationInfo getDeviceConfigurationInfo() = 83;
+    IBinder peekService(in Intent service, in String resolvedType, in String callingPackage) = 84;
+    // Turn on/off profiling in a particular process.
+    boolean profileControl(in String process, int userId, boolean start,
+            in ProfilerInfo profilerInfo, int profileType) = 85;
+    boolean shutdown(int timeout) = 86;
+    void stopAppSwitches() = 87;
+    void resumeAppSwitches() = 88;
+    boolean bindBackupAgent(in String packageName, int backupRestoreMode, int userId) = 89;
+    void backupAgentCreated(in String packageName, in IBinder agent) = 90;
+    void unbindBackupAgent(in ApplicationInfo appInfo) = 91;
+    int getUidForIntentSender(in IIntentSender sender) = 92;
+    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
+            boolean requireFull, in String name, in String callerPackage) = 93;
+    void addPackageDependency(in String packageName) = 94;
+    void killApplication(in String pkg, int appId, int userId, in String reason) = 95;
+    void closeSystemDialogs(in String reason) = 96;
+    Debug.MemoryInfo[] getProcessMemoryInfo(in int[] pids) = 97;
+    void killApplicationProcess(in String processName, int uid) = 98;
+    int startActivityIntentSender(in IApplicationThread caller,
+            in IntentSender intent, in Intent fillInIntent, in String resolvedType,
+            in IBinder resultTo, in String resultWho, int requestCode,
+            int flagsMask, int flagsValues, in Bundle options) = 99;
+    void overridePendingTransition(in IBinder token, in String packageName,
+            int enterAnim, int exitAnim) = 100;
+    // Special low-level communication with activity manager.
+    boolean handleApplicationWtf(in IBinder app, in String tag, boolean system,
+            in ApplicationErrorReport.ParcelableCrashInfo crashInfo) = 101;
+    void killBackgroundProcesses(in String packageName, int userId) = 102;
+    boolean isUserAMonkey() = 103;
+    WaitResult startActivityAndWait(in IApplicationThread caller, in String callingPackage,
+            in Intent intent, in String resolvedType, in IBinder resultTo, in String resultWho,
+            int requestCode, int flags, in ProfilerInfo profilerInfo, in Bundle options,
+            int userId) = 104;
+    boolean willActivityBeVisible(in IBinder token) = 105;
+    int startActivityWithConfig(in IApplicationThread caller, in String callingPackage,
+            in Intent intent, in String resolvedType, in IBinder resultTo, in String resultWho,
+            int requestCode, int startFlags, in Configuration newConfig,
+            in Bundle options, int userId) = 106;
+    // Retrieve info of applications installed on external media that are currently
+    // running.
+    List<ApplicationInfo> getRunningExternalApplications() = 107;
+    void finishHeavyWeightApp() = 108;
+    // A StrictMode violation to be handled.  The violationMask is a
+    // subset of the original StrictMode policy bitmask, with only the
+    // bit violated and penalty bits to be executed by the
+    // ActivityManagerService remaining set.
+    void handleApplicationStrictModeViolation(in IBinder app, int violationMask,
+            in StrictMode.ViolationInfo crashInfo) = 109;
+    boolean isImmersive(in IBinder token) = 110;
+    void setImmersive(in IBinder token, boolean immersive) = 111;
+    boolean isTopActivityImmersive() = 112;
+    void crashApplication(int uid, int initialPid, in String packageName, in String message) = 113;
+    String getProviderMimeType(in Uri uri, int userId) = 114;
+    IBinder newUriPermissionOwner(in String name) = 115;
+    void grantUriPermissionFromOwner(in IBinder owner, int fromUid, in String targetPkg,
+            in Uri uri, int mode, int sourceUserId, int targetUserId) = 116;
+    void revokeUriPermissionFromOwner(in IBinder owner, in Uri uri, int mode, int userId) = 117;
+    int checkGrantUriPermission(int callingUid, in String targetPkg, in Uri uri,
+            int modeFlags, int userId) = 118;
+    // Cause the specified process to dump the specified heap.
+    boolean dumpHeap(in String process, int userId, boolean managed, in String path,
+            in ParcelFileDescriptor fd) = 119;
+    int startActivities(in IApplicationThread caller, in String callingPackage,
+            in Intent[] intents, in String[] resolvedTypes, in IBinder resultTo,
+            in Bundle options, int userId) = 120;
+    boolean isUserRunning(int userid, int flags) = 121;
+    oneway void activitySlept(in IBinder token) = 122;
+    int getFrontActivityScreenCompatMode() = 123;
+    void setFrontActivityScreenCompatMode(int mode) = 124;
+    int getPackageScreenCompatMode(in String packageName) = 125;
+    void setPackageScreenCompatMode(in String packageName, int mode) = 126;
+    boolean getPackageAskScreenCompat(in String packageName) = 127;
+    void setPackageAskScreenCompat(in String packageName, boolean ask) = 128;
+    boolean switchUser(int userid) = 129;
+    void setFocusedTask(int taskId) = 130;
+    boolean removeTask(int taskId) = 131;
+    void registerProcessObserver(in IProcessObserver observer) = 132;
+    void unregisterProcessObserver(in IProcessObserver observer) = 133;
+    boolean isIntentSenderTargetedToPackage(in IIntentSender sender) = 134;
+    void updatePersistentConfiguration(in Configuration values) = 135;
+    long[] getProcessPss(in int[] pids) = 136;
+    void showBootMessage(in CharSequence msg, boolean always) = 137;
+    void killAllBackgroundProcesses() = 139;
+    ContentProviderHolder getContentProviderExternal(in String name, int userId,
+            in IBinder token) = 140;
+    void removeContentProviderExternal(in String name, in IBinder token) = 141;
+    // Get memory information about the calling process.
+    void getMyMemoryState(out ActivityManager.RunningAppProcessInfo outInfo) = 142;
+    boolean killProcessesBelowForeground(in String reason) = 143;
+    UserInfo getCurrentUser() = 144;
+    boolean shouldUpRecreateTask(in IBinder token, in String destAffinity) = 145;
+    boolean navigateUpTo(in IBinder token, in Intent target, int resultCode,
+            in Intent resultData) = 146;
+    void setLockScreenShown(boolean showing) = 147;
+    boolean finishActivityAffinity(in IBinder token) = 148;
+    // This is not public because you need to be very careful in how you
+    // manage your activity to make sure it is always the uid you expect.
+    int getLaunchedFromUid(in IBinder activityToken) = 149;
+    void unstableProviderDied(in IBinder connection) = 150;
+    boolean isIntentSenderAnActivity(in IIntentSender sender) = 151;
+    int startActivityAsUser(in IApplicationThread caller, in String callingPackage,
+            in Intent intent, in String resolvedType, in IBinder resultTo, in String resultWho,
+            int requestCode, int flags, in ProfilerInfo profilerInfo,
+            in Bundle options, int userId) = 152;
+    int stopUser(int userid, boolean force, in IStopUserCallback callback) = 153;
+    void registerUserSwitchObserver(in IUserSwitchObserver observer, in String name) = 154;
+    void unregisterUserSwitchObserver(in IUserSwitchObserver observer) = 155;
+    int[] getRunningUserIds() = 156;
+    void requestBugReport(int bugreportType) = 157;
+    long inputDispatchingTimedOut(int pid, boolean aboveSystem, in String reason) = 158;
+    void clearPendingBackup() = 159;
+    Intent getIntentForIntentSender(in IIntentSender sender) = 160;
+    Bundle getAssistContextExtras(int requestType) = 161;
+    void reportAssistContextExtras(in IBinder token, in Bundle extras,
+            in AssistStructure structure, in AssistContent content, in Uri referrer) = 162;
+    // This is not public because you need to be very careful in how you
+    // manage your activity to make sure it is always the uid you expect.
+    String getLaunchedFromPackage(in IBinder activityToken) = 163;
+    void killUid(int appId, int userId, in String reason) = 164;
+    void setUserIsMonkey(boolean monkey) = 165;
+    void hang(in IBinder who, boolean allowRestart) = 166;
+    IActivityContainer createVirtualActivityContainer(in IBinder parentActivityToken,
+            in IActivityContainerCallback callback) = 167;
+    void moveTaskToStack(int taskId, int stackId, boolean toTop) = 168;
+    /**
+     * Resizes the input stack id to the given bounds.
+     *
+     * @param stackId Id of the stack to resize.
+     * @param bounds Bounds to resize the stack to or {@code null} for fullscreen.
+     * @param allowResizeInDockedMode True if the resize should be allowed when the docked stack is
+     *                                active.
+     * @param preserveWindows True if the windows of activities contained in the stack should be
+     *                        preserved.
+     * @param animate True if the stack resize should be animated.
+     * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
+     *                          default animation duration should be used.
+     * @throws RemoteException
+     */
+    void resizeStack(int stackId, in Rect bounds, boolean allowResizeInDockedMode,
+            boolean preserveWindows, boolean animate, int animationDuration) = 169;
+    List<ActivityManager.StackInfo> getAllStackInfos() = 170;
+    void setFocusedStack(int stackId) = 171;
+    ActivityManager.StackInfo getStackInfo(int stackId) = 172;
+    boolean convertFromTranslucent(in IBinder token) = 173;
+    boolean convertToTranslucent(in IBinder token, in Bundle options) = 174;
+    void notifyActivityDrawn(in IBinder token) = 175;
+    void reportActivityFullyDrawn(in IBinder token) = 176;
+    void restart() = 177;
+    void performIdleMaintenance() = 178;
+    void takePersistableUriPermission(in Uri uri, int modeFlags, int userId) = 179;
+    void releasePersistableUriPermission(in Uri uri, int modeFlags, int userId) = 180;
+    ParceledListSlice getPersistedUriPermissions(in String packageName, boolean incoming) = 181;
+    void appNotRespondingViaProvider(in IBinder connection) = 182;
+    Rect getTaskBounds(int taskId) = 183;
+    int getActivityDisplayId(in IBinder activityToken) = 184;
+    boolean setProcessMemoryTrimLevel(in String process, int uid, int level) = 186;
+
+
+    // Start of L transactions
+    String getTagForIntentSender(in IIntentSender sender, in String prefix) = 210;
+    boolean startUserInBackground(int userid) = 211;
+    boolean isInHomeStack(int taskId) = 212;
+    void startLockTaskModeById(int taskId) = 213;
+    void startLockTaskModeByToken(in IBinder token) = 214;
+    void stopLockTaskMode() = 215;
+    boolean isInLockTaskMode() = 216;
+    void setTaskDescription(in IBinder token, in ActivityManager.TaskDescription values) = 217;
+    int startVoiceActivity(in String callingPackage, int callingPid, int callingUid,
+            in Intent intent, in String resolvedType, in IVoiceInteractionSession session,
+            in IVoiceInteractor interactor, int flags, in ProfilerInfo profilerInfo,
+            in Bundle options, int userId) = 218;
+    Bundle getActivityOptions(in IBinder token) = 219;
+    List<IBinder> getAppTasks(in String callingPackage) = 220;
+    void startSystemLockTaskMode(int taskId) = 221;
+    void stopSystemLockTaskMode() = 222;
+    void finishVoiceTask(in IVoiceInteractionSession session) = 223;
+    boolean isTopOfTask(in IBinder token) = 224;
+    boolean requestVisibleBehind(in IBinder token, boolean visible) = 225;
+    boolean isBackgroundVisibleBehind(in IBinder token) = 226;
+    void backgroundResourcesReleased(in IBinder token) = 227;
+    void notifyLaunchTaskBehindComplete(in IBinder token) = 228;
+    int startActivityFromRecents(int taskId, in Bundle options) = 229;
+    void notifyEnterAnimationComplete(in IBinder token) = 230;
+    int startActivityAsCaller(in IApplicationThread caller, in String callingPackage,
+            in Intent intent, in String resolvedType, in IBinder resultTo, in String resultWho,
+            int requestCode, int flags, in ProfilerInfo profilerInfo, in Bundle options,
+            boolean ignoreTargetSecurity, int userId) = 232;
+    int addAppTask(in IBinder activityToken, in Intent intent,
+            in ActivityManager.TaskDescription description, in Bitmap thumbnail) = 233;
+    Point getAppTaskThumbnailSize() = 234;
+    boolean releaseActivityInstance(in IBinder token) = 235;
+    void releaseSomeActivities(in IApplicationThread app) = 236;
+    void bootAnimationComplete() = 237;
+    Bitmap getTaskDescriptionIcon(in String filename, int userId) = 238;
+    boolean launchAssistIntent(in Intent intent, int requestType, in String hint, int userHandle,
+            in Bundle args) = 239;
+    void startInPlaceAnimationOnFrontMostApplication(in Bundle opts) = 240;
+    int checkPermissionWithToken(in String permission, int pid, int uid,
+            in IBinder callerToken) = 241;
+    void registerTaskStackListener(in ITaskStackListener listener) = 242;
+
+
+    // Start of M transactions
+    void notifyCleartextNetwork(int uid, in byte[] firstPacket) = 280;
+    IActivityContainer createStackOnDisplay(int displayId) = 281;
+    int getFocusedStackId() = 282;
+    void setTaskResizeable(int taskId, int resizeableMode) = 283;
+    boolean requestAssistContextExtras(int requestType, in IResultReceiver receiver,
+            in Bundle receiverExtras, in IBinder activityToken,
+            boolean focused, boolean newSessionId) = 284;
+    void resizeTask(int taskId, in Rect bounds, int resizeMode) = 285;
+    int getLockTaskModeState() = 286;
+    void setDumpHeapDebugLimit(in String processName, int uid, long maxMemSize,
+            in String reportPackage) = 287;
+    void dumpHeapFinished(in String path) = 288;
+    void setVoiceKeepAwake(in IVoiceInteractionSession session, boolean keepAwake) = 289;
+    void updateLockTaskPackages(int userId, in String[] packages) = 290;
+    void noteAlarmStart(in IIntentSender sender, int sourceUid, in String tag) = 291;
+    void noteAlarmFinish(in IIntentSender sender, int sourceUid, in String tag) = 292;
+    int getPackageProcessState(in String packageName, in String callingPackage) = 293;
+    oneway void showLockTaskEscapeMessage(in IBinder token) = 294;
+    void updateDeviceOwner(in String packageName) = 295;
+    /**
+     * Notify the system that the keyguard is going away.
+     *
+     * @param flags See {@link android.view.WindowManagerPolicy#KEYGUARD_GOING_AWAY_FLAG_TO_SHADE}
+     *              etc.
+     */
+    void keyguardGoingAway(int flags) = 296;
+    void registerUidObserver(in IUidObserver observer, int which) = 297;
+    void unregisterUidObserver(in IUidObserver observer) = 298;
+    boolean isAssistDataAllowedOnCurrentActivity() = 299;
+    boolean showAssistFromActivity(in IBinder token, in Bundle args) = 300;
+    boolean isRootVoiceInteraction(in IBinder token) = 301;
+
+
+    // Start of N transactions
+    // Start Binder transaction tracking for all applications.
+    boolean startBinderTracking() = 340;
+    // Stop Binder transaction tracking for all applications and dump trace data to the given file
+    // descriptor.
+    boolean stopBinderTrackingAndDump(in ParcelFileDescriptor fd) = 341;
+    void positionTaskInStack(int taskId, int stackId, int position) = 342;
+    int getActivityStackId(in IBinder token) = 343;
+    void exitFreeformMode(in IBinder token) = 344;
+    void reportSizeConfigurations(in IBinder token, in int[] horizontalSizeConfiguration,
+            in int[] verticalSizeConfigurations, in int[] smallestWidthConfigurations) = 345;
+    boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
+            in Rect initialBounds, boolean moveHomeStackFront) = 346;
+    void suppressResizeConfigChanges(boolean suppress) = 347;
+    void moveTasksToFullscreenStack(int fromStackId, boolean onTop) = 348;
+    boolean moveTopActivityToPinnedStack(int stackId, in Rect bounds) = 349;
+    int getAppStartMode(int uid, in String packageName) = 350;
+    boolean unlockUser(int userid, in byte[] token, in byte[] secret,
+            in IProgressListener listener) = 351;
+    boolean isInMultiWindowMode(in IBinder token) = 352;
+    boolean isInPictureInPictureMode(in IBinder token) = 353;
+    void killPackageDependents(in String packageName, int userId) = 354;
+    void enterPictureInPictureMode(in IBinder token) = 355;
+    void activityRelaunched(in IBinder token) = 356;
+    IBinder getUriPermissionOwnerForActivity(in IBinder activityToken) = 357;
+    /**
+     * Resizes the docked stack, and all other stacks as the result of the dock stack bounds change.
+     *
+     * @param dockedBounds The bounds for the docked stack.
+     * @param tempDockedTaskBounds The temporary bounds for the tasks in the docked stack, which
+     *                             might be different from the stack bounds to allow more
+     *                             flexibility while resizing, or {@code null} if they should be the
+     *                             same as the stack bounds.
+     * @param tempDockedTaskInsetBounds The temporary bounds for the tasks to calculate the insets.
+     *                                  When resizing, we usually "freeze" the layout of a task. To
+     *                                  achieve that, we also need to "freeze" the insets, which
+     *                                  gets achieved by changing task bounds but not bounds used
+     *                                  to calculate the insets in this transient state
+     * @param tempOtherTaskBounds The temporary bounds for the tasks in all other stacks, or
+     *                            {@code null} if they should be the same as the stack bounds.
+     * @param tempOtherTaskInsetBounds Like {@code tempDockedTaskInsetBounds}, but for the other
+     *                                 stacks.
+     * @throws RemoteException
+     */
+    void resizeDockedStack(in Rect dockedBounds, in Rect tempDockedTaskBounds,
+            in Rect tempDockedTaskInsetBounds,
+            in Rect tempOtherTaskBounds, in Rect tempOtherTaskInsetBounds) = 358;
+    int setVrMode(in IBinder token, boolean enabled, in ComponentName packageName) = 359;
+    // Gets the URI permissions granted to an arbitrary package.
+    // NOTE: this is different from getPersistedUriPermissions(), which returns the URIs the package
+    // granted to another packages (instead of those granted to it).
+    ParceledListSlice getGrantedUriPermissions(in String packageName, int userId) = 360;
+    // Clears the URI permissions granted to an arbitrary package.
+    void clearGrantedUriPermissions(in String packageName, int userId) = 361;
+    boolean isAppForeground(int uid) = 362;
+    void startLocalVoiceInteraction(in IBinder token, in Bundle options) = 363;
+    void stopLocalVoiceInteraction(in IBinder token) = 364;
+    boolean supportsLocalVoiceInteraction() = 365;
+    void notifyPinnedStackAnimationEnded() = 366;
+    void removeStack(int stackId) = 367;
+    void setLenientBackgroundCheck(boolean enabled) = 368;
+    int getMemoryTrimLevel() = 369;
+    /**
+     * Resizes the pinned stack.
+     *
+     * @param pinnedBounds The bounds for the pinned stack.
+     * @param tempPinnedTaskBounds The temporary bounds for the tasks in the pinned stack, which
+     *                             might be different from the stack bounds to allow more
+     *                             flexibility while resizing, or {@code null} if they should be the
+     *                             same as the stack bounds.
+     */
+    void resizePinnedStack(in Rect pinnedBounds, in Rect tempPinnedTaskBounds) = 370;
+    boolean isVrModePackageEnabled(in ComponentName packageName) = 371;
+    /**
+     * Moves all tasks from the docked stack in the fullscreen stack and puts the top task of the
+     * fullscreen stack into the docked stack.
+     */
+    void swapDockedAndFullscreenStack() = 372;
+    void notifyLockedProfile(int userId) = 373;
+    void startConfirmDeviceCredentialIntent(in Intent intent) = 374;
+    void sendIdleJobTrigger() = 375;
+    int sendIntentSender(in IIntentSender target, int code, in Intent intent,
+            in String resolvedType, in IIntentReceiver finishedReceiver,
+            in String requiredPermission, in Bundle options) = 376;
+
+
+    // Start of N MR1 transactions
+    void setVrThread(int tid) = 377;
+    void setRenderThread(int tid) = 378;
+    /**
+     * Lets activity manager know whether the calling process is currently showing "top-level" UI
+     * that is not an activity, i.e. windows on the screen the user is currently interacting with.
+     *
+     * <p>This flag can only be set for persistent processes.
+     *
+     * @param hasTopUi Whether the calling process has "top-level" UI.
+     */
+    void setHasTopUi(boolean hasTopUi) = 379;
+    /**
+     * Returns if the target of the PendingIntent can be fired directly, without triggering
+     * a work profile challenge. This can happen if the PendingIntent is to start direct-boot
+     * aware activities, and the target user is in RUNNING_LOCKED state, i.e. we should allow
+     * direct-boot aware activity to bypass work challenge when the user hasn't unlocked yet.
+     * @param intent the {@link  PendingIntent} to be tested.
+     * @return {@code true} if the intent should not trigger a work challenge, {@code false}
+     *     otherwise.
+     * @throws RemoteException
+     */
+    boolean canBypassWorkChallenge(in PendingIntent intent) = 380;
+
+    // Start of O transactions
+    void requestActivityRelaunch(in IBinder token) = 400;
+    /**
+     * Updates override configuration applied to specific display.
+     * @param values Update values for display configuration. If null is passed it will request the
+     *               Window Manager to compute new config for the specified display.
+     * @param displayId Id of the display to apply the config to.
+     * @throws RemoteException
+     * @return Returns true if the configuration was updated.
+     */
+    boolean updateDisplayOverrideConfiguration(in Configuration values, int displayId) = 401;
+    void unregisterTaskStackListener(ITaskStackListener listener) = 402;
+    void moveStackToDisplay(int stackId, int displayId) = 403;
+
+    // Please keep these transaction codes the same -- they are also
+    // sent by C++ code. when a new method is added, use the next available transaction id.
+}
\ No newline at end of file
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
deleted file mode 100644
index 7166789..0000000
--- a/core/java/android/app/IActivityManager.java
+++ /dev/null
@@ -1,1105 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app;
-
-import android.annotation.UserIdInt;
-import android.app.ActivityManager.RunningServiceInfo;
-import android.app.ActivityManager.RunningTaskInfo;
-import android.app.ActivityManager.StackInfo;
-import android.app.assist.AssistContent;
-import android.app.assist.AssistStructure;
-import android.content.ComponentName;
-import android.content.ContentProviderNative;
-import android.content.IContentProvider;
-import android.content.IIntentReceiver;
-import android.content.IIntentSender;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.IntentSender;
-import android.content.UriPermission;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.ConfigurationInfo;
-import android.content.pm.IPackageDataObserver;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.ParceledListSlice;
-import android.content.pm.ProviderInfo;
-import android.content.pm.UserInfo;
-import android.content.res.Configuration;
-import android.graphics.Bitmap;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Debug;
-import android.os.IBinder;
-import android.os.IInterface;
-import android.os.IProgressListener;
-import android.os.Parcel;
-import android.os.ParcelFileDescriptor;
-import android.os.Parcelable;
-import android.os.PersistableBundle;
-import android.os.RemoteException;
-import android.os.StrictMode;
-import android.service.voice.IVoiceInteractionSession;
-import com.android.internal.app.IVoiceInteractor;
-import com.android.internal.os.IResultReceiver;
-
-import java.util.List;
-
-/**
- * System private API for talking with the activity manager service.  This
- * provides calls from the application back to the activity manager.
- *
- * {@hide}
- */
-public interface IActivityManager extends IInterface {
-    public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
-            String resolvedType, IBinder resultTo, String resultWho, int requestCode, int flags,
-            ProfilerInfo profilerInfo, Bundle options) throws RemoteException;
-    public int startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent,
-            String resolvedType, IBinder resultTo, String resultWho, int requestCode, int flags,
-            ProfilerInfo profilerInfo, Bundle options, int userId) throws RemoteException;
-    public int startActivityAsCaller(IApplicationThread caller, String callingPackage,
-            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
-            int flags, ProfilerInfo profilerInfo, Bundle options, boolean ignoreTargetSecurity,
-            int userId) throws RemoteException;
-    public WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
-            Intent intent, String resolvedType, IBinder resultTo, String resultWho,
-            int requestCode, int flags, ProfilerInfo profilerInfo, Bundle options,
-            int userId) throws RemoteException;
-    public int startActivityWithConfig(IApplicationThread caller, String callingPackage,
-            Intent intent, String resolvedType, IBinder resultTo, String resultWho,
-            int requestCode, int startFlags, Configuration newConfig,
-            Bundle options, int userId) throws RemoteException;
-    public int startActivityIntentSender(IApplicationThread caller,
-            IntentSender intent, Intent fillInIntent, String resolvedType,
-            IBinder resultTo, String resultWho, int requestCode,
-            int flagsMask, int flagsValues, Bundle options) throws RemoteException;
-    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
-            Intent intent, String resolvedType, IVoiceInteractionSession session,
-            IVoiceInteractor interactor, int flags, ProfilerInfo profilerInfo, Bundle options,
-            int userId) throws RemoteException;
-    public boolean startNextMatchingActivity(IBinder callingActivity,
-            Intent intent, Bundle options) throws RemoteException;
-    public int startActivityFromRecents(int taskId, Bundle options)
-            throws RemoteException;
-    public boolean finishActivity(IBinder token, int code, Intent data, int finishTask)
-            throws RemoteException;
-    public void finishSubActivity(IBinder token, String resultWho, int requestCode) throws RemoteException;
-    public boolean finishActivityAffinity(IBinder token) throws RemoteException;
-    public void finishVoiceTask(IVoiceInteractionSession session) throws RemoteException;
-    public void requestActivityRelaunch(IBinder token) throws RemoteException;
-    public boolean releaseActivityInstance(IBinder token) throws RemoteException;
-    public void releaseSomeActivities(IApplicationThread app) throws RemoteException;
-    public boolean willActivityBeVisible(IBinder token) throws RemoteException;
-    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
-            IIntentReceiver receiver, IntentFilter filter,
-            String requiredPermission, int userId) throws RemoteException;
-    public void unregisterReceiver(IIntentReceiver receiver) throws RemoteException;
-    public int broadcastIntent(IApplicationThread caller, Intent intent,
-            String resolvedType, IIntentReceiver resultTo, int resultCode,
-            String resultData, Bundle map, String[] requiredPermissions,
-            int appOp, Bundle options, boolean serialized, boolean sticky, int userId) throws RemoteException;
-    public void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) throws RemoteException;
-    public void finishReceiver(IBinder who, int resultCode, String resultData, Bundle map,
-            boolean abortBroadcast, int flags) throws RemoteException;
-    public void attachApplication(IApplicationThread app) throws RemoteException;
-    public void activityResumed(IBinder token) throws RemoteException;
-    public void activityIdle(IBinder token, Configuration config,
-            boolean stopProfiling) throws RemoteException;
-    public void activityPaused(IBinder token) throws RemoteException;
-    public void activityStopped(IBinder token, Bundle state,
-            PersistableBundle persistentState, CharSequence description) throws RemoteException;
-    public void activitySlept(IBinder token) throws RemoteException;
-    public void activityDestroyed(IBinder token) throws RemoteException;
-    public void activityRelaunched(IBinder token) throws RemoteException;
-    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
-            int[] verticalSizeConfigurations, int[] smallestWidthConfigurations)
-            throws RemoteException;
-    public String getCallingPackage(IBinder token) throws RemoteException;
-    public ComponentName getCallingActivity(IBinder token) throws RemoteException;
-    public List<IAppTask> getAppTasks(String callingPackage) throws RemoteException;
-    public int addAppTask(IBinder activityToken, Intent intent,
-            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException;
-    public Point getAppTaskThumbnailSize() throws RemoteException;
-    public List<RunningTaskInfo> getTasks(int maxNum, int flags) throws RemoteException;
-    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
-            int flags, int userId) throws RemoteException;
-    public ActivityManager.TaskThumbnail getTaskThumbnail(int taskId) throws RemoteException;
-    public List<RunningServiceInfo> getServices(int maxNum, int flags) throws RemoteException;
-    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState()
-            throws RemoteException;
-    public void moveStackToDisplay(int stackId, int displayId) throws RemoteException;
-    public void moveTaskToFront(int task, int flags, Bundle options) throws RemoteException;
-    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) throws RemoteException;
-    public void moveTaskBackwards(int task) throws RemoteException;
-    public void moveTaskToStack(int taskId, int stackId, boolean toTop) throws RemoteException;
-    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
-            Rect initialBounds, boolean moveHomeStackFront) throws RemoteException;
-    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) throws RemoteException;
-
-    /**
-     * Resizes the input stack id to the given bounds.
-     *
-     * @param stackId Id of the stack to resize.
-     * @param bounds Bounds to resize the stack to or {@code null} for fullscreen.
-     * @param allowResizeInDockedMode True if the resize should be allowed when the docked stack is
-     *                                active.
-     * @param preserveWindows True if the windows of activities contained in the stack should be
-     *                        preserved.
-     * @param animate True if the stack resize should be animated.
-     * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
-     *                          default animation duration should be used.
-     * @throws RemoteException
-     */
-    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
-            boolean preserveWindows, boolean animate, int animationDuration) throws RemoteException;
-
-    /**
-     * Moves all tasks from the docked stack in the fullscreen stack and puts the top task of the
-     * fullscreen stack into the docked stack.
-     */
-    public void swapDockedAndFullscreenStack() throws RemoteException;
-
-    /**
-     * Resizes the docked stack, and all other stacks as the result of the dock stack bounds change.
-     *
-     * @param dockedBounds The bounds for the docked stack.
-     * @param tempDockedTaskBounds The temporary bounds for the tasks in the docked stack, which
-     *                             might be different from the stack bounds to allow more
-     *                             flexibility while resizing, or {@code null} if they should be the
-     *                             same as the stack bounds.
-     * @param tempDockedTaskInsetBounds The temporary bounds for the tasks to calculate the insets.
-     *                                  When resizing, we usually "freeze" the layout of a task. To
-     *                                  achieve that, we also need to "freeze" the insets, which
-     *                                  gets achieved by changing task bounds but not bounds used
-     *                                  to calculate the insets in this transient state
-     * @param tempOtherTaskBounds The temporary bounds for the tasks in all other stacks, or
-     *                            {@code null} if they should be the same as the stack bounds.
-     * @param tempOtherTaskInsetBounds Like {@code tempDockedTaskInsetBounds}, but for the other
-     *                                 stacks.
-     * @throws RemoteException
-     */
-    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
-            Rect tempDockedTaskInsetBounds,
-            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) throws RemoteException;
-    /**
-     * Resizes the pinned stack.
-     *
-     * @param pinnedBounds The bounds for the pinned stack.
-     * @param tempPinnedTaskBounds The temporary bounds for the tasks in the pinned stack, which
-     *                             might be different from the stack bounds to allow more
-     *                             flexibility while resizing, or {@code null} if they should be the
-     *                             same as the stack bounds.
-     */
-    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) throws RemoteException;
-    public void positionTaskInStack(int taskId, int stackId, int position) throws RemoteException;
-    public List<StackInfo> getAllStackInfos() throws RemoteException;
-    public StackInfo getStackInfo(int stackId) throws RemoteException;
-    public boolean isInHomeStack(int taskId) throws RemoteException;
-    public void setFocusedStack(int stackId) throws RemoteException;
-    public int getFocusedStackId() throws RemoteException;
-    public void setFocusedTask(int taskId) throws RemoteException;
-    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException;
-    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException;
-    public int getTaskForActivity(IBinder token, boolean onlyRoot) throws RemoteException;
-    public ContentProviderHolder getContentProvider(IApplicationThread caller,
-            String name, int userId, boolean stable) throws RemoteException;
-    public ContentProviderHolder getContentProviderExternal(String name, int userId, IBinder token)
-            throws RemoteException;
-    public void removeContentProvider(IBinder connection, boolean stable) throws RemoteException;
-    public void removeContentProviderExternal(String name, IBinder token) throws RemoteException;
-    public void publishContentProviders(IApplicationThread caller,
-            List<ContentProviderHolder> providers) throws RemoteException;
-    public boolean refContentProvider(IBinder connection, int stableDelta, int unstableDelta)
-            throws RemoteException;
-    public void unstableProviderDied(IBinder connection) throws RemoteException;
-    public void appNotRespondingViaProvider(IBinder connection) throws RemoteException;
-    public PendingIntent getRunningServiceControlPanel(ComponentName service)
-            throws RemoteException;
-    public ComponentName startService(IApplicationThread caller, Intent service,
-            String resolvedType, String callingPackage, int userId) throws RemoteException;
-    public int stopService(IApplicationThread caller, Intent service,
-            String resolvedType, int userId) throws RemoteException;
-    public boolean stopServiceToken(ComponentName className, IBinder token,
-            int startId) throws RemoteException;
-    public void setServiceForeground(ComponentName className, IBinder token,
-            int id, Notification notification, int flags) throws RemoteException;
-    public int bindService(IApplicationThread caller, IBinder token, Intent service,
-            String resolvedType, IServiceConnection connection, int flags,
-            String callingPackage, int userId) throws RemoteException;
-    public boolean unbindService(IServiceConnection connection) throws RemoteException;
-    public void publishService(IBinder token,
-            Intent intent, IBinder service) throws RemoteException;
-    public void unbindFinished(IBinder token, Intent service,
-            boolean doRebind) throws RemoteException;
-    /* oneway */
-    public void serviceDoneExecuting(IBinder token, int type, int startId,
-            int res) throws RemoteException;
-    public IBinder peekService(Intent service, String resolvedType, String callingPackage)
-            throws RemoteException;
-
-    public boolean bindBackupAgent(String packageName, int backupRestoreMode, int userId)
-            throws RemoteException;
-    public void clearPendingBackup() throws RemoteException;
-    public void backupAgentCreated(String packageName, IBinder agent) throws RemoteException;
-    public void unbindBackupAgent(ApplicationInfo appInfo) throws RemoteException;
-    public void killApplicationProcess(String processName, int uid) throws RemoteException;
-
-    public boolean startInstrumentation(ComponentName className, String profileFile,
-            int flags, Bundle arguments, IInstrumentationWatcher watcher,
-            IUiAutomationConnection connection, int userId,
-            String abiOverride) throws RemoteException;
-    public void finishInstrumentation(IApplicationThread target,
-            int resultCode, Bundle results) throws RemoteException;
-
-    /**
-     * @return A copy of global {@link Configuration}, contains general settings for the entire
-     *         system. Corresponds to the configuration of the default display.
-     * @throws RemoteException
-     */
-    public Configuration getConfiguration() throws RemoteException;
-
-    /**
-     * Updates global configuration and applies changes to the entire system.
-     * @param values Update values for global configuration. If null is passed it will request the
-     *               Window Manager to compute new config for the default display.
-     * @throws RemoteException
-     * @return Returns true if the configuration was updated.
-     */
-    public boolean updateConfiguration(Configuration values) throws RemoteException;
-
-    /**
-     * Updates override configuration applied to specific display.
-     * @param values Update values for display configuration. If null is passed it will request the
-     *               Window Manager to compute new config for the specified display.
-     * @param displayId Id of the display to apply the config to.
-     * @throws RemoteException
-     * @return Returns true if the configuration was updated.
-     */
-    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId)
-            throws RemoteException;
-
-    public void setRequestedOrientation(IBinder token,
-            int requestedOrientation) throws RemoteException;
-    public int getRequestedOrientation(IBinder token) throws RemoteException;
-
-    public ComponentName getActivityClassForToken(IBinder token) throws RemoteException;
-    public String getPackageForToken(IBinder token) throws RemoteException;
-
-    public IIntentSender getIntentSender(int type,
-            String packageName, IBinder token, String resultWho,
-            int requestCode, Intent[] intents, String[] resolvedTypes,
-            int flags, Bundle options, int userId) throws RemoteException;
-    public void cancelIntentSender(IIntentSender sender) throws RemoteException;
-    public boolean clearApplicationUserData(final String packageName,
-            final IPackageDataObserver observer, int userId) throws RemoteException;
-    public String getPackageForIntentSender(IIntentSender sender) throws RemoteException;
-    public int getUidForIntentSender(IIntentSender sender) throws RemoteException;
-
-    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
-            boolean requireFull, String name, String callerPackage) throws RemoteException;
-
-    public void setProcessLimit(int max) throws RemoteException;
-    public int getProcessLimit() throws RemoteException;
-
-    public void setProcessForeground(IBinder token, int pid,
-            boolean isForeground) throws RemoteException;
-
-    public int checkPermission(String permission, int pid, int uid)
-            throws RemoteException;
-    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken)
-            throws RemoteException;
-
-    public int checkUriPermission(Uri uri, int pid, int uid, int mode, int userId,
-            IBinder callerToken) throws RemoteException;
-    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
-            int mode, int userId) throws RemoteException;
-    public void revokeUriPermission(IApplicationThread caller, Uri uri, int mode, int userId)
-            throws RemoteException;
-    public void takePersistableUriPermission(Uri uri, int modeFlags, int userId)
-            throws RemoteException;
-    public void releasePersistableUriPermission(Uri uri, int modeFlags, int userId)
-            throws RemoteException;
-    public ParceledListSlice<UriPermission> getPersistedUriPermissions(
-            String packageName, boolean incoming) throws RemoteException;
-
-    // Gets the URI permissions granted to an arbitrary package.
-    // NOTE: this is different from getPersistedUriPermissions(), which returns the URIs the package
-    // granted to another packages (instead of those granted to it).
-    public ParceledListSlice<UriPermission> getGrantedUriPermissions(String packageName, int userId)
-            throws RemoteException;
-
-    // Clears the URI permissions granted to an arbitrary package.
-    public void clearGrantedUriPermissions(String packageName, int userId) throws RemoteException;
-
-    public void showWaitingForDebugger(IApplicationThread who, boolean waiting)
-            throws RemoteException;
-
-    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) throws RemoteException;
-
-    public void killBackgroundProcesses(final String packageName, int userId)
-            throws RemoteException;
-    public void killAllBackgroundProcesses() throws RemoteException;
-    public void killPackageDependents(final String packageName, int userId) throws RemoteException;
-    public void forceStopPackage(final String packageName, int userId) throws RemoteException;
-
-    public void setLockScreenShown(boolean showing) throws RemoteException;
-
-    public void unhandledBack() throws RemoteException;
-    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException;
-    public void setDebugApp(
-        String packageName, boolean waitForDebugger, boolean persistent)
-        throws RemoteException;
-    public void setAlwaysFinish(boolean enabled) throws RemoteException;
-    public void setActivityController(IActivityController watcher, boolean imAMonkey)
-        throws RemoteException;
-    public void setLenientBackgroundCheck(boolean enabled) throws RemoteException;
-    public int getMemoryTrimLevel() throws RemoteException;
-
-    public void enterSafeMode() throws RemoteException;
-
-    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag)
-            throws RemoteException;
-    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag)
-            throws RemoteException;
-    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag)
-            throws RemoteException;
-
-    public boolean killPids(int[] pids, String reason, boolean secure) throws RemoteException;
-    public boolean killProcessesBelowForeground(String reason) throws RemoteException;
-
-    // Special low-level communication with activity manager.
-    public void handleApplicationCrash(IBinder app,
-            ApplicationErrorReport.CrashInfo crashInfo) throws RemoteException;
-    public boolean handleApplicationWtf(IBinder app, String tag, boolean system,
-            ApplicationErrorReport.CrashInfo crashInfo) throws RemoteException;
-
-    // A StrictMode violation to be handled.  The violationMask is a
-    // subset of the original StrictMode policy bitmask, with only the
-    // bit violated and penalty bits to be executed by the
-    // ActivityManagerService remaining set.
-    public void handleApplicationStrictModeViolation(IBinder app, int violationMask,
-            StrictMode.ViolationInfo crashInfo) throws RemoteException;
-
-    /*
-     * This will deliver the specified signal to all the persistent processes. Currently only
-     * SIGUSR1 is delivered. All others are ignored.
-     */
-    public void signalPersistentProcesses(int signal) throws RemoteException;
-    // Retrieve running application processes in the system
-    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses()
-            throws RemoteException;
-    // Retrieve info of applications installed on external media that are currently
-    // running.
-    public List<ApplicationInfo> getRunningExternalApplications()
-            throws RemoteException;
-    // Get memory information about the calling process.
-    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo)
-            throws RemoteException;
-    // Get device configuration
-    public ConfigurationInfo getDeviceConfigurationInfo() throws RemoteException;
-
-    // Turn on/off profiling in a particular process.
-    public boolean profileControl(String process, int userId, boolean start,
-            ProfilerInfo profilerInfo, int profileType) throws RemoteException;
-
-    public boolean shutdown(int timeout) throws RemoteException;
-
-    public void stopAppSwitches() throws RemoteException;
-    public void resumeAppSwitches() throws RemoteException;
-
-    public void addPackageDependency(String packageName) throws RemoteException;
-
-    public void killApplication(String pkg, int appId, int userId, String reason)
-            throws RemoteException;
-
-    public void closeSystemDialogs(String reason) throws RemoteException;
-
-    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
-            throws RemoteException;
-
-    public void overridePendingTransition(IBinder token, String packageName,
-            int enterAnim, int exitAnim) throws RemoteException;
-
-    public boolean isUserAMonkey() throws RemoteException;
-
-    public void setUserIsMonkey(boolean monkey) throws RemoteException;
-
-    public void finishHeavyWeightApp() throws RemoteException;
-
-    public boolean convertFromTranslucent(IBinder token) throws RemoteException;
-    public boolean convertToTranslucent(IBinder token, ActivityOptions options) throws RemoteException;
-    public void notifyActivityDrawn(IBinder token) throws RemoteException;
-    public ActivityOptions getActivityOptions(IBinder token) throws RemoteException;
-
-    public void bootAnimationComplete() throws RemoteException;
-
-    public void setImmersive(IBinder token, boolean immersive) throws RemoteException;
-    public boolean isImmersive(IBinder token) throws RemoteException;
-    public boolean isTopActivityImmersive() throws RemoteException;
-    public boolean isTopOfTask(IBinder token) throws RemoteException;
-
-    public void crashApplication(int uid, int initialPid, String packageName,
-            String message) throws RemoteException;
-
-    public String getProviderMimeType(Uri uri, int userId) throws RemoteException;
-
-    public IBinder newUriPermissionOwner(String name) throws RemoteException;
-    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) throws RemoteException;
-    public void grantUriPermissionFromOwner(IBinder owner, int fromUid, String targetPkg,
-            Uri uri, int mode, int sourceUserId, int targetUserId) throws RemoteException;
-    public void revokeUriPermissionFromOwner(IBinder owner, Uri uri,
-            int mode, int userId) throws RemoteException;
-
-    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
-            int modeFlags, int userId) throws RemoteException;
-
-    // Cause the specified process to dump the specified heap.
-    public boolean dumpHeap(String process, int userId, boolean managed, String path,
-        ParcelFileDescriptor fd) throws RemoteException;
-
-    public int startActivities(IApplicationThread caller, String callingPackage,
-            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
-            Bundle options, int userId) throws RemoteException;
-
-    public int getFrontActivityScreenCompatMode() throws RemoteException;
-    public void setFrontActivityScreenCompatMode(int mode) throws RemoteException;
-    public int getPackageScreenCompatMode(String packageName) throws RemoteException;
-    public void setPackageScreenCompatMode(String packageName, int mode)
-            throws RemoteException;
-    public boolean getPackageAskScreenCompat(String packageName) throws RemoteException;
-    public void setPackageAskScreenCompat(String packageName, boolean ask)
-            throws RemoteException;
-
-    // Multi-user APIs
-    public boolean switchUser(int userid) throws RemoteException;
-    public boolean startUserInBackground(int userid) throws RemoteException;
-    public boolean unlockUser(int userid, byte[] token, byte[] secret, IProgressListener listener)
-            throws RemoteException;
-    public int stopUser(int userid, boolean force, IStopUserCallback callback) throws RemoteException;
-    public UserInfo getCurrentUser() throws RemoteException;
-    public boolean isUserRunning(int userid, int flags) throws RemoteException;
-    public int[] getRunningUserIds() throws RemoteException;
-
-    public boolean removeTask(int taskId) throws RemoteException;
-
-    public void registerProcessObserver(IProcessObserver observer) throws RemoteException;
-    public void unregisterProcessObserver(IProcessObserver observer) throws RemoteException;
-
-    public void registerUidObserver(IUidObserver observer, int which) throws RemoteException;
-    public void unregisterUidObserver(IUidObserver observer) throws RemoteException;
-
-    public boolean isIntentSenderTargetedToPackage(IIntentSender sender) throws RemoteException;
-
-    public boolean isIntentSenderAnActivity(IIntentSender sender) throws RemoteException;
-
-    public Intent getIntentForIntentSender(IIntentSender sender) throws RemoteException;
-
-    public String getTagForIntentSender(IIntentSender sender, String prefix) throws RemoteException;
-
-    public void updatePersistentConfiguration(Configuration values) throws RemoteException;
-
-    public long[] getProcessPss(int[] pids) throws RemoteException;
-
-    public void showBootMessage(CharSequence msg, boolean always) throws RemoteException;
-
-    /**
-     * Notify the system that the keyguard is going away.
-     *
-     * @param flags See {@link android.view.WindowManagerPolicy#KEYGUARD_GOING_AWAY_FLAG_TO_SHADE}
-     *              etc.
-     */
-    public void keyguardGoingAway(int flags) throws RemoteException;
-
-    public boolean shouldUpRecreateTask(IBinder token, String destAffinity)
-            throws RemoteException;
-
-    public boolean navigateUpTo(IBinder token, Intent target, int resultCode, Intent resultData)
-            throws RemoteException;
-
-    // These are not public because you need to be very careful in how you
-    // manage your activity to make sure it is always the uid you expect.
-    public int getLaunchedFromUid(IBinder activityToken) throws RemoteException;
-    public String getLaunchedFromPackage(IBinder activityToken) throws RemoteException;
-
-    public void registerUserSwitchObserver(IUserSwitchObserver observer,
-            String name) throws RemoteException;
-    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) throws RemoteException;
-
-    public void requestBugReport(int bugreportType) throws RemoteException;
-
-    public long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason)
-            throws RemoteException;
-
-    public Bundle getAssistContextExtras(int requestType) throws RemoteException;
-
-    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
-            Bundle receiverExtras,
-            IBinder activityToken, boolean focused, boolean newSessionId) throws RemoteException;
-
-    public void reportAssistContextExtras(IBinder token, Bundle extras,
-            AssistStructure structure, AssistContent content, Uri referrer) throws RemoteException;
-
-    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
-            Bundle args) throws RemoteException;
-
-    public boolean isAssistDataAllowedOnCurrentActivity() throws RemoteException;
-
-    public boolean showAssistFromActivity(IBinder token, Bundle args) throws RemoteException;
-
-    public void killUid(int appId, int userId, String reason) throws RemoteException;
-
-    public void hang(IBinder who, boolean allowRestart) throws RemoteException;
-
-    public void reportActivityFullyDrawn(IBinder token) throws RemoteException;
-
-    public void restart() throws RemoteException;
-
-    public void performIdleMaintenance() throws RemoteException;
-
-    public void sendIdleJobTrigger() throws RemoteException;
-
-    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
-            IActivityContainerCallback callback) throws RemoteException;
-
-    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException;
-
-    public int getActivityDisplayId(IBinder activityToken) throws RemoteException;
-
-    public void startSystemLockTaskMode(int taskId) throws RemoteException;
-
-    public void startLockTaskMode(int taskId) throws RemoteException;
-
-    public void startLockTaskMode(IBinder token) throws RemoteException;
-
-    public void stopLockTaskMode() throws RemoteException;
-
-    public void stopSystemLockTaskMode() throws RemoteException;
-
-    public boolean isInLockTaskMode() throws RemoteException;
-
-    public int getLockTaskModeState() throws RemoteException;
-
-    public void showLockTaskEscapeMessage(IBinder token) throws RemoteException;
-
-    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription values)
-            throws RemoteException;
-    public void setTaskResizeable(int taskId, int resizeableMode) throws RemoteException;
-    public void resizeTask(int taskId, Rect bounds, int resizeMode) throws RemoteException;
-
-    public Rect getTaskBounds(int taskId) throws RemoteException;
-    public Bitmap getTaskDescriptionIcon(String filename, int userId) throws RemoteException;
-
-    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
-            throws RemoteException;
-
-    public boolean requestVisibleBehind(IBinder token, boolean visible) throws RemoteException;
-    public boolean isBackgroundVisibleBehind(IBinder token) throws RemoteException;
-    public void backgroundResourcesReleased(IBinder token) throws RemoteException;
-
-    public void notifyLaunchTaskBehindComplete(IBinder token) throws RemoteException;
-    public void notifyEnterAnimationComplete(IBinder token) throws RemoteException;
-
-    public void notifyCleartextNetwork(int uid, byte[] firstPacket) throws RemoteException;
-
-    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
-            String reportPackage) throws RemoteException;
-    public void dumpHeapFinished(String path) throws RemoteException;
-
-    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake)
-            throws RemoteException;
-    public void updateLockTaskPackages(int userId, String[] packages) throws RemoteException;
-    public void updateDeviceOwner(String packageName) throws RemoteException;
-
-    public int getPackageProcessState(String packageName, String callingPackage)
-            throws RemoteException;
-
-    public boolean setProcessMemoryTrimLevel(String process, int uid, int level)
-            throws RemoteException;
-
-    public boolean isRootVoiceInteraction(IBinder token) throws RemoteException;
-
-    // Start Binder transaction tracking for all applications.
-    public boolean startBinderTracking() throws RemoteException;
-
-    // Stop Binder transaction tracking for all applications and dump trace data to the given file
-    // descriptor.
-    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException;
-
-    public int getActivityStackId(IBinder token) throws RemoteException;
-    public void exitFreeformMode(IBinder token) throws RemoteException;
-
-    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException;
-
-    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) throws RemoteException;
-
-    public int getAppStartMode(int uid, String packageName) throws RemoteException;
-
-    public boolean isInMultiWindowMode(IBinder token) throws RemoteException;
-
-    public boolean isInPictureInPictureMode(IBinder token) throws RemoteException;
-
-    public void enterPictureInPictureMode(IBinder token) throws RemoteException;
-
-    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName)
-            throws RemoteException;
-
-    public boolean isVrModePackageEnabled(ComponentName packageName) throws RemoteException;
-
-    public boolean isAppForeground(int uid) throws RemoteException;
-
-    public void startLocalVoiceInteraction(IBinder token, Bundle options) throws RemoteException;
-
-    public void stopLocalVoiceInteraction(IBinder token) throws RemoteException;
-
-    public boolean supportsLocalVoiceInteraction() throws RemoteException;
-
-    public void notifyPinnedStackAnimationEnded() throws RemoteException;
-
-    public void removeStack(int stackId) throws RemoteException;
-
-    public void notifyLockedProfile(@UserIdInt int userId) throws RemoteException;
-
-    public void startConfirmDeviceCredentialIntent(Intent intent) throws RemoteException;
-
-    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
-            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options)
-            throws RemoteException;
-
-    public void setVrThread(int tid) throws RemoteException;
-    public void setRenderThread(int tid) throws RemoteException;
-
-    /**
-     * Lets activity manager know whether the calling process is currently showing "top-level" UI
-     * that is not an activity, i.e. windows on the screen the user is currently interacting with.
-     *
-     * <p>This flag can only be set for persistent processes.
-     *
-     * @param hasTopUi Whether the calling process has "top-level" UI.
-     */
-    public void setHasTopUi(boolean hasTopUi) throws RemoteException;
-
-    /**
-     * Returns if the target of the PendingIntent can be fired directly, without triggering
-     * a work profile challenge. This can happen if the PendingIntent is to start direct-boot
-     * aware activities, and the target user is in RUNNING_LOCKED state, i.e. we should allow
-     * direct-boot aware activity to bypass work challenge when the user hasn't unlocked yet.
-     * @param intent the {@link  PendingIntent} to be tested.
-     * @return {@code true} if the intent should not trigger a work challenge, {@code false}
-     *     otherwise.
-     * @throws RemoteException
-     */
-    public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException;
-
-    /*
-     * Private non-Binder interfaces
-     */
-    /* package */ boolean testIsSystemReady();
-
-    /** Information you can retrieve about a particular application. */
-    public static class ContentProviderHolder implements Parcelable {
-        public final ProviderInfo info;
-        public IContentProvider provider;
-        public IBinder connection;
-        public boolean noReleaseNeeded;
-
-        public ContentProviderHolder(ProviderInfo _info) {
-            info = _info;
-        }
-
-        @Override
-        public int describeContents() {
-            return 0;
-        }
-
-        @Override
-        public void writeToParcel(Parcel dest, int flags) {
-            info.writeToParcel(dest, 0);
-            if (provider != null) {
-                dest.writeStrongBinder(provider.asBinder());
-            } else {
-                dest.writeStrongBinder(null);
-            }
-            dest.writeStrongBinder(connection);
-            dest.writeInt(noReleaseNeeded ? 1 : 0);
-        }
-
-        public static final Parcelable.Creator<ContentProviderHolder> CREATOR
-                = new Parcelable.Creator<ContentProviderHolder>() {
-            @Override
-            public ContentProviderHolder createFromParcel(Parcel source) {
-                return new ContentProviderHolder(source);
-            }
-
-            @Override
-            public ContentProviderHolder[] newArray(int size) {
-                return new ContentProviderHolder[size];
-            }
-        };
-
-        private ContentProviderHolder(Parcel source) {
-            info = ProviderInfo.CREATOR.createFromParcel(source);
-            provider = ContentProviderNative.asInterface(
-                    source.readStrongBinder());
-            connection = source.readStrongBinder();
-            noReleaseNeeded = source.readInt() != 0;
-        }
-    }
-
-    /** Information returned after waiting for an activity start. */
-    public static class WaitResult implements Parcelable {
-        public int result;
-        public boolean timeout;
-        public ComponentName who;
-        public long thisTime;
-        public long totalTime;
-
-        public WaitResult() {
-        }
-
-        @Override
-        public int describeContents() {
-            return 0;
-        }
-
-        @Override
-        public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(result);
-            dest.writeInt(timeout ? 1 : 0);
-            ComponentName.writeToParcel(who, dest);
-            dest.writeLong(thisTime);
-            dest.writeLong(totalTime);
-        }
-
-        public static final Parcelable.Creator<WaitResult> CREATOR
-                = new Parcelable.Creator<WaitResult>() {
-            @Override
-            public WaitResult createFromParcel(Parcel source) {
-                return new WaitResult(source);
-            }
-
-            @Override
-            public WaitResult[] newArray(int size) {
-                return new WaitResult[size];
-            }
-        };
-
-        private WaitResult(Parcel source) {
-            result = source.readInt();
-            timeout = source.readInt() != 0;
-            who = ComponentName.readFromParcel(source);
-            thisTime = source.readLong();
-            totalTime = source.readLong();
-        }
-    }
-
-    String descriptor = "android.app.IActivityManager";
-
-    // Please keep these transaction codes the same -- they are also
-    // sent by C++ code.
-    int HANDLE_APPLICATION_CRASH_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+1;
-    int START_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+2;
-    int UNHANDLED_BACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+3;
-    int OPEN_CONTENT_URI_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+4;
-
-    // Remaining non-native transaction codes.
-    int FINISH_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+10;
-    int REGISTER_RECEIVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+11;
-    int UNREGISTER_RECEIVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+12;
-    int BROADCAST_INTENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+13;
-    int UNBROADCAST_INTENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+14;
-    int FINISH_RECEIVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+15;
-    int ATTACH_APPLICATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+16;
-    int ACTIVITY_IDLE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+17;
-    int ACTIVITY_PAUSED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+18;
-    int ACTIVITY_STOPPED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+19;
-    int GET_CALLING_PACKAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+20;
-    int GET_CALLING_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+21;
-    int GET_TASKS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+22;
-    int MOVE_TASK_TO_FRONT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+23;
-
-    int MOVE_TASK_BACKWARDS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+25;
-    int GET_TASK_FOR_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+26;
-
-    int GET_CONTENT_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+28;
-    int PUBLISH_CONTENT_PROVIDERS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+29;
-    int REF_CONTENT_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+30;
-    int FINISH_SUB_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+31;
-    int GET_RUNNING_SERVICE_CONTROL_PANEL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+32;
-    int START_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+33;
-    int STOP_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+34;
-    int BIND_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+35;
-    int UNBIND_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+36;
-    int PUBLISH_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+37;
-    int ACTIVITY_RESUMED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+38;
-    int SET_DEBUG_APP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+41;
-    int SET_ALWAYS_FINISH_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+42;
-    int START_INSTRUMENTATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+43;
-    int FINISH_INSTRUMENTATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+44;
-    int GET_CONFIGURATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+45;
-    int UPDATE_CONFIGURATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+46;
-    int STOP_SERVICE_TOKEN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+47;
-    int GET_ACTIVITY_CLASS_FOR_TOKEN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+48;
-    int GET_PACKAGE_FOR_TOKEN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+49;
-    int SET_PROCESS_LIMIT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+50;
-    int GET_PROCESS_LIMIT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+51;
-    int CHECK_PERMISSION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+52;
-    int CHECK_URI_PERMISSION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+53;
-    int GRANT_URI_PERMISSION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+54;
-    int REVOKE_URI_PERMISSION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+55;
-    int SET_ACTIVITY_CONTROLLER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+56;
-    int SHOW_WAITING_FOR_DEBUGGER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+57;
-    int SIGNAL_PERSISTENT_PROCESSES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+58;
-    int GET_RECENT_TASKS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+59;
-    int SERVICE_DONE_EXECUTING_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+60;
-    int ACTIVITY_DESTROYED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+61;
-    int GET_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+62;
-    int CANCEL_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+63;
-    int GET_PACKAGE_FOR_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+64;
-    int ENTER_SAFE_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+65;
-    int START_NEXT_MATCHING_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+66;
-    int NOTE_WAKEUP_ALARM_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+67;
-    int REMOVE_CONTENT_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+68;
-    int SET_REQUESTED_ORIENTATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+69;
-    int GET_REQUESTED_ORIENTATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+70;
-    int UNBIND_FINISHED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+71;
-    int SET_PROCESS_FOREGROUND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+72;
-    int SET_SERVICE_FOREGROUND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+73;
-    int MOVE_ACTIVITY_TASK_TO_BACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+74;
-    int GET_MEMORY_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+75;
-    int GET_PROCESSES_IN_ERROR_STATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+76;
-    int CLEAR_APP_DATA_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+77;
-    int FORCE_STOP_PACKAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+78;
-    int KILL_PIDS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+79;
-    int GET_SERVICES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+80;
-    int GET_TASK_THUMBNAIL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+81;
-    int GET_RUNNING_APP_PROCESSES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+82;
-    int GET_DEVICE_CONFIGURATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+83;
-    int PEEK_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+84;
-    int PROFILE_CONTROL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+85;
-    int SHUTDOWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+86;
-    int STOP_APP_SWITCHES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+87;
-    int RESUME_APP_SWITCHES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+88;
-    int START_BACKUP_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+89;
-    int BACKUP_AGENT_CREATED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+90;
-    int UNBIND_BACKUP_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+91;
-    int GET_UID_FOR_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+92;
-    int HANDLE_INCOMING_USER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+93;
-    int ADD_PACKAGE_DEPENDENCY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+94;
-    int KILL_APPLICATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+95;
-    int CLOSE_SYSTEM_DIALOGS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+96;
-    int GET_PROCESS_MEMORY_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+97;
-    int KILL_APPLICATION_PROCESS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+98;
-    int START_ACTIVITY_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+99;
-    int OVERRIDE_PENDING_TRANSITION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+100;
-    int HANDLE_APPLICATION_WTF_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+101;
-    int KILL_BACKGROUND_PROCESSES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+102;
-    int IS_USER_A_MONKEY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+103;
-    int START_ACTIVITY_AND_WAIT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+104;
-    int WILL_ACTIVITY_BE_VISIBLE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+105;
-    int START_ACTIVITY_WITH_CONFIG_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+106;
-    int GET_RUNNING_EXTERNAL_APPLICATIONS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+107;
-    int FINISH_HEAVY_WEIGHT_APP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+108;
-    int HANDLE_APPLICATION_STRICT_MODE_VIOLATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+109;
-    int IS_IMMERSIVE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+110;
-    int SET_IMMERSIVE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+111;
-    int IS_TOP_ACTIVITY_IMMERSIVE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+112;
-    int CRASH_APPLICATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+113;
-    int GET_PROVIDER_MIME_TYPE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+114;
-    int NEW_URI_PERMISSION_OWNER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+115;
-    int GRANT_URI_PERMISSION_FROM_OWNER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+116;
-    int REVOKE_URI_PERMISSION_FROM_OWNER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+117;
-    int CHECK_GRANT_URI_PERMISSION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+118;
-    int DUMP_HEAP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+119;
-    int START_ACTIVITIES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+120;
-    int IS_USER_RUNNING_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+121;
-    int ACTIVITY_SLEPT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+122;
-    int GET_FRONT_ACTIVITY_SCREEN_COMPAT_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+123;
-    int SET_FRONT_ACTIVITY_SCREEN_COMPAT_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+124;
-    int GET_PACKAGE_SCREEN_COMPAT_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+125;
-    int SET_PACKAGE_SCREEN_COMPAT_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+126;
-    int GET_PACKAGE_ASK_SCREEN_COMPAT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+127;
-    int SET_PACKAGE_ASK_SCREEN_COMPAT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+128;
-    int SWITCH_USER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+129;
-    int SET_FOCUSED_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+130;
-    int REMOVE_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+131;
-    int REGISTER_PROCESS_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+132;
-    int UNREGISTER_PROCESS_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+133;
-    int IS_INTENT_SENDER_TARGETED_TO_PACKAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+134;
-    int UPDATE_PERSISTENT_CONFIGURATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+135;
-    int GET_PROCESS_PSS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+136;
-    int SHOW_BOOT_MESSAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+137;
-    int KILL_ALL_BACKGROUND_PROCESSES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+139;
-    int GET_CONTENT_PROVIDER_EXTERNAL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+140;
-    int REMOVE_CONTENT_PROVIDER_EXTERNAL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+141;
-    int GET_MY_MEMORY_STATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+142;
-    int KILL_PROCESSES_BELOW_FOREGROUND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+143;
-    int GET_CURRENT_USER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+144;
-    int SHOULD_UP_RECREATE_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+145;
-    int NAVIGATE_UP_TO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+146;
-    int SET_LOCK_SCREEN_SHOWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+147;
-    int FINISH_ACTIVITY_AFFINITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+148;
-    int GET_LAUNCHED_FROM_UID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+149;
-    int UNSTABLE_PROVIDER_DIED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+150;
-    int IS_INTENT_SENDER_AN_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+151;
-    int START_ACTIVITY_AS_USER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+152;
-    int STOP_USER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+153;
-    int REGISTER_USER_SWITCH_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+154;
-    int UNREGISTER_USER_SWITCH_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+155;
-    int GET_RUNNING_USER_IDS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+156;
-    int REQUEST_BUG_REPORT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+157;
-    int INPUT_DISPATCHING_TIMED_OUT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+158;
-    int CLEAR_PENDING_BACKUP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+159;
-    int GET_INTENT_FOR_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+160;
-    int GET_ASSIST_CONTEXT_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+161;
-    int REPORT_ASSIST_CONTEXT_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+162;
-    int GET_LAUNCHED_FROM_PACKAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+163;
-    int KILL_UID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+164;
-    int SET_USER_IS_MONKEY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+165;
-    int HANG_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+166;
-    int CREATE_VIRTUAL_ACTIVITY_CONTAINER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+167;
-    int MOVE_TASK_TO_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+168;
-    int RESIZE_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+169;
-    int GET_ALL_STACK_INFOS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+170;
-    int SET_FOCUSED_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+171;
-    int GET_STACK_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+172;
-    int CONVERT_FROM_TRANSLUCENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+173;
-    int CONVERT_TO_TRANSLUCENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+174;
-    int NOTIFY_ACTIVITY_DRAWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+175;
-    int REPORT_ACTIVITY_FULLY_DRAWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+176;
-    int RESTART_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+177;
-    int PERFORM_IDLE_MAINTENANCE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+178;
-    int TAKE_PERSISTABLE_URI_PERMISSION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+179;
-    int RELEASE_PERSISTABLE_URI_PERMISSION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+180;
-    int GET_PERSISTED_URI_PERMISSIONS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+181;
-    int APP_NOT_RESPONDING_VIA_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+182;
-    int GET_TASK_BOUNDS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+183;
-    int GET_ACTIVITY_DISPLAY_ID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+184;
-    int DELETE_ACTIVITY_CONTAINER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+185;
-    int SET_PROCESS_MEMORY_TRIM_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+186;
-
-    // Start of L transactions
-    int GET_TAG_FOR_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+210;
-    int START_USER_IN_BACKGROUND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+211;
-    int IS_IN_HOME_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+212;
-    int START_LOCK_TASK_BY_TASK_ID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+213;
-    int START_LOCK_TASK_BY_TOKEN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+214;
-    int STOP_LOCK_TASK_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+215;
-    int IS_IN_LOCK_TASK_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+216;
-    int SET_TASK_DESCRIPTION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+217;
-    int START_VOICE_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+218;
-    int GET_ACTIVITY_OPTIONS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+219;
-    int GET_APP_TASKS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+220;
-    int START_SYSTEM_LOCK_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+221;
-    int STOP_SYSTEM_LOCK_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+222;
-    int FINISH_VOICE_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+223;
-    int IS_TOP_OF_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+224;
-    int REQUEST_VISIBLE_BEHIND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+225;
-    int IS_BACKGROUND_VISIBLE_BEHIND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+226;
-    int BACKGROUND_RESOURCES_RELEASED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+227;
-    int NOTIFY_LAUNCH_TASK_BEHIND_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+228;
-    int START_ACTIVITY_FROM_RECENTS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 229;
-    int NOTIFY_ENTER_ANIMATION_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+230;
-    int START_ACTIVITY_AS_CALLER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+232;
-    int ADD_APP_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+233;
-    int GET_APP_TASK_THUMBNAIL_SIZE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+234;
-    int RELEASE_ACTIVITY_INSTANCE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+235;
-    int RELEASE_SOME_ACTIVITIES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+236;
-    int BOOT_ANIMATION_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+237;
-    int GET_TASK_DESCRIPTION_ICON_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+238;
-    int LAUNCH_ASSIST_INTENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+239;
-    int START_IN_PLACE_ANIMATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+240;
-    int CHECK_PERMISSION_WITH_TOKEN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+241;
-    int REGISTER_TASK_STACK_LISTENER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+242;
-
-    // Start of M transactions
-    int NOTIFY_CLEARTEXT_NETWORK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+280;
-    int CREATE_STACK_ON_DISPLAY = IBinder.FIRST_CALL_TRANSACTION+281;
-    int GET_FOCUSED_STACK_ID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+282;
-    int SET_TASK_RESIZEABLE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+283;
-    int REQUEST_ASSIST_CONTEXT_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+284;
-    int RESIZE_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+285;
-    int GET_LOCK_TASK_MODE_STATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+286;
-    int SET_DUMP_HEAP_DEBUG_LIMIT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+287;
-    int DUMP_HEAP_FINISHED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+288;
-    int SET_VOICE_KEEP_AWAKE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+289;
-    int UPDATE_LOCK_TASK_PACKAGES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+290;
-    int NOTE_ALARM_START_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+291;
-    int NOTE_ALARM_FINISH_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+292;
-    int GET_PACKAGE_PROCESS_STATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+293;
-    int SHOW_LOCK_TASK_ESCAPE_MESSAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+294;
-    int UPDATE_DEVICE_OWNER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+295;
-    int KEYGUARD_GOING_AWAY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+296;
-    int REGISTER_UID_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+297;
-    int UNREGISTER_UID_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+298;
-    int IS_SCREEN_CAPTURE_ALLOWED_ON_CURRENT_ACTIVITY_TRANSACTION
-            = IBinder.FIRST_CALL_TRANSACTION+299;
-    int SHOW_ASSIST_FROM_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+300;
-    int IS_ROOT_VOICE_INTERACTION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+301;
-
-    // Start of N transactions
-    int START_BINDER_TRACKING_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 340;
-    int STOP_BINDER_TRACKING_AND_DUMP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 341;
-    int POSITION_TASK_IN_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 342;
-    int GET_ACTIVITY_STACK_ID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 343;
-    int EXIT_FREEFORM_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 344;
-    int REPORT_SIZE_CONFIGURATIONS = IBinder.FIRST_CALL_TRANSACTION + 345;
-    int MOVE_TASK_TO_DOCKED_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 346;
-    int SUPPRESS_RESIZE_CONFIG_CHANGES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 347;
-    int MOVE_TASKS_TO_FULLSCREEN_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 348;
-    int MOVE_TOP_ACTIVITY_TO_PINNED_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 349;
-    int GET_APP_START_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 350;
-    int UNLOCK_USER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 351;
-    int IN_MULTI_WINDOW_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 352;
-    int IN_PICTURE_IN_PICTURE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 353;
-    int KILL_PACKAGE_DEPENDENTS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 354;
-    int ENTER_PICTURE_IN_PICTURE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 355;
-    int ACTIVITY_RELAUNCHED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 356;
-    int GET_URI_PERMISSION_OWNER_FOR_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 357;
-    int RESIZE_DOCKED_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 358;
-    int SET_VR_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 359;
-    int GET_GRANTED_URI_PERMISSIONS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 360;
-    int CLEAR_GRANTED_URI_PERMISSIONS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 361;
-    int IS_APP_FOREGROUND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 362;
-    int START_LOCAL_VOICE_INTERACTION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 363;
-    int STOP_LOCAL_VOICE_INTERACTION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 364;
-    int SUPPORTS_LOCAL_VOICE_INTERACTION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 365;
-    int NOTIFY_PINNED_STACK_ANIMATION_ENDED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 366;
-    int REMOVE_STACK = IBinder.FIRST_CALL_TRANSACTION + 367;
-    int SET_LENIENT_BACKGROUND_CHECK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+368;
-    int GET_MEMORY_TRIM_LEVEL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+369;
-    int RESIZE_PINNED_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 370;
-    int IS_VR_PACKAGE_ENABLED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 371;
-    int SWAP_DOCKED_AND_FULLSCREEN_STACK = IBinder.FIRST_CALL_TRANSACTION + 372;
-    int NOTIFY_LOCKED_PROFILE = IBinder.FIRST_CALL_TRANSACTION + 373;
-    int START_CONFIRM_DEVICE_CREDENTIAL_INTENT = IBinder.FIRST_CALL_TRANSACTION + 374;
-    int SEND_IDLE_JOB_TRIGGER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 375;
-    int SEND_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 376;
-
-    // Start of N MR1 transactions
-    int SET_VR_THREAD_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 377;
-    int SET_RENDER_THREAD_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 378;
-    int SET_HAS_TOP_UI = IBinder.FIRST_CALL_TRANSACTION + 379;
-    int CAN_BYPASS_WORK_CHALLENGE = IBinder.FIRST_CALL_TRANSACTION + 380;
-
-    // Start of O transactions
-    int REQUEST_ACTIVITY_RELAUNCH = IBinder.FIRST_CALL_TRANSACTION+400;
-    int UPDATE_DISPLAY_OVERRIDE_CONFIGURATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 401;
-    int UNREGISTER_TASK_STACK_LISTENER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+402;
-    int MOVE_STACK_TO_DISPLAY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 403;
-}
diff --git a/core/java/android/app/WaitResult.aidl b/core/java/android/app/WaitResult.aidl
new file mode 100644
index 0000000..22a6558
--- /dev/null
+++ b/core/java/android/app/WaitResult.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+/** @hide */
+parcelable WaitResult;
\ No newline at end of file
diff --git a/core/java/android/app/WaitResult.java b/core/java/android/app/WaitResult.java
new file mode 100644
index 0000000..af196cf
--- /dev/null
+++ b/core/java/android/app/WaitResult.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import android.content.ComponentName;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Information returned after waiting for an activity start.
+ *
+ * @hide
+ */
+public class WaitResult implements Parcelable {
+    public int result;
+    public boolean timeout;
+    public ComponentName who;
+    public long thisTime;
+    public long totalTime;
+
+    public WaitResult() {
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(result);
+        dest.writeInt(timeout ? 1 : 0);
+        ComponentName.writeToParcel(who, dest);
+        dest.writeLong(thisTime);
+        dest.writeLong(totalTime);
+    }
+
+    public static final Parcelable.Creator<WaitResult> CREATOR
+            = new Parcelable.Creator<WaitResult>() {
+        @Override
+        public WaitResult createFromParcel(Parcel source) {
+            return new WaitResult(source);
+        }
+
+        @Override
+        public WaitResult[] newArray(int size) {
+            return new WaitResult[size];
+        }
+    };
+
+    private WaitResult(Parcel source) {
+        result = source.readInt();
+        timeout = source.readInt() != 0;
+        who = ComponentName.readFromParcel(source);
+        thisTime = source.readLong();
+        totalTime = source.readLong();
+    }
+}
\ No newline at end of file
diff --git a/core/java/android/content/pm/ConfigurationInfo.aidl b/core/java/android/content/pm/ConfigurationInfo.aidl
new file mode 100644
index 0000000..0fa1003a
--- /dev/null
+++ b/core/java/android/content/pm/ConfigurationInfo.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+parcelable ConfigurationInfo;
\ No newline at end of file
diff --git a/core/java/android/os/StrictMode.aidl b/core/java/android/os/StrictMode.aidl
new file mode 100644
index 0000000..d045db4
--- /dev/null
+++ b/core/java/android/os/StrictMode.aidl
@@ -0,0 +1,20 @@
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+/** @hide */
+parcelable StrictMode.ViolationInfo;
\ No newline at end of file
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index ff69cf6..e9a3936 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -16,6 +16,7 @@
 package android.os;
 
 import android.animation.ValueAnimator;
+import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
 import android.app.ActivityThread;
 import android.app.ApplicationErrorReport;
@@ -1554,7 +1555,7 @@
                     // We restore the current policy below, in the finally block.
                     setThreadPolicyMask(0);
 
-                    ActivityManagerNative.getDefault().handleApplicationStrictModeViolation(
+                    ActivityManager.getService().handleApplicationStrictModeViolation(
                         RuntimeInit.getApplicationObject(),
                         violationMaskSubset,
                         info);
@@ -2373,7 +2374,7 @@
      *
      * @hide
      */
-    public static class ViolationInfo {
+    public static class ViolationInfo implements Parcelable {
         public String message;
 
         /**
@@ -2528,6 +2529,7 @@
         /**
          * Save a ViolationInfo instance to a parcel.
          */
+        @Override
         public void writeToParcel(Parcel dest, int flags) {
             dest.writeString(message);
             crashInfo.writeToParcel(dest, flags);
@@ -2584,6 +2586,23 @@
             }
         }
 
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        public static final Parcelable.Creator<ViolationInfo> CREATOR =
+                new Parcelable.Creator<ViolationInfo>() {
+                    @Override
+                    public ViolationInfo createFromParcel(Parcel in) {
+                        return new ViolationInfo(in);
+                    }
+
+                    @Override
+                    public ViolationInfo[] newArray(int size) {
+                        return new ViolationInfo[size];
+                    }
+                };
     }
 
     // Dummy throwable, for now, since we don't know when or where the
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index c851e4e..e57a224 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -114,7 +114,7 @@
 
                 // Bring up crash dialog, wait for it to be dismissed
                 ActivityManagerNative.getDefault().handleApplicationCrash(
-                        mApplicationObject, new ApplicationErrorReport.CrashInfo(e));
+                        mApplicationObject, new ApplicationErrorReport.ParcelableCrashInfo(e));
             } catch (Throwable t2) {
                 if (t2 instanceof DeadObjectException) {
                     // System process is dead; ignore
@@ -380,7 +380,8 @@
     public static void wtf(String tag, Throwable t, boolean system) {
         try {
             if (ActivityManagerNative.getDefault().handleApplicationWtf(
-                    mApplicationObject, tag, system, new ApplicationErrorReport.CrashInfo(t))) {
+                    mApplicationObject, tag, system,
+                    new ApplicationErrorReport.ParcelableCrashInfo(t))) {
                 // The Activity Manager has already written us off -- now exit.
                 Process.killProcess(Process.myPid());
                 System.exit(10);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index 8137dc6..11a4f64 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -659,11 +659,9 @@
      * Sends a message to close other system windows.
      */
     public void sendCloseSystemWindows(String reason) {
-        if (ActivityManagerNative.isSystemReady()) {
-            try {
-                mIam.closeSystemDialogs(reason);
-            } catch (RemoteException e) {
-            }
+        try {
+            mIam.closeSystemDialogs(reason);
+        } catch (RemoteException e) {
         }
     }
 
@@ -1018,7 +1016,8 @@
         if (mIam == null) return;
 
         try {
-            mIam.startInPlaceAnimationOnFrontMostApplication(opts);
+            mIam.startInPlaceAnimationOnFrontMostApplication(
+                    opts == null ? null : opts.toBundle());
         } catch (Exception e) {
             e.printStackTrace();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 70e21d6..23acb1b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -1320,11 +1320,9 @@
     }
 
     protected void sendCloseSystemWindows(String reason) {
-        if (ActivityManagerNative.isSystemReady()) {
-            try {
-                ActivityManagerNative.getDefault().closeSystemDialogs(reason);
-            } catch (RemoteException e) {
-            }
+        try {
+            ActivityManagerNative.getDefault().closeSystemDialogs(reason);
+        } catch (RemoteException e) {
         }
     }
 
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index d2cfb6d..b88a45e 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -16,6 +16,7 @@
 
 package com.android.server;
 
+import android.app.ActivityManagerInternal;
 import android.database.ContentObserver;
 import android.os.BatteryStats;
 
@@ -148,6 +149,8 @@
 
     private boolean mSentLowBatteryBroadcast = false;
 
+    private ActivityManagerInternal mActivityManagerInternal;
+
     public BatteryService(Context context) {
         super(context);
 
@@ -155,6 +158,7 @@
         mHandler = new Handler(true /*async*/);
         mLed = new Led(context, getLocalService(LightsManager.class));
         mBatteryStats = BatteryStatsService.getService();
+        mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
 
         mCriticalBatteryLevel = mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_criticalBatteryWarningLevel);
@@ -279,7 +283,7 @@
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
-                    if (ActivityManagerNative.isSystemReady()) {
+                    if (mActivityManagerInternal.isSystemReady()) {
                         Intent intent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);
                         intent.putExtra(Intent.EXTRA_KEY_CONFIRM, false);
                         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
@@ -298,7 +302,7 @@
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
-                    if (ActivityManagerNative.isSystemReady()) {
+                    if (mActivityManagerInternal.isSystemReady()) {
                         Intent intent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);
                         intent.putExtra(Intent.EXTRA_KEY_CONFIRM, false);
                         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index 2c4cfb9..2698f95 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -48,6 +48,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
+import android.app.ActivityManagerInternal;
 import android.app.ActivityManagerNative;
 import android.app.AlertDialog;
 import android.app.AppGlobals;
@@ -2055,7 +2056,7 @@
             // setSelectedInputMethodAndSubtypeLocked().
             mCurMethodId = id;
 
-            if (ActivityManagerNative.isSystemReady()) {
+            if (LocalServices.getService(ActivityManagerInternal.class).isSystemReady()) {
                 Intent intent = new Intent(Intent.ACTION_INPUT_METHOD_CHANGED);
                 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
                 intent.putExtra("input_method_id", id);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 5aee770..dd417d9 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -16,8 +16,11 @@
 
 package com.android.server.am;
 
-import android.app.ApplicationThreadConstants;
 import android.annotation.Nullable;
+import android.app.ApplicationThreadConstants;
+import android.app.ContentProviderHolder;
+import android.app.IActivityManager;
+import android.app.WaitResult;
 import android.os.IDeviceIdentifiersPolicyService;
 import android.util.Size;
 import android.util.TypedValue;
@@ -81,7 +84,6 @@
 import android.app.ActivityManager.TaskThumbnailInfo;
 import android.app.ActivityManagerInternal;
 import android.app.ActivityManagerInternal.SleepToken;
-import android.app.ActivityManagerNative;
 import android.app.ActivityOptions;
 import android.app.ActivityThread;
 import android.app.AlertDialog;
@@ -381,7 +383,7 @@
 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
 import static org.xmlpull.v1.XmlPullParser.START_TAG;
 
-public class ActivityManagerService extends ActivityManagerNative
+public class ActivityManagerService extends IActivityManager.Stub
         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
 
     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
@@ -8867,12 +8869,12 @@
     // =========================================================
 
     @Override
-    public List<IAppTask> getAppTasks(String callingPackage) {
+    public List<IBinder> getAppTasks(String callingPackage) {
         int callingUid = Binder.getCallingUid();
         long ident = Binder.clearCallingIdentity();
 
         synchronized(this) {
-            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
+            ArrayList<IBinder> list = new ArrayList<IBinder>();
             try {
                 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
 
@@ -8893,7 +8895,7 @@
                     ActivityManager.RecentTaskInfo taskInfo =
                             createRecentTaskInfoFromTaskRecord(tr);
                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
-                    list.add(taskImpl);
+                    list.add(taskImpl.asBinder());
                 }
             } finally {
                 Binder.restoreCallingIdentity(ident);
@@ -9345,16 +9347,17 @@
     }
 
     @Override
-    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
+    public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
             throws RemoteException {
-        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
-                opts.getCustomInPlaceResId() == 0) {
+        final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
+        if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
+                activityOptions.getCustomInPlaceResId() == 0) {
             throw new IllegalArgumentException("Expected in-place ActivityOption " +
                     "with valid animation");
         }
         mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
-        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
-                opts.getCustomInPlaceResId());
+        mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
+                activityOptions.getCustomInPlaceResId());
         mWindowManager.executeAppTransition();
     }
 
@@ -10058,7 +10061,7 @@
     }
 
     @Override
-    public void startLockTaskMode(int taskId) {
+    public void startLockTaskModeById(int taskId) {
         synchronized (this) {
             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
             if (task != null) {
@@ -10068,7 +10071,7 @@
     }
 
     @Override
-    public void startLockTaskMode(IBinder token) {
+    public void startLockTaskModeByToken(IBinder token) {
         synchronized (this) {
             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
             if (r == null) {
@@ -10088,7 +10091,7 @@
         long ident = Binder.clearCallingIdentity();
         try {
             synchronized (this) {
-                startLockTaskMode(taskId);
+                startLockTaskModeById(taskId);
             }
         } finally {
             Binder.restoreCallingIdentity(ident);
@@ -11408,9 +11411,10 @@
         }
     }
 
-    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
+    public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
         enforceNotIsolatedCaller("openContentUri");
         final int userId = UserHandle.getCallingUserId();
+        final Uri uri = Uri.parse(uriString);
         String name = uri.getAuthority();
         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
         ParcelFileDescriptor pfd = null;
@@ -12279,7 +12283,7 @@
     }
 
     @Override
-    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
+    public boolean convertToTranslucent(IBinder token, Bundle options) {
         final long origId = Binder.clearCallingIdentity();
         try {
             synchronized (this) {
@@ -12290,7 +12294,7 @@
                 int index = r.task.mActivities.lastIndexOf(r);
                 if (index > 0) {
                     ActivityRecord under = r.task.mActivities.get(index - 1);
-                    under.returningOptions = options;
+                    under.returningOptions = ActivityOptions.fromBundle(options);
                 }
                 final boolean translucentChanged = r.changeWindowTranslucency(false);
                 if (translucentChanged) {
@@ -12338,7 +12342,7 @@
     }
 
     @Override
-    public ActivityOptions getActivityOptions(IBinder token) {
+    public Bundle getActivityOptions(IBinder token) {
         final long origId = Binder.clearCallingIdentity();
         try {
             synchronized (this) {
@@ -12346,7 +12350,7 @@
                 if (r != null) {
                     final ActivityOptions activityOptions = r.pendingOptions;
                     r.pendingOptions = null;
-                    return activityOptions;
+                    return activityOptions == null ? null : activityOptions.toBundle();
                 }
                 return null;
             }
@@ -13002,11 +13006,6 @@
         }
     }
 
-    public boolean testIsSystemReady() {
-        // no need to synchronize(this) just to read & return the value
-        return mSystemReady;
-    }
-
     public void systemReady(final Runnable goingCallback) {
         synchronized(this) {
             if (mSystemReady) {
@@ -13200,7 +13199,8 @@
      * @param app object of the crashing app, null for the system server
      * @param crashInfo describing the exception
      */
-    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
+    public void handleApplicationCrash(IBinder app,
+            ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
         ProcessRecord r = findAppProcess(app, "Crash");
         final String processName = app == null ? "system_server"
                 : (r == null ? "unknown" : r.processName);
@@ -13412,7 +13412,7 @@
      * @return true if the process should exit immediately (WTF is fatal)
      */
     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
-            final ApplicationErrorReport.CrashInfo crashInfo) {
+            final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
         final int callingUid = Binder.getCallingUid();
         final int callingPid = Binder.getCallingPid();
 
@@ -22069,6 +22069,12 @@
                 callback.run();
             }
         }
+
+        @Override
+        public boolean isSystemReady() {
+            // no need to synchronize(this) just to read & return the value
+            return mSystemReady;
+        }
     }
 
     private final class SleepTokenImpl extends SleepToken {
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 3efd300..ecc1dba 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -27,6 +27,7 @@
 import android.app.Instrumentation;
 import android.app.ProfilerInfo;
 import android.app.UiAutomationConnection;
+import android.app.WaitResult;
 import android.app.usage.ConfigurationStats;
 import android.app.usage.IUsageStatsManager;
 import android.app.usage.UsageStatsManager;
@@ -344,7 +345,7 @@
             pw.flush();
             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 
-            IActivityManager.WaitResult result = null;
+            WaitResult result = null;
             int res;
             final long startTime = SystemClock.uptimeMillis();
             ActivityOptions options = null;
@@ -433,7 +434,7 @@
             out.flush();
             if (mWaitOption && launched) {
                 if (result == null) {
-                    result = new IActivityManager.WaitResult();
+                    result = new WaitResult();
                     result.who = intent.getComponent();
                 }
                 pw.println("Status: " + (result.timeout ? "timeout" : "ok"));
@@ -1982,7 +1983,7 @@
             mInterface.stopLockTaskMode();
         } else {
             int taskId = Integer.parseInt(taskIdStr);
-            mInterface.startLockTaskMode(taskId);
+            mInterface.startLockTaskModeById(taskId);
         }
         pw.println("Activity manager is " + (mInterface.isInLockTaskMode() ? "" : "not ") +
                 "in lockTaskMode");
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 6167671..8bb0e1a 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -100,11 +100,10 @@
 import android.app.AppGlobals;
 import android.app.AppOpsManager;
 import android.app.IActivityContainerCallback;
-import android.app.IActivityManager;
-import android.app.IActivityManager.WaitResult;
 import android.app.ProfilerInfo;
 import android.app.ResultInfo;
 import android.app.StatusBarManager;
+import android.app.WaitResult;
 import android.app.admin.IDevicePolicyManager;
 import android.content.ComponentName;
 import android.content.Context;
@@ -317,10 +316,10 @@
     final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<>();
 
     /** List of processes waiting to find out about the next visible activity. */
-    final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible = new ArrayList<>();
+    final ArrayList<WaitResult> mWaitingActivityVisible = new ArrayList<>();
 
     /** List of processes waiting to find out about the next launched activity. */
-    final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched = new ArrayList<>();
+    final ArrayList<WaitResult> mWaitingActivityLaunched = new ArrayList<>();
 
     /** List of activities that are ready to be stopped, but waiting for the next activity to
      * settle down before doing so. */
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index db73048..e4ec169 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -81,11 +81,11 @@
 import android.app.ActivityOptions;
 import android.app.AppGlobals;
 import android.app.IActivityContainer;
-import android.app.IActivityManager;
 import android.app.IApplicationThread;
 import android.app.KeyguardManager;
 import android.app.PendingIntent;
 import android.app.ProfilerInfo;
+import android.app.WaitResult;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.IIntentSender;
@@ -707,7 +707,7 @@
             String callingPackage, Intent intent, String resolvedType,
             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
             IBinder resultTo, String resultWho, int requestCode, int startFlags,
-            ProfilerInfo profilerInfo, IActivityManager.WaitResult outResult,
+            ProfilerInfo profilerInfo, WaitResult outResult,
             Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId,
             IActivityContainer iContainer, TaskRecord inTask) {
         // Refuse possible leaked file descriptors
diff --git a/services/core/java/com/android/server/am/ContentProviderRecord.java b/services/core/java/com/android/server/am/ContentProviderRecord.java
index dceadf4..7b9b6595 100644
--- a/services/core/java/com/android/server/am/ContentProviderRecord.java
+++ b/services/core/java/com/android/server/am/ContentProviderRecord.java
@@ -16,7 +16,7 @@
 
 package com.android.server.am;
 
-import android.app.IActivityManager.ContentProviderHolder;
+import android.app.ContentProviderHolder;
 import android.content.ComponentName;
 import android.content.IContentProvider;
 import android.content.pm.ApplicationInfo;
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 87f1cf8..f037f2f 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -403,6 +403,7 @@
 
     /** Interface for UserManagerService. */
     private final UserManagerInternal mUserManagerInternal;
+    private final ActivityManagerInternal mActivityManagerInternal;
 
     private final UserRestrictionsListener mUserRestrictionsListener =
             new AudioServiceUserRestrictionsListener();
@@ -612,6 +613,7 @@
         mIsSingleVolume = AudioSystem.isSingleVolume(context);
 
         mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
+        mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
 
         PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
         mAudioEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleAudioEvent");
@@ -3691,7 +3693,7 @@
 
     private void broadcastVibrateSetting(int vibrateType) {
         // Send broadcast
-        if (ActivityManagerNative.isSystemReady()) {
+        if (mActivityManagerInternal.isSystemReady()) {
             Intent broadcast = new Intent(AudioManager.VIBRATE_SETTING_CHANGED_ACTION);
             broadcast.putExtra(AudioManager.EXTRA_VIBRATE_TYPE, vibrateType);
             broadcast.putExtra(AudioManager.EXTRA_VIBRATE_SETTING, getVibrateSetting(vibrateType));
@@ -5425,8 +5427,7 @@
         // when the user switches back. For managed profiles, we should kill all recording apps
         ComponentName homeActivityName = null;
         if (!oldUser.isManagedProfile()) {
-            homeActivityName = LocalServices.getService(ActivityManagerInternal.class)
-                    .getHomeActivityForUser(oldUser.id);
+            homeActivityName = mActivityManagerInternal.getHomeActivityForUser(oldUser.id);
         }
         final String[] permissions = { Manifest.permission.RECORD_AUDIO };
         List<PackageInfo> packages;
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index b2a5966..b7067d2 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -6209,7 +6209,7 @@
     }
 
     void dispatchMediaKeyWithWakeLockToAudioService(KeyEvent event) {
-        if (ActivityManagerNative.isSystemReady()) {
+        if (mActivityManagerInternal.isSystemReady()) {
             MediaSessionLegacyHelper.getHelper(mContext).sendMediaButtonEvent(event, true);
         }
     }
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index 4e9f5a2..00700b8 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -648,7 +648,7 @@
             Slog.d(TAG, "Sending wake up broadcast.");
         }
 
-        if (ActivityManagerNative.isSystemReady()) {
+        if (mActivityManagerInternal.isSystemReady()) {
             mContext.sendOrderedBroadcastAsUser(mScreenOnIntent, UserHandle.ALL, null,
                     mWakeUpBroadcastDone, mHandler, 0, null, null);
         } else {
@@ -671,7 +671,7 @@
             Slog.d(TAG, "Sending go to sleep broadcast.");
         }
 
-        if (ActivityManagerNative.isSystemReady()) {
+        if (mActivityManagerInternal.isSystemReady()) {
             mContext.sendOrderedBroadcastAsUser(mScreenOffIntent, UserHandle.ALL, null,
                     mGoToSleepBroadcastDone, mHandler, 0, null, null);
         } else {
diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java
index badee82..a920d54 100644
--- a/services/core/java/com/android/server/power/ShutdownThread.java
+++ b/services/core/java/com/android/server/power/ShutdownThread.java
@@ -17,7 +17,6 @@
 
 package com.android.server.power;
 
-import android.app.ActivityManagerNative;
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.app.IActivityManager;
@@ -415,7 +414,7 @@
         Log.i(TAG, "Shutting down activity manager...");
 
         final IActivityManager am =
-            ActivityManagerNative.asInterface(ServiceManager.checkService("activity"));
+                IActivityManager.Stub.asInterface(ServiceManager.checkService("activity"));
         if (am != null) {
             try {
                 am.shutdown(MAX_BROADCAST_TIME);
diff --git a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
index 16a0def..f5f7ea3 100644
--- a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
+++ b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
@@ -32,7 +32,6 @@
 import android.os.UserHandle;
 import android.app.UiAutomation;
 import android.app.IActivityManager;
-import android.app.IActivityManager.WaitResult;
 import android.support.test.rule.logging.AtraceLogger;
 import android.test.InstrumentationTestCase;
 import android.test.InstrumentationTestRunner;
