Bind to DefaultContainerService early for AIA

This change attempts to bind to the default system service on
PackageInstallSession creation instead of waiting until the session is
committed. This potentially saves up to 200ms off of instant app launch
latency.

Change-Id: I6a27c6db3094ddbe2f633f118e4b30182f07647a
Fixes: 72661783
Test: manual - install succeeds and service connection happens on session open
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index ee32618..f7a0215 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -122,8 +122,9 @@
     private static final boolean LOGD = true;
     private static final String REMOVE_SPLIT_MARKER_EXTENSION = ".removed";
 
-    private static final int MSG_COMMIT = 0;
-    private static final int MSG_ON_PACKAGE_INSTALLED = 1;
+    private static final int MSG_EARLY_BIND = 0;
+    private static final int MSG_COMMIT = 1;
+    private static final int MSG_ON_PACKAGE_INSTALLED = 2;
 
     /** XML constants used for persisting a session */
     static final String TAG_SESSION = "session";
@@ -280,6 +281,9 @@
         @Override
         public boolean handleMessage(Message msg) {
             switch (msg.what) {
+                case MSG_EARLY_BIND:
+                    earlyBindToDefContainer();
+                    break;
                 case MSG_COMMIT:
                     synchronized (mLock) {
                         try {
@@ -315,6 +319,10 @@
         }
     };
 
+    private void earlyBindToDefContainer() {
+        mPm.earlyBindToDefContainer();
+    }
+
     /**
      * @return {@code true} iff the installing is app an device owner or affiliated profile owner.
      */
@@ -410,6 +418,10 @@
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
+        // attempt to bind to the DefContainer as early as possible
+        if ((params.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
+            mHandler.sendMessage(mHandler.obtainMessage(MSG_EARLY_BIND));
+        }
     }
 
     public SessionInfo generateInfo() {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index f4360e4..bdc7f0a 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -1316,6 +1316,7 @@
     static final int INTENT_FILTER_VERIFIED = 18;
     static final int WRITE_PACKAGE_LIST = 19;
     static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20;
+    static final int DEF_CONTAINER_BIND = 21;
 
     static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
 
@@ -1407,8 +1408,7 @@
             new ArrayList<HandlerParams>();
 
         private boolean connectToService() {
-            if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
-                    " DefaultContainerService");
+            if (DEBUG_INSTALL) Log.i(TAG, "Trying to bind to DefaultContainerService");
             Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
             if (mContext.bindServiceAsUser(service, mDefContainerConn,
@@ -1443,6 +1443,17 @@
 
         void doHandleMessage(Message msg) {
             switch (msg.what) {
+                case DEF_CONTAINER_BIND:
+                    if (!mBound) {
+                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "earlyBindingMCS",
+                                System.identityHashCode(mHandler));
+                        if (!connectToService()) {
+                            Slog.e(TAG, "Failed to bind to media container service");
+                        }
+                        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "earlyBindingMCS",
+                                System.identityHashCode(mHandler));
+                    }
+                    break;
                 case INIT_COPY: {
                     HandlerParams params = (HandlerParams) msg.obj;
                     int idx = mPendingInstalls.size();
@@ -13606,6 +13617,14 @@
         return installReason;
     }
 
+    /**
+     * Attempts to bind to the default container service explicitly instead of doing so lazily on
+     * install commit.
+     */
+    void earlyBindToDefContainer() {
+        mHandler.sendMessage(mHandler.obtainMessage(DEF_CONTAINER_BIND));
+    }
+
     void installStage(String packageName, File stagedDir,
             IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
             String installerPackageName, int installerUid, UserHandle user,