Framework part of issue #2391576: Add method to start the Jit and call it
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 10fef0d..1af6d6e 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -61,6 +61,7 @@
 import android.view.View;
 import android.view.ViewDebug;
 import android.view.ViewManager;
+import android.view.ViewRoot;
 import android.view.Window;
 import android.view.WindowManager;
 import android.view.WindowManagerImpl;
@@ -1813,6 +1814,7 @@
         public static final int DESTROY_BACKUP_AGENT    = 129;
         public static final int SUICIDE                 = 130;
         public static final int REMOVE_PROVIDER         = 131;
+        public static final int ENABLE_JIT              = 132;
         String codeToString(int code) {
             if (localLOGV) {
                 switch (code) {
@@ -1848,6 +1850,7 @@
                     case DESTROY_BACKUP_AGENT: return "DESTROY_BACKUP_AGENT";
                     case SUICIDE: return "SUICIDE";
                     case REMOVE_PROVIDER: return "REMOVE_PROVIDER";
+                    case ENABLE_JIT: return "ENABLE_JIT";
                 }
             }
             return "(unknown)";
@@ -1965,6 +1968,9 @@
                 case REMOVE_PROVIDER:
                     completeRemoveProvider((IContentProvider)msg.obj);
                     break;
+                case ENABLE_JIT:
+                    ensureJitEnabled();
+                    break;
             }
         }
 
@@ -2000,6 +2006,7 @@
                     prev.nextIdle = null;
                 } while (a != null);
             }
+            ensureJitEnabled();
             return false;
         }
     }
@@ -2064,6 +2071,7 @@
     String mInstrumentationAppPackage = null;
     String mInstrumentedAppDir = null;
     boolean mSystemThread = false;
+    boolean mJitEnabled = false;
 
     /**
      * Activities that are enqueued to be relaunched.  This list is accessed
@@ -2269,6 +2277,13 @@
         }
     }
 
+    void ensureJitEnabled() {
+        if (!mJitEnabled) {
+            mJitEnabled = true;
+            dalvik.system.VMRuntime.getRuntime().startJitCompilation();
+        }
+    }
+    
     void scheduleGcIdler() {
         if (!mGcIdlerScheduled) {
             mGcIdlerScheduled = true;
@@ -2808,6 +2823,7 @@
                         ActivityManagerNative.getDefault().serviceDoneExecuting(
                                 data.token, 0, 0, 0);
                     }
+                    ensureJitEnabled();
                 } catch (RemoteException ex) {
                 }
             } catch (Exception e) {
@@ -2876,6 +2892,7 @@
                 } catch (RemoteException e) {
                     // nothing to do.
                 }
+                ensureJitEnabled();
             } catch (Exception e) {
                 if (!mInstrumentation.onException(s, e)) {
                     throw new RuntimeException(
@@ -3864,10 +3881,6 @@
         mBoundApplication = data;
         mConfiguration = new Configuration(data.config);
 
-        // We now rely on this being set by zygote.
-        //Process.setGid(data.appInfo.gid);
-        //Process.setUid(data.appInfo.uid);
-
         // send up app name; do this *before* waiting for debugger
         Process.setArgV0(data.processName);
         android.ddm.DdmHandleAppName.setAppName(data.processName);
@@ -3998,6 +4011,9 @@
         List<ProviderInfo> providers = data.providers;
         if (providers != null) {
             installContentProviders(app, providers);
+            // For process that contain content providers, we want to
+            // ensure that the JIT is enabled "at some point".
+            mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
         }
 
         try {
@@ -4303,6 +4319,11 @@
         sThreadLocal.set(this);
         mSystemThread = system;
         if (!system) {
+            ViewRoot.addFirstDrawHandler(new Runnable() {
+                public void run() {
+                    ensureJitEnabled();
+                }
+            });
             android.ddm.DdmHandleAppName.setAppName("<pre-initialized>");
             RuntimeInit.setApplicationObject(mAppThread.asBinder());
             IActivityManager mgr = ActivityManagerNative.getDefault();
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 094b7dd..07b2d1c 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -98,6 +98,9 @@
 
     static final ThreadLocal<RunQueue> sRunQueues = new ThreadLocal<RunQueue>();
 
+    static final ArrayList<Runnable> sFirstDrawHandlers = new ArrayList<Runnable>();
+    static boolean sFirstDrawComplete = false;
+    
     private static int sDrawTime;
 
     long mLastTrackballTime = 0;
@@ -254,6 +257,14 @@
         return sInstanceCount;
     }
 
+    public static void addFirstDrawHandler(Runnable callback) {
+        synchronized (sFirstDrawHandlers) {
+            if (!sFirstDrawComplete) {
+                sFirstDrawHandlers.add(callback);
+            }
+        }
+    }
+    
     // FIXME for perf testing only
     private boolean mProfile = false;
 
@@ -1189,6 +1200,15 @@
             return;
         }
 
+        if (!sFirstDrawComplete) {
+            synchronized (sFirstDrawHandlers) {
+                sFirstDrawComplete = true;
+                for (int i=0; i<sFirstDrawHandlers.size(); i++) {
+                    post(sFirstDrawHandlers.get(i));
+                }
+            }
+        }
+        
         scrollToRectOrFocus(null, false);
 
         if (mAttachInfo.mViewScrollChanged) {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 22447ed..ee1cc8d 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -529,7 +529,8 @@
         // The system server has to run all of the time, so it needs to be
         // as efficient as possible with its memory usage.
         VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
-
+        VMRuntime.getRuntime().startJitCompilation();
+        
         System.loadLibrary("android_servers");
         init1(args);
     }