Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.content.browser; | 5 package org.chromium.content.browser; |
| 6 | 6 |
| 7 import android.content.ComponentName; | 7 import android.content.ComponentName; |
| 8 import android.content.Context; | 8 import android.content.Context; |
| 9 import android.content.Intent; | 9 import android.content.Intent; |
| 10 import android.content.ServiceConnection; | 10 import android.content.ServiceConnection; |
| 11 import android.os.Handler; | 11 import android.os.Handler; |
| 12 import android.os.IBinder; | 12 import android.os.IBinder; |
| 13 import android.os.Looper; | 13 import android.os.Looper; |
| 14 import android.os.Message; | 14 import android.os.Message; |
| 15 import android.os.Messenger; | 15 import android.os.Messenger; |
| 16 import android.os.RemoteException; | 16 import android.os.RemoteException; |
| 17 import android.support.test.filters.MediumTest; | 17 import android.support.test.filters.MediumTest; |
| 18 import android.test.InstrumentationTestCase; | 18 import android.test.InstrumentationTestCase; |
| 19 | 19 |
| 20 import org.chromium.base.BaseSwitches; | 20 import org.chromium.base.BaseSwitches; |
| 21 import org.chromium.base.library_loader.LibraryLoader; | 21 import org.chromium.base.library_loader.LibraryLoader; |
| 22 import org.chromium.base.library_loader.LibraryProcessType; | 22 import org.chromium.base.library_loader.LibraryProcessType; |
| 23 import org.chromium.base.test.util.CommandLineFlags; | 23 import org.chromium.base.test.util.CommandLineFlags; |
| 24 import org.chromium.base.test.util.Feature; | 24 import org.chromium.base.test.util.Feature; |
| 25 import org.chromium.content.browser.test.util.Criteria; | 25 import org.chromium.content.browser.test.util.Criteria; |
| 26 import org.chromium.content.browser.test.util.CriteriaHelper; | 26 import org.chromium.content.browser.test.util.CriteriaHelper; |
| 27 import org.chromium.content.common.FileDescriptorInfo; | 27 import org.chromium.content.common.FileDescriptorInfo; |
| 28 import org.chromium.content_shell_apk.ChildProcessLauncherTestHelperService; | 28 import org.chromium.content_shell_apk.ChildProcessLauncherTestHelperService; |
| 29 | 29 |
| 30 import java.util.Map; | |
| 31 import java.util.concurrent.Callable; | 30 import java.util.concurrent.Callable; |
| 32 | 31 |
| 33 /** | 32 /** |
| 34 * Instrumentation tests for ChildProcessLauncher. | 33 * Instrumentation tests for ChildProcessLauncher. |
| 35 */ | 34 */ |
| 36 public class ChildProcessLauncherTest extends InstrumentationTestCase { | 35 public class ChildProcessLauncherTest extends InstrumentationTestCase { |
| 37 // Pseudo command line arguments to instruct the child process to wait until being killed. | 36 // Pseudo command line arguments to instruct the child process to wait until being killed. |
| 38 // Allowing the process to continue would lead to a crash when attempting to initialize IPC | 37 // Allowing the process to continue would lead to a crash when attempting to initialize IPC |
| 39 // channels that are not being set up in this test. | 38 // channels that are not being set up in this test. |
| 40 private static final String[] sProcessWaitArguments = { | 39 private static final String[] sProcessWaitArguments = { |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 392 getDefaultChildProcessCreationParams(context.getPackageName())); | 391 getDefaultChildProcessCreationParams(context.getPackageName())); |
| 393 | 392 |
| 394 CriteriaHelper.pollInstrumentationThread( | 393 CriteriaHelper.pollInstrumentationThread( |
| 395 new Criteria("Failed waiting for instrumentation-bound service") { | 394 new Criteria("Failed waiting for instrumentation-bound service") { |
| 396 @Override | 395 @Override |
| 397 public boolean isSatisfied() { | 396 public boolean isSatisfied() { |
| 398 return conn.getService() != null; | 397 return conn.getService() != null; |
| 399 } | 398 } |
| 400 }); | 399 }); |
| 401 | 400 |
| 402 triggerConnectionSetup((ChildProcessConnectionImpl) conn); | 401 assertEquals(0, conn.getServiceNumber()); |
| 403 | 402 |
| 404 assertEquals(0, conn.getServiceNumber()); | 403 final ChildProcessConnection[] sandboxedConnections = |
| 405 assertEquals(-1, conn.getPid()); // PID gets set to -1 if service is al ready bound. | 404 ChildProcessLauncher.getSandboxedConnectionArrayForTesting( |
| 406 | 405 context.getPackageName()); |
| 407 final Map<Integer, ChildProcessConnection> serviceMap = | |
| 408 ChildProcessLauncher.getServiceMapForTesting(); | |
| 409 | 406 |
| 410 // Wait for the retry to succeed. | 407 // Wait for the retry to succeed. |
| 411 CriteriaHelper.pollInstrumentationThread( | 408 CriteriaHelper.pollInstrumentationThread( |
| 412 new Criteria("Failed waiting for both child process services") { | 409 new Criteria("Failed waiting for both child process services") { |
| 413 @Override | 410 @Override |
| 414 public boolean isSatisfied() { | 411 public boolean isSatisfied() { |
| 415 boolean allChildrenConnected = serviceMap.size() == 2; | 412 boolean allChildrenConnected = true; |
| 416 for (ChildProcessConnection conn : serviceMap.values()) { | 413 for (int i = 0; i < sandboxedConnections.length; ++i) { |
| 417 allChildrenConnected &= conn.getService() != null; | 414 ChildProcessConnection conn = sandboxedConnections[i ]; |
| 415 if (i <= 1) { | |
| 416 allChildrenConnected &= conn != null && conn.get Service() != null; | |
| 417 } else { | |
| 418 allChildrenConnected &= conn == null; | |
|
boliu
2017/01/26 19:00:35
is there any reason to check this?
Robert Sesek
2017/01/26 19:27:01
Just to ensure the retry only happens once.
boliu
2017/01/26 19:30:28
You can check that after the poll, this just makes
Robert Sesek
2017/01/26 19:47:24
Done.
| |
| 419 } | |
| 418 } | 420 } |
| 419 return allChildrenConnected; | 421 return allChildrenConnected; |
| 420 } | 422 } |
| 421 }); | 423 }); |
| 422 | 424 |
| 423 assertEquals(2, serviceMap.size()); | 425 assertTrue(conn == sandboxedConnections[0]); |
| 426 final ChildProcessConnection retryConn = sandboxedConnections[1]; | |
| 424 | 427 |
| 425 boolean testedSlot0 = false, testedSlot1 = false; | 428 assertFalse(conn == retryConn); |
| 426 | 429 |
| 427 for (ChildProcessConnection childProcess : serviceMap.values()) { | 430 assertEquals(0, conn.getServiceNumber()); |
| 428 if (childProcess == conn) { | 431 assertEquals(0, conn.getPid()); |
| 429 assertFalse(testedSlot0); | 432 assertFalse(conn.getService().bindToCaller()); |
| 430 assertEquals(0, childProcess.getServiceNumber()); | |
| 431 assertEquals(-1, childProcess.getPid()); | |
| 432 assertFalse(childProcess.getService().bindToCaller()); | |
| 433 testedSlot0 = true; | |
| 434 } else { | |
| 435 assertFalse(testedSlot1); | |
| 436 assertEquals(1, childProcess.getServiceNumber()); | |
| 437 assertTrue(childProcess.getPid() > 0); | |
| 438 assertTrue(childProcess.getPid() != helperConnPid); | |
| 439 assertTrue(childProcess.getService().bindToCaller()); | |
| 440 testedSlot1 = true; | |
| 441 } | |
| 442 } | |
| 443 | 433 |
| 444 assertTrue(testedSlot0); | 434 assertEquals(1, retryConn.getServiceNumber()); |
| 445 assertTrue(testedSlot1); | 435 assertTrue(retryConn.getPid() > 0); |
| 436 assertTrue(retryConn.getPid() != helperConnPid); | |
| 437 assertTrue(retryConn.getService().bindToCaller()); | |
| 446 } | 438 } |
| 447 | 439 |
| 448 private ChildProcessConnectionImpl startConnection() { | 440 private ChildProcessConnectionImpl startConnection() { |
| 449 // Allocate a new connection. | 441 // Allocate a new connection. |
| 450 Context context = getInstrumentation().getTargetContext(); | 442 Context context = getInstrumentation().getTargetContext(); |
| 451 final ChildProcessConnectionImpl connection = | 443 final ChildProcessConnectionImpl connection = |
| 452 (ChildProcessConnectionImpl) ChildProcessLauncher.allocateBoundC onnectionForTesting( | 444 (ChildProcessConnectionImpl) ChildProcessLauncher.allocateBoundC onnectionForTesting( |
| 453 context, getDefaultChildProcessCreationParams(context.ge tPackageName())); | 445 context, getDefaultChildProcessCreationParams(context.ge tPackageName())); |
| 454 | 446 |
| 455 // Wait for the service to connect. | 447 // Wait for the service to connect. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 487 private ChildProcessCreationParams getDefaultChildProcessCreationParams(Stri ng packageName) { | 479 private ChildProcessCreationParams getDefaultChildProcessCreationParams(Stri ng packageName) { |
| 488 return new ChildProcessCreationParams(packageName, false /* isExternalSe rvice */, | 480 return new ChildProcessCreationParams(packageName, false /* isExternalSe rvice */, |
| 489 LibraryProcessType.PROCESS_CHILD); | 481 LibraryProcessType.PROCESS_CHILD); |
| 490 } | 482 } |
| 491 | 483 |
| 492 private void triggerConnectionSetup(ChildProcessConnectionImpl connection) { | 484 private void triggerConnectionSetup(ChildProcessConnectionImpl connection) { |
| 493 ChildProcessLauncher.triggerConnectionSetup(connection, sProcessWaitArgu ments, 1, | 485 ChildProcessLauncher.triggerConnectionSetup(connection, sProcessWaitArgu ments, 1, |
| 494 new FileDescriptorInfo[0], ChildProcessLauncher.CALLBACK_FOR_REN DERER_PROCESS, 0); | 486 new FileDescriptorInfo[0], ChildProcessLauncher.CALLBACK_FOR_REN DERER_PROCESS, 0); |
| 495 } | 487 } |
| 496 } | 488 } |
| OLD | NEW |