Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1671)

Unified Diff: android_webview/javatests/src/org/chromium/android_webview/test/SeparateServiceTestBase.java

Issue 2201783003: Add test to ensure shouldOverrideUrlLoading throws Java exception (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add testbase for separate-service tests, use this from AwSecondBrowserTest. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: android_webview/javatests/src/org/chromium/android_webview/test/SeparateServiceTestBase.java
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/SeparateServiceTestBase.java b/android_webview/javatests/src/org/chromium/android_webview/test/SeparateServiceTestBase.java
new file mode 100644
index 0000000000000000000000000000000000000000..120be39d43c136a9c6acb68c110d2a29e1447c49
--- /dev/null
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/SeparateServiceTestBase.java
@@ -0,0 +1,191 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.android_webview.test;
+
+import android.annotation.SuppressLint;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.Process;
+import android.os.RemoteException;
+import android.util.AndroidRuntimeException;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * This class provides functionality that lets you start a service and return some message from the
+ * service to a handler running on a separate thread in the test-process.
+ * NOTE: this class only supports waiting for one message sent from the separate service.
+ */
+public class SeparateServiceTestBase extends AwTestBase {
+ private static final String TAG = SeparateServiceTestBase.class.getSimpleName();
boliu 2016/09/15 04:57:53 unused
+ private AtomicInteger mSeparateProcessPid;
+ // Messenger taking replies from the separate service
+ private Messenger mMessenger;
+ // Thread on which we handle replies from the separate service
+ private HandlerThread mSeparateProcessThread;
+ private CountDownLatch mMessageReceivedLatch;
+ private CountDownLatch mProcessPidMessageReceivedLatch;
+ private Handler.Callback mTestMessageHandler;
+
+ /**
+ * Ensure that we do not start WebView in this process - otherwise we will crash when trying to
+ * start WebView in another process.
+ */
+ @Override
+ protected boolean needsBrowserProcessStarted() {
+ return false;
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mSeparateProcessThread = new HandlerThread("SeparateWebViewProcessThread");
boliu 2016/09/15 04:57:53 do you need a new thread? I think you don't actual
gsennton 2016/09/15 10:02:04 Right, this thread just handles messages and unblo
+ mSeparateProcessThread.start();
+ mMessenger = new Messenger(new TestHandler());
+ mSeparateProcessPid = new AtomicInteger();
+ mMessageReceivedLatch = new CountDownLatch(1);
+ mProcessPidMessageReceivedLatch = new CountDownLatch(1);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ mSeparateProcessThread.quitSafely();
+ mSeparateProcessThread = null;
+ mMessageReceivedLatch = null;
+ mProcessPidMessageReceivedLatch = null;
+ super.tearDown();
+ }
+
+ /**
+ * Starts a Service and then blocks the current thread until a response from the Service has
+ * been handled in the testCode callback.
+ * The Service will be running the code defined in serviceTestCode
+ * testCode is a callback in which we handle a response from the separate Service - this should
+ * return true if the response is handled and false otherwise.
+ */
+ protected void runServiceTestBlocking(ServiceTestRunner serviceTestCode,
+ Handler.Callback testCode, boolean unBindAndStopService) {
+ assertEquals(0, mSeparateProcessPid.get());
+
+ mTestMessageHandler = testCode;
+ Intent intent = new Intent(getActivity(), SeparateProcessWebViewService.class);
+
+ TestServiceConnection serviceConnection =
+ new TestServiceConnection(mMessenger, serviceTestCode, mMessageReceivedLatch);
+
+ // We start the service explicitly to ensure it keeps on running asynchronous tasks.
+ assertNotNull(getActivity().startService(intent));
+ try {
+ assertTrue(getActivity().bindService(intent, serviceConnection, 0));
+ try {
+ waitForServiceResponse();
+ } finally {
+ if (unBindAndStopService) {
+ getActivity().unbindService(serviceConnection);
+ }
+ }
+ } finally {
+ if (unBindAndStopService) {
+ getActivity().stopService(intent);
+ }
+ }
+ }
+
+ /**
+ * ServiceConnection that sends a custom message and messenger to the given service when bound.
+ */
+ private static class TestServiceConnection implements ServiceConnection {
+ private Messenger mMessenger;
+ private ServiceTestRunner mServiceTestCode;
+ private CountDownLatch mMessageReceivedLatch;
+
+ public TestServiceConnection(Messenger messenger, ServiceTestRunner serviceTestCode,
+ CountDownLatch messageReceivedLatch) {
+ mMessenger = messenger;
+ mServiceTestCode = serviceTestCode;
+ mMessageReceivedLatch = messageReceivedLatch;
+ }
+
+ public void onServiceConnected(ComponentName className, IBinder service) {
+ Messenger serviceMessenger = new Messenger(service);
+ setupServiceMessaging(serviceMessenger);
+ }
+
+ public void onServiceDisconnected(ComponentName className) {
+ assertEquals("Service disconnected before we received a response", (long) 0,
boliu 2016/09/15 04:57:53 0L
+ mMessageReceivedLatch.getCount());
+ }
+
+ private void setupServiceMessaging(Messenger serviceMessenger) {
+ Message msg = Message.obtain();
+ msg.replyTo = mMessenger;
+ Bundle data = new Bundle();
+ data.putSerializable(
+ SeparateProcessWebViewService.TEST_CODE_BUNDLE_TAG, mServiceTestCode);
+ msg.setData(data);
+ try {
+ serviceMessenger.send(msg);
+ } catch (RemoteException e) {
+ throw new AndroidRuntimeException(e);
+ }
+ }
+ };
+
+ // TODO do we care about handler leaks in a test class?
boliu 2016/09/15 04:57:53 no
+ @SuppressLint("HandlerLeak")
+ private class TestHandler extends Handler {
+ public TestHandler() {
+ super(mSeparateProcessThread.getLooper(), new Handler.Callback() {
+ @Override
+ public boolean handleMessage(Message message) {
+ if (message.what == SeparateProcessWebViewService.PROCESS_PID_MESSAGE_ID) {
+ mSeparateProcessPid.set(message.arg1);
+ mProcessPidMessageReceivedLatch.countDown();
boliu 2016/09/15 04:57:53 It's really odd that we are the one starting a ser
gsennton 2016/09/15 10:02:04 Oooooh, you mean in case the child decides to retu
Torne 2016/09/15 10:26:43 Not really; Android doesn't really think there's a
boliu 2016/09/15 16:47:51 Yeah that's sort of what I assumed too. Still supe
+ return true;
+ }
+ if (mTestMessageHandler.handleMessage(message)) {
+ mMessageReceivedLatch.countDown();
boliu 2016/09/15 04:57:53 I'm confused what the return value of mTestMessage
gsennton 2016/09/15 10:02:04 Yeah, this implementation is assuming that you eit
boliu 2016/09/15 18:04:04 Another option is you can give the latch up to the
+ return true;
+ }
+ return false;
+ }
+ });
+ }
+ }
+
+ protected void waitForServiceResponse() {
+ try {
+ assertTrue(mProcessPidMessageReceivedLatch.await(
+ AwTestBase.WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ assertTrue(
+ mMessageReceivedLatch.await(AwTestBase.WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ } catch (InterruptedException e) {
+ }
+ }
+
+ protected void killSeparateProcess() {
+ if (mSeparateProcessPid.get() <= 0)
+ throw new AndroidRuntimeException("Separate browser pid less than 0 :(");
+ Process.killProcess(mSeparateProcessPid.get());
+ }
+
+ protected void resetSeparateProcessPid() {
+ mSeparateProcessPid.set(0);
+ }
+
+ protected int getSeparateProcessPid() {
+ assertEquals(0, mProcessPidMessageReceivedLatch.getCount());
+ return mSeparateProcessPid.get();
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698