Add CTS tests for PendingIntent.getForegroundService()

Also there's some infrastructure here for general testing of
startForegroundService() followed by *not* calling startForeground(),
but that will need to be driven from a hostside test in order to
properly test that ANRs happen as expected.

Bug 36130212
Test: this

Change-Id: I83d6672045d480d2da8be4063d3769b222e28617
diff --git a/tests/app/app/src/android/app/stubs/LocalForegroundService.java b/tests/app/app/src/android/app/stubs/LocalForegroundService.java
index f3bb8d3..e0051a4 100644
--- a/tests/app/app/src/android/app/stubs/LocalForegroundService.java
+++ b/tests/app/app/src/android/app/stubs/LocalForegroundService.java
@@ -40,6 +40,7 @@
     public static final int COMMAND_STOP_FOREGROUND_DONT_REMOVE_NOTIFICATION = 3;
     public static final int COMMAND_STOP_FOREGROUND_DETACH_NOTIFICATION = 4;
     public static final int COMMAND_STOP_FOREGROUND_REMOVE_NOTIFICATION_USING_FLAGS = 5;
+    public static final int COMMAND_START_NO_FOREGROUND = 6;
 
     private int mNotificationId = 0;
 
@@ -82,11 +83,20 @@
                 Log.d(TAG, "Detaching foreground service notification");
                 stopForeground(Service.STOP_FOREGROUND_DETACH);
                 break;
+            case COMMAND_START_NO_FOREGROUND:
+                Log.d(TAG, "Starting without calling startForeground()");
+                break;
             default:
                 Log.e(TAG, "Unknown command: " + command);
         }
     }
 
+    @Override
+    public void onDestroy() {
+        Log.d(TAG, "service destroyed");
+        super.onDestroy();
+    }
+
     public static Bundle newCommand(IBinder stateReceiver, int command) {
         Bundle bundle = new Bundle();
         bundle.putParcelable(LocalService.REPORT_OBJ_NAME, new IBinderParcelable(stateReceiver));
diff --git a/tests/app/src/android/app/cts/ServiceTest.java b/tests/app/src/android/app/cts/ServiceTest.java
index c08d421..0e7b308 100644
--- a/tests/app/src/android/app/cts/ServiceTest.java
+++ b/tests/app/src/android/app/cts/ServiceTest.java
@@ -20,6 +20,7 @@
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
+import android.app.PendingIntent;
 import android.app.stubs.ActivityTestsBase;
 import android.app.stubs.LocalDeniedService;
 import android.app.stubs.LocalForegroundService;
@@ -501,9 +502,19 @@
         bindExpectResult(mLocalService);
     }
 
+    /* Just the Intent for a foreground service */
+    private Intent foregroundServiceIntent(int command) {
+        return new Intent(mLocalForegroundService)
+                .putExtras(LocalForegroundService.newCommand(mStateReceiver, command));
+    }
+
     private void startForegroundService(int command) {
-        mContext.startService(new Intent(mLocalForegroundService).putExtras(LocalForegroundService
-                .newCommand(mStateReceiver, command)));
+        mContext.startService(foregroundServiceIntent(command));
+    }
+
+    /* Start the service in a way that promises to go into the foreground */
+    private void startRequiredForegroundService(int command) {
+        mContext.startForegroundService(foregroundServiceIntent(command));
     }
 
     @MediumTest
@@ -703,6 +714,43 @@
         assertNoNotification(2);
     }
 
+    class TestSendCallback implements PendingIntent.OnFinished {
+        public volatile int result = -1;
+
+        @Override
+        public void onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode,
+                String resultData, Bundle resultExtras) {
+            Log.i(TAG, "foreground service PendingIntent callback got " + resultCode);
+            this.result = resultCode;
+        }
+    }
+
+    @MediumTest
+    public void testForegroundService_pendingIntentForeground() throws Exception {
+        boolean success = false;
+
+        PendingIntent pi = PendingIntent.getForegroundService(mContext, 1,
+                foregroundServiceIntent(LocalForegroundService.COMMAND_START_FOREGROUND), 0);
+        TestSendCallback callback = new TestSendCallback();
+
+        try {
+            mExpectedServiceState = STATE_START_1;
+            pi.send(5038, callback, null);
+            waitForResultOrThrow(DELAY, "service to start first time");
+            assertTrue(callback.result > -1);
+
+            success = true;
+        } finally {
+            if (!success) {
+                mContext.stopService(mLocalForegroundService);
+            }
+        }
+
+        mExpectedServiceState = STATE_DESTROY;
+        mContext.stopService(mLocalForegroundService);
+        waitForResultOrThrow(DELAY, "pendingintent service to be destroyed");
+    }
+
     @MediumTest
     public void testLocalBindAction() throws Exception {
         bindExpectResult(new Intent(