diff options
author | Amith Yamasani <yamasani@google.com> | 2017-08-28 09:36:42 -0700 |
---|---|---|
committer | Amith Yamasani <yamasani@google.com> | 2017-09-05 16:51:51 -0700 |
commit | b0c8a887299a7f462c41408edda6043202143233 (patch) | |
tree | 614f1f8c292163e6f55826cb2bfb5fffe1d7e616 /tests/ServiceCrashTest | |
parent | 7affe0160939324d9c2d9404e771b139e7a7f2b9 (diff) |
Retry crashed bound foreground service with some delay
After quick crashes, back-off for 30 minutes and try again.
Keep backing-off up to 10 times and then give up.
Bug: 63075467
Test: runtest -x frameworks/base/tests/ServiceCrashTest
Change-Id: I3819aefac5fd48b49a70b1765e07696f2ad61328
Diffstat (limited to 'tests/ServiceCrashTest')
5 files changed, 254 insertions, 0 deletions
diff --git a/tests/ServiceCrashTest/Android.mk b/tests/ServiceCrashTest/Android.mk new file mode 100644 index 000000000000..d1f845623be8 --- /dev/null +++ b/tests/ServiceCrashTest/Android.mk @@ -0,0 +1,19 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := tests + +# Only compile source java files in this apk. +LOCAL_SRC_FILES := $(call all-java-files-under, src) + +LOCAL_PACKAGE_NAME := ServiceCrashTest + +LOCAL_CERTIFICATE := platform +LOCAL_JAVA_LIBRARIES := legacy-android-test + +LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util android-support-test + +include $(BUILD_PACKAGE) + +# Use the following include to make our test apk. +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/tests/ServiceCrashTest/AndroidManifest.xml b/tests/ServiceCrashTest/AndroidManifest.xml new file mode 100644 index 000000000000..387c8b8ae36b --- /dev/null +++ b/tests/ServiceCrashTest/AndroidManifest.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.tests.servicecrashtest"> + + <application android:label="Service Crash Test"> + <uses-library android:name="android.test.runner" /> + + <service android:name=".CrashingService" + android:process=":badservice" /> + + <activity android:name=".MainActivity" > + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + </intent-filter> + </activity> + </application> + + <instrumentation android:label="Test bound service crash restart" + android:name="android.test.InstrumentationTestRunner" + android:targetPackage="com.android.tests.servicecrashtest" /> + +</manifest> diff --git a/tests/ServiceCrashTest/src/com/android/tests/servicecrashtest/CrashingService.java b/tests/ServiceCrashTest/src/com/android/tests/servicecrashtest/CrashingService.java new file mode 100644 index 000000000000..8593bcea9c3d --- /dev/null +++ b/tests/ServiceCrashTest/src/com/android/tests/servicecrashtest/CrashingService.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2017 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 com.android.tests.servicecrashtest; + +import android.app.Service; +import android.content.Intent; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.IBinder; +import android.os.Looper; +import android.os.Message; +import android.os.Process; +import android.widget.Toast; + +public class CrashingService extends Service { + private ServiceHandler mServiceHandler; + + static long CRASH_DELAY = 1000; + + // Handler that receives messages from the thread + private final class ServiceHandler extends Handler { + public ServiceHandler(Looper looper) { + super(looper); + } + + @Override + public void handleMessage(Message msg) { + throw new RuntimeException("Crashing!"); + } + } + + @Override + public void onCreate() { + mServiceHandler = new ServiceHandler(Looper.getMainLooper()); + Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show(); + + Message msg = mServiceHandler.obtainMessage(); + mServiceHandler.sendMessageDelayed(msg, CRASH_DELAY); + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + // If we get killed, after returning from here, restart + return START_STICKY; + } + + @Override + public IBinder onBind(Intent intent) { + // We don't provide binding, so return null + return null; + } +}
\ No newline at end of file diff --git a/tests/ServiceCrashTest/src/com/android/tests/servicecrashtest/MainActivity.java b/tests/ServiceCrashTest/src/com/android/tests/servicecrashtest/MainActivity.java new file mode 100644 index 000000000000..8fffecc41dbd --- /dev/null +++ b/tests/ServiceCrashTest/src/com/android/tests/servicecrashtest/MainActivity.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2017 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 com.android.tests.servicecrashtest; + +import android.app.Activity; +import android.app.Service; +import android.content.ComponentName; +import android.content.Intent; +import android.content.ServiceConnection; +import android.os.Bundle; +import android.os.IBinder; +import android.util.Log; +import android.widget.TextView; + +import java.util.concurrent.CountDownLatch; + +public class MainActivity extends Activity { + + private static final String TAG = "ServiceCrashTest"; + + static final CountDownLatch sBindingDiedLatch = new CountDownLatch(1); + + private ServiceConnection mServiceConnection = new ServiceConnection() { + + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + Log.i(TAG, "Service connected"); + } + + @Override + public void onServiceDisconnected(ComponentName name) { + Log.i(TAG, "Service disconnected"); + } + + @Override + public void onBindingDied(ComponentName componentName) { + Log.i(TAG, "Binding died"); + sBindingDiedLatch.countDown(); + } + }; + + @Override + public void onCreate(Bundle savedInstance) { + super.onCreate(savedInstance); + + setContentView(new TextView(this)); + } + + public void onResume() { + Intent intent = new Intent(); + intent.setClass(this, CrashingService.class); + bindService(intent, mServiceConnection, Service.BIND_AUTO_CREATE); + + super.onResume(); + } +} diff --git a/tests/ServiceCrashTest/src/com/android/tests/servicecrashtest/ServiceCrashTest.java b/tests/ServiceCrashTest/src/com/android/tests/servicecrashtest/ServiceCrashTest.java new file mode 100644 index 000000000000..fb0fa4b86185 --- /dev/null +++ b/tests/ServiceCrashTest/src/com/android/tests/servicecrashtest/ServiceCrashTest.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2017 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 com.android.tests.servicecrashtest; + +import android.app.UiAutomation; +import android.content.Context; +import android.content.Intent; +import android.os.RemoteException; +import android.provider.Settings; +import android.test.InstrumentationTestCase; + +import com.android.compatibility.common.util.SystemUtil; + +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +public class ServiceCrashTest extends InstrumentationTestCase { + + private static final String TAG = ServiceCrashTest.class.getSimpleName(); + + private String mResetConstants = "foo=bar"; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mResetConstants = Settings.Global.getString( + getInstrumentation().getContext().getContentResolver(), + Settings.Global.ACTIVITY_MANAGER_CONSTANTS); + setAMConstants("service_crash_restart_duration=5000,service_crash_max_retry=4"); + } + + @Override + protected void tearDown() throws Exception { + // Reset the activity manager constants + setAMConstants(mResetConstants); + super.tearDown(); + } + + private void setAMConstants(String value) throws IOException { + // Set the activity manager constants + if (value == null) { + SystemUtil.runShellCommand(getInstrumentation(), + "settings delete global activity_manager_constants"); + } else { + SystemUtil.runShellCommand(getInstrumentation(), "settings put global " + + "activity_manager_constants " + value); + } + } + + public void testCrashQuickly() throws RemoteException { + Context ctx = getInstrumentation().getContext(); + // Start the activity, which will bind the crashing service + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_MAIN); + intent.setClass(ctx, MainActivity.class); + ctx.startActivity(intent); + try { + assertTrue(MainActivity.sBindingDiedLatch.await(200, TimeUnit.SECONDS)); + } catch (InterruptedException ie) { + } + } +} |