Add headless mode for running the framework without the surface flinger

Enabled by setting system property ro.config.headless to 1
This will allow the framework to run without starting activities,
system UI and the keyguard.
Framework can still run services, content providers and broadcast receivers.

Signed-off-by: Mike Lockwood <lockwood@android.com>

Conflicts:

	policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
	services/java/com/android/server/PowerManagerService.java
	services/java/com/android/server/am/ActivityManagerService.java
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index bb0ac3e..7974951 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -50,6 +50,7 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
+import android.os.SystemProperties;
 import android.os.WorkSource;
 import android.provider.Settings;
 import android.util.EventLog;
@@ -176,6 +177,7 @@
 
     private boolean mDoneBooting = false;
     private boolean mBootCompleted = false;
+    private boolean mHeadless = false;
     private int mStayOnConditions = 0;
     private final int[] mBroadcastQueue = new int[] { -1, -1, -1 };
     private final int[] mBroadcastWhy = new int[3];
@@ -530,6 +532,7 @@
         mButtonLight = lights.getLight(LightsService.LIGHT_ID_BUTTONS);
         mKeyboardLight = lights.getLight(LightsService.LIGHT_ID_KEYBOARD);
         mAttentionLight = lights.getLight(LightsService.LIGHT_ID_ATTENTION);
+        mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
 
         nativeInit();
         synchronized (mLocks) {
@@ -1894,9 +1897,11 @@
     }
 
     private void updateNativePowerStateLocked() {
-        nativeSetPowerState(
-                (mPowerState & SCREEN_ON_BIT) != 0,
-                (mPowerState & SCREEN_BRIGHT) == SCREEN_BRIGHT);
+        if (!mHeadless) {
+            nativeSetPowerState(
+                    (mPowerState & SCREEN_ON_BIT) != 0,
+                    (mPowerState & SCREEN_BRIGHT) == SCREEN_BRIGHT);
+        }
     }
 
     private int screenOffFinishedAnimatingLocked(int reason) {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index e0d8d4ed..e9fcecc 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -108,6 +108,7 @@
         String factoryTestStr = SystemProperties.get("ro.factorytest");
         int factoryTest = "".equals(factoryTestStr) ? SystemServer.FACTORY_TEST_OFF
                 : Integer.parseInt(factoryTestStr);
+        final boolean headless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
 
         LightsService lights = null;
         PowerManagerService power = null;
@@ -462,8 +463,10 @@
 
             try {
                 Slog.i(TAG, "Wallpaper Service");
-                wallpaper = new WallpaperManagerService(context);
-                ServiceManager.addService(Context.WALLPAPER_SERVICE, wallpaper);
+                if (!headless) {
+                    wallpaper = new WallpaperManagerService(context);
+                    ServiceManager.addService(Context.WALLPAPER_SERVICE, wallpaper);
+                }
             } catch (Throwable e) {
                 reportWtf("starting Wallpaper Service", e);
             }
@@ -655,7 +658,7 @@
             public void run() {
                 Slog.i(TAG, "Making services ready");
 
-                startSystemUi(contextF);
+                if (!headless) startSystemUi(contextF);
                 try {
                     if (batteryF != null) batteryF.systemReady();
                 } catch (Throwable e) {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 0d1d620..0a4c6ac 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -269,7 +269,9 @@
     static final String[] EMPTY_STRING_ARRAY = new String[0];
 
     public ActivityStack mMainStack;
-    
+
+    private final boolean mHeadless;
+
     /**
      * Description of a request to start a new activity, which has been held
      * due to app switches being disabled.
@@ -2311,6 +2313,7 @@
         
         mUsageStatsService = new UsageStatsService(new File(
                 systemDir, "usagestats").toString());
+        mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
 
         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
@@ -4747,7 +4750,9 @@
             if (hr.app == null && app.uid == hr.info.applicationInfo.uid
                     && processName.equals(hr.processName)) {
                 try {
-                    if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
+                    if (mHeadless) {
+                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
+                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
                         didSomething = true;
                     }
                 } catch (Exception e) {
@@ -13878,6 +13883,9 @@
      */
     boolean updateConfigurationLocked(Configuration values,
             ActivityRecord starting, boolean persistent, boolean initLocale) {
+        // do nothing if we are headless
+        if (mHeadless) return true;
+
         int changes = 0;
         
         boolean kept = true;
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 04c1c98..08d4aaf 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -250,6 +250,7 @@
 
     private static final String SYSTEM_SECURE = "ro.secure";
     private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
+    private static final String SYSTEM_HEADLESS = "ro.config.headless";
 
     /**
      * Condition waited on by {@link #reenableKeyguard} to know the call to
@@ -259,6 +260,8 @@
      */
     private boolean mKeyguardDisabled = false;
 
+    private final boolean mHeadless;
+
     private static final int ALLOW_DISABLE_YES = 1;
     private static final int ALLOW_DISABLE_NO = 0;
     private static final int ALLOW_DISABLE_UNKNOWN = -1; // check with DevicePolicyManager
@@ -789,6 +792,7 @@
         mAllowBootMessages = showBootMsgs;
         mLimitedAlphaCompositing = context.getResources().getBoolean(
                 com.android.internal.R.bool.config_sf_limitedAlpha);
+        mHeadless = "1".equals(SystemProperties.get(SYSTEM_HEADLESS, "0"));
 
         mPowerManager = pm;
         mPowerManager.setPolicy(mPolicy);
@@ -5057,6 +5061,8 @@
     // TODO: more accounting of which pid(s) turned it on, keep count,
     // only allow disables from pids which have count on, etc.
     public void showStrictModeViolation(boolean on) {
+        if (mHeadless) return;
+
         int pid = Binder.getCallingPid();
         synchronized(mWindowMap) {
             // Ignoring requests to enable the red border from clients