Add test case for Api coverage

Add testStartLocalStoppedService into ServiceTest.

Change-Id: Ic8d9c04f635709081439eba64ab1fbec847714af
Fix: 129200611
Test: atest ServiceTest
diff --git a/tests/app/app/AndroidManifest.xml b/tests/app/app/AndroidManifest.xml
index a576e626..7d34da0 100644
--- a/tests/app/app/AndroidManifest.xml
+++ b/tests/app/app/AndroidManifest.xml
@@ -133,6 +133,8 @@
             <meta-data android:name="android.app.stubs.reference" android:resource="@xml/metadata" />
         </service>
 
+        <service android:name="android.app.stubs.LocalStoppedService" />
+
         <service android:name="android.app.stubs.LocalForegroundService">
             <intent-filter>
                 <action android:name="android.app.stubs.FOREGROUND_SERVICE" />
diff --git a/tests/app/app/src/android/app/stubs/LocalService.java b/tests/app/app/src/android/app/stubs/LocalService.java
index f914cdf..f270582 100644
--- a/tests/app/app/src/android/app/stubs/LocalService.java
+++ b/tests/app/app/src/android/app/stubs/LocalService.java
@@ -48,12 +48,17 @@
     public static final int GET_UID_CODE = 9;
     public static final int GET_PPID_CODE = 10;
     public static final int GET_ZYGOTE_PRELOAD_CALLED = 11;
+    public static final int STOP_SELF_CODE = 12;
+    public static final int STOP_SELF_RESULT_CODE = 13;
+    public static final int STOP_SELF_SUCCESS_UNBIND_CODE = 14;
 
     public static Context sServiceContext = null;
 
     private IBinder mReportObject;
     private int mStartCount = 1;
     private int mValue = 0;
+    private int mStartId = -1;
+    private boolean mIsStoppedSelfSuccess;
 
     private final IBinder mBinder = new Binder() {
         @Override
@@ -88,6 +93,12 @@
                     data.enforceInterface(SERVICE_LOCAL);
                     reply.writeBoolean(ZygotePreload.preloadCalled());
                     return true;
+                case STOP_SELF_RESULT_CODE:
+                    mIsStoppedSelfSuccess = stopSelfResult(mStartId);
+                    return true;
+                case STOP_SELF_CODE:
+                    stopSelf(mStartId);
+                    return true;
                 default:
                     return super.onTransact(code, data, reply, flags);
             }
@@ -99,6 +110,7 @@
 
     @Override
     public void onStart(Intent intent, int startId) {
+        mStartId = startId;
         if (intent.getExtras() != null) {
             IBinderParcelable parcelable
                     = (IBinderParcelable) intent.getExtras().getParcelable(REPORT_OBJ_NAME);
@@ -130,7 +142,11 @@
     @Override
     public boolean onUnbind(Intent intent) {
         if (mReportObject != null) {
-            bindAction(UNBIND_CODE);
+            if (mIsStoppedSelfSuccess) {
+                bindAction(STOP_SELF_SUCCESS_UNBIND_CODE);
+            } else {
+                bindAction(UNBIND_CODE);
+            }
         }
         return true;
     }
diff --git a/tests/app/app/src/android/app/stubs/LocalStoppedService.java b/tests/app/app/src/android/app/stubs/LocalStoppedService.java
new file mode 100644
index 0000000..b569f95
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/LocalStoppedService.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.app.stubs;
+
+public class LocalStoppedService extends LocalService
+{
+}
+
diff --git a/tests/app/src/android/app/cts/ServiceTest.java b/tests/app/src/android/app/cts/ServiceTest.java
index 6649346..5486082 100644
--- a/tests/app/src/android/app/cts/ServiceTest.java
+++ b/tests/app/src/android/app/cts/ServiceTest.java
@@ -29,6 +29,7 @@
 import android.app.stubs.LocalForegroundService;
 import android.app.stubs.LocalGrantedService;
 import android.app.stubs.LocalService;
+import android.app.stubs.LocalStoppedService;
 import android.app.stubs.NullService;
 import android.app.stubs.R;
 import android.content.ComponentName;
@@ -77,6 +78,7 @@
     private static final int STATE_DESTROY = 4;
     private static final int STATE_REBIND = 5;
     private static final int STATE_UNBIND_ONLY = 6;
+    private static final int STATE_STOP_SELF_SUCCESS_UNBIND = 6;
     private static final int DELAY = 5000;
     private static final
         String EXIST_CONN_TO_RECEIVE_SERVICE = "existing connection to receive service";
@@ -220,6 +222,46 @@
         }
     }
 
+    private class TestStopSelfConnection extends TestConnection {
+        private IBinder mService;
+
+        public TestStopSelfConnection() {
+            super(false /* expectDisconnect */, true /* setReporter */);
+        }
+
+        private void executeTransact(int code) {
+            Parcel data = Parcel.obtain();
+            data.writeInterfaceToken(LocalService.SERVICE_LOCAL);
+            try {
+                mService.transact(code, data, null /* reply */, 0);
+            } catch (RemoteException e) {
+                finishBad("DeadObjectException when sending reporting object");
+            }
+            data.recycle();
+        }
+
+        public void stopSelf() {
+            executeTransact(LocalService.STOP_SELF_CODE);
+        }
+
+        public void stopSelfResult() {
+            executeTransact(LocalService.STOP_SELF_RESULT_CODE);
+        }
+
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            mService = service;
+            super.onServiceConnected(name, service);
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            synchronized (this) {
+                mService = null;
+            }
+        }
+    }
+
     final class IsolatedConnection implements ServiceConnection {
         private IBinder mService;
         private int mUid;
@@ -756,12 +798,70 @@
                             + mExpectedServiceState + ")");
                 }
                 return true;
+            } else if (code == LocalService.STOP_SELF_SUCCESS_UNBIND_CODE) {
+                data.enforceInterface(LocalService.SERVICE_LOCAL);
+                if (mExpectedServiceState == STATE_STOP_SELF_SUCCESS_UNBIND) {
+                    finishGood();
+                } else {
+                    finishBad("onUnbind() was called when not expected (state="
+                            + mExpectedServiceState + ")");
+                }
+                return true;
             } else {
                 return super.onTransact(code, data, reply, flags);
             }
         }
     }
 
+    public void testStopSelf() throws Exception {
+        TestStopSelfConnection conn = new TestStopSelfConnection();
+        boolean success = false;
+        final Intent service = new Intent(mContext, LocalStoppedService.class);
+        try {
+            conn.setMonitor(true);
+            mExpectedServiceState = STATE_START_1;
+            mContext.bindService(service, conn, 0);
+            mContext.startService(service);
+            waitForResultOrThrow(DELAY, EXIST_CONN_TO_RECEIVE_SERVICE);
+            success = true;
+        } finally {
+            if (!success) {
+                mContext.unbindService(conn);
+                mContext.stopService(service);
+            }
+        }
+        // Expect to see the service unbind and then destroyed.
+        mExpectedServiceState = STATE_UNBIND;
+        conn.stopSelf();
+        waitForResultOrThrow(DELAY, EXIST_CONN_TO_LOSE_SERVICE);
+
+        mContext.unbindService(conn);
+    }
+
+    public void testStopSelfResult() throws Exception {
+        TestStopSelfConnection conn = new TestStopSelfConnection();
+        boolean success = false;
+        final Intent service = new Intent(mContext, LocalStoppedService.class);
+        try {
+            conn.setMonitor(true);
+            mExpectedServiceState = STATE_START_1;
+            mContext.bindService(service, conn, 0);
+            mContext.startService(service);
+            waitForResultOrThrow(DELAY, EXIST_CONN_TO_RECEIVE_SERVICE);
+            success = true;
+        } finally {
+            if (!success) {
+                mContext.unbindService(conn);
+                mContext.stopService(service);
+            }
+        }
+        // Expect to see the service unbind and then destroyed.
+        mExpectedServiceState = STATE_STOP_SELF_SUCCESS_UNBIND;
+        conn.stopSelfResult();
+        waitForResultOrThrow(DELAY, EXIST_CONN_TO_LOSE_SERVICE);
+
+        mContext.unbindService(conn);
+    }
 
     public void testLocalStartClass() throws Exception {
         startExpectResult(mLocalService);