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);