Revert "Fix issue #72116995: Add permission guarding Service#startForeground"

This reverts commit 7890baea48dba67c3c4aa2b07709ead409f16240.

Reason for revert: b/73224471

Bug: 73224471
Bug: 72116995
Change-Id: Ife5dc5c14026ae7dcb126b0b3c3e7701ed3eaebe
(cherry picked from commit b19c1b8ec6b26e16466ae3a6ccbf0e10a1efd9b0)
diff --git a/samples/ApiDemos/AndroidManifest.xml b/samples/ApiDemos/AndroidManifest.xml
index 7efa922..0301849 100644
--- a/samples/ApiDemos/AndroidManifest.xml
+++ b/samples/ApiDemos/AndroidManifest.xml
@@ -39,7 +39,6 @@
     <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"/>
-    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
     <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
     <uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES"/>
     <!-- Required for drawing overlay windows (TYPE_SYSTEM_ALERT, TYPE_APPLICATION_OVERLAY) -->
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 8d34b0c..a8c3b86 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/ForegroundService.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ForegroundService.java
@@ -52,7 +52,119 @@
     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};
+    private static final Class<?>[] mStartForegroundSignature = new Class[] {
+        int.class, Notification.class};
+    private static final Class<?>[] mStopForegroundSignature = new Class[] {
+        boolean.class};
+    
     private NotificationManager mNM;
+    private Method mSetForeground;
+    private Method mStartForeground;
+    private Method mStopForeground;
+    private Object[] mSetForegroundArgs = new Object[1];
+    private Object[] mStartForegroundArgs = new Object[2];
+    private Object[] mStopForegroundArgs = new Object[1];
+    
+    void invokeMethod(Method method, Object[] args) {
+        try {
+            method.invoke(this, args);
+        } catch (InvocationTargetException e) {
+            // Should not happen.
+            Log.w("ApiDemos", "Unable to invoke method", e);
+        } catch (IllegalAccessException e) {
+            // Should not happen.
+            Log.w("ApiDemos", "Unable to invoke method", e);
+        }
+    }
+    
+    /**
+     * This is a wrapper around the new startForeground method, using the older
+     * APIs if it is not available.
+     */
+    void startForegroundCompat(int id, Notification notification) {
+        // If we have the new startForeground API, then use it.
+        if (mStartForeground != null) {
+            mStartForegroundArgs[0] = Integer.valueOf(id);
+            mStartForegroundArgs[1] = notification;
+            invokeMethod(mStartForeground, mStartForegroundArgs);
+            return;
+        }
+        
+        // Fall back on the old API.
+        mSetForegroundArgs[0] = Boolean.TRUE;
+        invokeMethod(mSetForeground, mSetForegroundArgs);
+        mNM.notify(id, notification);
+    }
+    
+    /**
+     * This is a wrapper around the new stopForeground method, using the older
+     * APIs if it is not available.
+     */
+    void stopForegroundCompat(int id) {
+        // If we have the new stopForeground API, then use it.
+        if (mStopForeground != null) {
+            mStopForegroundArgs[0] = Boolean.TRUE;
+            invokeMethod(mStopForeground, mStopForegroundArgs);
+            return;
+        }
+        
+        // Fall back on the old API.  Note to cancel BEFORE changing the
+        // foreground state, since we could be killed at that point.
+        mNM.cancel(id);
+        mSetForegroundArgs[0] = Boolean.FALSE;
+        invokeMethod(mSetForeground, mSetForegroundArgs);
+    }
+    
+    @Override
+    public void onCreate() {
+        mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
+        try {
+            mStartForeground = getClass().getMethod("startForeground",
+                    mStartForegroundSignature);
+            mStopForeground = getClass().getMethod("stopForeground",
+                    mStopForegroundSignature);
+            return;
+        } catch (NoSuchMethodException e) {
+            // Running on an older platform.
+            mStartForeground = mStopForeground = null;
+        }
+        try {
+            mSetForeground = getClass().getMethod("setForeground",
+                    mSetForegroundSignature);
+        } catch (NoSuchMethodException e) {
+            throw new IllegalStateException(
+                    "OS doesn't have Service.startForeground OR Service.setForeground!");
+        }
+    }
+
+    @Override
+    public void onDestroy() {
+        handleDestroy();
+        // Make sure our notification is gone.
+        stopForegroundCompat(R.string.foreground_service_started);
+    }
+// END_INCLUDE(foreground_compatibility)
+
+// BEGIN_INCLUDE(start_compatibility)
+    // This is the old onStart method that will be called on the pre-2.0
+    // platform.  On 2.0 or later we override onStartCommand() so this
+    // method will not be called.
+    @Override
+    public void onStart(Intent intent, int startId) {
+        handleCommand(intent);
+    }
+
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+        handleCommand(intent);
+        // We want this service to continue running until it is explicitly
+        // stopped, so return sticky.
+        return START_STICKY;
+    }
+// END_INCLUDE(start_compatibility)
 
     private PowerManager.WakeLock mWakeLock;
     private Handler mHandler = new Handler();
@@ -63,20 +175,7 @@
         }
     };
 
-    @Override
-    public void onCreate() {
-        mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
-    }
-
-    @Override
-    public void onDestroy() {
-        handleDestroy();
-        // Make sure our notification is gone.
-        stopForeground(R.string.foreground_service_started);
-    }
-
-    @Override
-    public int onStartCommand(Intent intent, int flags, int startId) {
+    void handleCommand(Intent intent) {
         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
@@ -95,11 +194,11 @@
                     .setContentIntent(contentIntent)  // The intent to send when clicked
                     .build();
 
-            startForeground(R.string.foreground_service_started, notification);
-
+            startForegroundCompat(R.string.foreground_service_started, notification);
+            
         } else if (ACTION_BACKGROUND.equals(intent.getAction())
                 || ACTION_BACKGROUND_WAKELOCK.equals(intent.getAction())) {
-            stopForeground(R.string.foreground_service_started);
+            stopForegroundCompat(R.string.foreground_service_started);
         }
 
         if (ACTION_FOREGROUND_WAKELOCK.equals(intent.getAction())
@@ -115,10 +214,6 @@
 
         mHandler.removeCallbacks(mPulser);
         mPulser.run();
-
-        // We want this service to continue running until it is explicitly
-        // stopped, so return sticky.
-        return START_STICKY;
     }
 
     void releaseWakeLock() {
diff --git a/samples/ToyVpn/AndroidManifest.xml b/samples/ToyVpn/AndroidManifest.xml
index 5f1cc2b..8366dd6 100644
--- a/samples/ToyVpn/AndroidManifest.xml
+++ b/samples/ToyVpn/AndroidManifest.xml
@@ -17,7 +17,6 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="com.example.android.toyvpn">
 
-    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
     <uses-permission android:name="android.permission.INTERNET"/>
 
     <uses-sdk android:minSdkVersion="14"/>
diff --git a/samples/browseable/BluetoothAdvertisements/AndroidManifest.xml b/samples/browseable/BluetoothAdvertisements/AndroidManifest.xml
index 571a08f..cd2a65e 100644
--- a/samples/browseable/BluetoothAdvertisements/AndroidManifest.xml
+++ b/samples/browseable/BluetoothAdvertisements/AndroidManifest.xml
@@ -21,7 +21,6 @@
 
     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
     <uses-permission android:name="android.permission.BLUETOOTH" />
-    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
 
     <application
         android:allowBackup="true"
diff --git a/samples/browseable/MediaBrowserService/AndroidManifest.xml b/samples/browseable/MediaBrowserService/AndroidManifest.xml
index e459ed1..45c8de7 100644
--- a/samples/browseable/MediaBrowserService/AndroidManifest.xml
+++ b/samples/browseable/MediaBrowserService/AndroidManifest.xml
@@ -19,7 +19,6 @@
     android:versionCode="1"
     android:versionName="1.0" >
 
-    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.WAKE_LOCK" />