Extend foreground service test to demonstrate doze behavior.

Change-Id: I81162b6a309a09c1041b71fce1e9a8335afa5b53
diff --git a/samples/ApiDemos/AndroidManifest.xml b/samples/ApiDemos/AndroidManifest.xml
index 50c5d13..b122870 100644
--- a/samples/ApiDemos/AndroidManifest.xml
+++ b/samples/ApiDemos/AndroidManifest.xml
@@ -37,6 +37,7 @@
     <uses-permission android:name="android.permission.NFC" />
     <uses-permission android:name="android.permission.TRANSMIT_IR" />
     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
+    <uses-permission android:name="android.permission.WAKE_LOCK"/>
 
 
     <!-- For android.media.audiofx.Visualizer -->
@@ -48,6 +49,8 @@
     <uses-feature android:name="android.hardware.camera" />
     <uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
 
+    <uses-sdk android:minSdkVersion="23" android:targetSdkVersion="23" />
+
     <application android:name="ApiDemosApplication"
             android:label="@string/activity_sample_code"
             android:icon="@drawable/app_sample_code"
diff --git a/samples/ApiDemos/res/layout/foreground_service_controller.xml b/samples/ApiDemos/res/layout/foreground_service_controller.xml
index 7716150..ca12be1 100644
--- a/samples/ApiDemos/res/layout/foreground_service_controller.xml
+++ b/samples/ApiDemos/res/layout/foreground_service_controller.xml
@@ -34,12 +34,24 @@
         <requestFocus />
     </Button>
 
+    <Button android:id="@+id/start_foreground_wakelock"
+        android:layout_width="wrap_content" android:layout_height="wrap_content"
+        android:text="@string/start_service_foreground_wakelock">
+        <requestFocus />
+    </Button>
+
     <Button android:id="@+id/start_background"
         android:layout_width="wrap_content" android:layout_height="wrap_content" 
         android:text="@string/start_service_background">
         <requestFocus />
     </Button>
 
+    <Button android:id="@+id/start_background_wakelock"
+        android:layout_width="wrap_content" android:layout_height="wrap_content"
+        android:text="@string/start_service_background_wakelock">
+        <requestFocus />
+    </Button>
+
     <Button android:id="@+id/stop"
         android:layout_width="wrap_content" android:layout_height="wrap_content" 
         android:text="@string/stop_service">
diff --git a/samples/ApiDemos/res/values/strings.xml b/samples/ApiDemos/res/values/strings.xml
index f83dcde..b74c875 100644
--- a/samples/ApiDemos/res/values/strings.xml
+++ b/samples/ApiDemos/res/values/strings.xml
@@ -309,7 +309,9 @@
     <string name="foreground_service_controller">This demonstrates how you can
             implement services that run in the foreground when needed.</string>
     <string name="start_service_foreground">Start Service Foreground</string>
+    <string name="start_service_foreground_wakelock">Start Service Foreground w/Wakelock</string>
     <string name="start_service_background">Start Service Background</string>
+    <string name="start_service_background_wakelock">Start Service Background w/Wakelock</string>
 
     <string name="activity_isolated_service_controller">App/Service/Isolated Service Controller</string>
     <string name="isolated_service_controller">This demonstrates the use of android:isolatedProcess
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/ForegroundService.java b/samples/ApiDemos/src/com/example/android/apis/app/ForegroundService.java
index 19e41d8..bbc3c08 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/ForegroundService.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ForegroundService.java
@@ -23,7 +23,9 @@
 import android.app.Service;
 import android.content.Intent;
 import android.os.Bundle;
+import android.os.Handler;
 import android.os.IBinder;
+import android.os.PowerManager;
 import android.util.Log;
 import android.view.View;
 import android.view.View.OnClickListener;
@@ -41,13 +43,15 @@
  * run in the "foreground".  It shows how to code this to work well by using
  * the improved Android 2.0 APIs when available and otherwise falling back
  * to the original APIs.  Yes: you can take this exact code, compile it
- * against the Android 2.0 SDK, and it will against everything down to
+ * against the Android 2.0 SDK, and it will run against everything down to
  * Android 1.0.
  */
 public class ForegroundService extends Service {
     static final String ACTION_FOREGROUND = "com.example.android.apis.FOREGROUND";
+    static final String ACTION_FOREGROUND_WAKELOCK = "com.example.android.apis.FOREGROUND_WAKELOCK";
     static final String ACTION_BACKGROUND = "com.example.android.apis.BACKGROUND";
-    
+    static final String ACTION_BACKGROUND_WAKELOCK = "com.example.android.apis.BACKGROUND_WAKELOCK";
+
  // BEGIN_INCLUDE(foreground_compatibility)
     private static final Class<?>[] mSetForegroundSignature = new Class[] {
         boolean.class};
@@ -138,6 +142,7 @@
 
     @Override
     public void onDestroy() {
+        handleDestroy();
         // Make sure our notification is gone.
         stopForegroundCompat(R.string.foreground_service_started);
     }
@@ -161,8 +166,18 @@
     }
 // END_INCLUDE(start_compatibility)
 
+    private PowerManager.WakeLock mWakeLock;
+    private Handler mHandler = new Handler();
+    private Runnable mPulser = new Runnable() {
+        @Override public void run() {
+            Log.i("ForegroundService", "PULSE!");
+            mHandler.postDelayed(this, 5*1000);
+        }
+    };
+
     void handleCommand(Intent intent) {
-        if (ACTION_FOREGROUND.equals(intent.getAction())) {
+        if (ACTION_FOREGROUND.equals(intent.getAction())
+                || ACTION_FOREGROUND_WAKELOCK.equals(intent.getAction())) {
             // In this sample, we'll use the same text for the ticker and the expanded notification
             CharSequence text = getText(R.string.foreground_service_started);
 
@@ -181,11 +196,38 @@
 
             startForegroundCompat(R.string.foreground_service_started, notification);
             
-        } else if (ACTION_BACKGROUND.equals(intent.getAction())) {
+        } else if (ACTION_BACKGROUND.equals(intent.getAction())
+                || ACTION_BACKGROUND_WAKELOCK.equals(intent.getAction())) {
             stopForegroundCompat(R.string.foreground_service_started);
         }
+
+        if (ACTION_FOREGROUND_WAKELOCK.equals(intent.getAction())
+                || ACTION_BACKGROUND_WAKELOCK.equals(intent.getAction())) {
+            if (mWakeLock == null) {
+                mWakeLock = getSystemService(PowerManager.class).newWakeLock(
+                        PowerManager.PARTIAL_WAKE_LOCK, "wake-service");
+                mWakeLock.acquire();
+            } else {
+                releaseWakeLock();
+            }
+        }
+
+        mHandler.removeCallbacks(mPulser);
+        mPulser.run();
     }
-    
+
+    void releaseWakeLock() {
+        if (mWakeLock != null) {
+            mWakeLock.release();
+            mWakeLock = null;
+        }
+    }
+
+    void handleDestroy() {
+        releaseWakeLock();
+        mHandler.removeCallbacks(mPulser);
+    }
+
     @Override
     public IBinder onBind(Intent intent) {
         return null;
@@ -209,8 +251,12 @@
             // Watch for button clicks.
             Button button = (Button)findViewById(R.id.start_foreground);
             button.setOnClickListener(mForegroundListener);
+            button = (Button)findViewById(R.id.start_foreground_wakelock);
+            button.setOnClickListener(mForegroundWakelockListener);
             button = (Button)findViewById(R.id.start_background);
             button.setOnClickListener(mBackgroundListener);
+            button = (Button)findViewById(R.id.start_background_wakelock);
+            button.setOnClickListener(mBackgroundWakelockListener);
             button = (Button)findViewById(R.id.stop);
             button.setOnClickListener(mStopListener);
         }
@@ -223,6 +269,14 @@
             }
         };
 
+        private OnClickListener mForegroundWakelockListener = new OnClickListener() {
+            public void onClick(View v) {
+                Intent intent = new Intent(ForegroundService.ACTION_FOREGROUND_WAKELOCK);
+                intent.setClass(Controller.this, ForegroundService.class);
+                startService(intent);
+            }
+        };
+
         private OnClickListener mBackgroundListener = new OnClickListener() {
             public void onClick(View v) {
                 Intent intent = new Intent(ForegroundService.ACTION_BACKGROUND);
@@ -231,6 +285,14 @@
             }
         };
 
+        private OnClickListener mBackgroundWakelockListener = new OnClickListener() {
+            public void onClick(View v) {
+                Intent intent = new Intent(ForegroundService.ACTION_BACKGROUND_WAKELOCK);
+                intent.setClass(Controller.this, ForegroundService.class);
+                startService(intent);
+            }
+        };
+
         private OnClickListener mStopListener = new OnClickListener() {
             public void onClick(View v) {
                 stopService(new Intent(Controller.this,
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.java b/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.java
index 41b9d88..256b1c5 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.java
@@ -82,7 +82,7 @@
 
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
-        Log.i("LocalService", "Received start id " + startId + ": " + intent);
+        Log.i("RemoteService", "Received start id " + startId + ": " + intent);
         return START_NOT_STICKY;
     }