| 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.Bundle; |
| 11 import android.os.Handler; | 12 import android.os.Handler; |
| 12 import android.os.IBinder; | 13 import android.os.IBinder; |
| 13 import android.os.Looper; | 14 import android.os.Looper; |
| 14 import android.os.Message; | 15 import android.os.Message; |
| 15 import android.os.Messenger; | 16 import android.os.Messenger; |
| 16 import android.os.RemoteException; | 17 import android.os.RemoteException; |
| 17 import android.support.test.InstrumentationRegistry; | 18 import android.support.test.InstrumentationRegistry; |
| 18 import android.support.test.filters.MediumTest; | 19 import android.support.test.filters.MediumTest; |
| 19 | 20 |
| 20 import org.junit.Assert; | 21 import org.junit.Assert; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 49 // channels that are not being set up in this test. | 50 // channels that are not being set up in this test. |
| 50 private static final String[] sProcessWaitArguments = { | 51 private static final String[] sProcessWaitArguments = { |
| 51 "_", "--" + BaseSwitches.RENDERER_WAIT_FOR_JAVA_DEBUGGER }; | 52 "_", "--" + BaseSwitches.RENDERER_WAIT_FOR_JAVA_DEBUGGER }; |
| 52 private static final String EXTERNAL_APK_PACKAGE_NAME = "org.chromium.extern
al.apk"; | 53 private static final String EXTERNAL_APK_PACKAGE_NAME = "org.chromium.extern
al.apk"; |
| 53 private static final String DEFAULT_SANDBOXED_PROCESS_SERVICE = | 54 private static final String DEFAULT_SANDBOXED_PROCESS_SERVICE = |
| 54 "org.chromium.content.app.SandboxedProcessService"; | 55 "org.chromium.content.app.SandboxedProcessService"; |
| 55 | 56 |
| 56 @Before | 57 @Before |
| 57 public void setUp() throws Exception { | 58 public void setUp() throws Exception { |
| 58 LibraryLoader.get(LibraryProcessType.PROCESS_CHILD).ensureInitialized(); | 59 LibraryLoader.get(LibraryProcessType.PROCESS_CHILD).ensureInitialized(); |
| 60 ChildProcessLauncherTestUtils.runOnLauncherThreadBlocking(new Runnable()
{ |
| 61 @Override |
| 62 public void run() { |
| 63 ChildProcessLauncherHelper.initLinker(); |
| 64 } |
| 65 }); |
| 59 } | 66 } |
| 60 | 67 |
| 61 /** | 68 /** |
| 62 * Tests cleanup for a connection that fails to connect in the first place. | 69 * Tests cleanup for a connection that fails to connect in the first place. |
| 63 */ | 70 */ |
| 64 @Test | 71 @Test |
| 65 @MediumTest | 72 @MediumTest |
| 66 @Feature({"ProcessManagement"}) | 73 @Feature({"ProcessManagement"}) |
| 67 @ChildProcessAllocatorSettings(sandboxedServiceCount = 4) | 74 @ChildProcessAllocatorSettings(sandboxedServiceCount = 4) |
| 68 public void testServiceFailedToBind() { | 75 public void testServiceFailedToBind() { |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 397 Assert.assertNotNull(replyHandler.mMessage); | 404 Assert.assertNotNull(replyHandler.mMessage); |
| 398 Assert.assertEquals(ChildProcessLauncherTestHelperService.MSG_BIND_SERVI
CE_REPLY, | 405 Assert.assertEquals(ChildProcessLauncherTestHelperService.MSG_BIND_SERVI
CE_REPLY, |
| 399 replyHandler.mMessage.what); | 406 replyHandler.mMessage.what); |
| 400 Assert.assertEquals( | 407 Assert.assertEquals( |
| 401 "Connection slot from helper service is not 0", 0, replyHandler.
mMessage.arg2); | 408 "Connection slot from helper service is not 0", 0, replyHandler.
mMessage.arg2); |
| 402 | 409 |
| 403 final int helperConnPid = replyHandler.mMessage.arg1; | 410 final int helperConnPid = replyHandler.mMessage.arg1; |
| 404 Assert.assertTrue(helperConnPid > 0); | 411 Assert.assertTrue(helperConnPid > 0); |
| 405 | 412 |
| 406 // Launch a service from this process. Since slot 0 is already bound by
the Helper, it | 413 // Launch a service from this process. Since slot 0 is already bound by
the Helper, it |
| 407 // will fail to start and the ChildProcessLauncher will retry. | 414 // will fail to start and the ChildProcessLauncher will retry and use th
e slot 1. |
| 408 final ChildProcessCreationParams creationParams = new ChildProcessCreati
onParams( | 415 final ChildProcessCreationParams creationParams = new ChildProcessCreati
onParams( |
| 409 context.getPackageName(), false /* isExternalService */, | 416 context.getPackageName(), false /* isExternalService */, |
| 410 LibraryProcessType.PROCESS_CHILD, true /* bindToCallerCheck */); | 417 LibraryProcessType.PROCESS_CHILD, true /* bindToCallerCheck */); |
| 411 final ChildProcessConnection conn = ChildProcessLauncherTestUtils.startI
nternalForTesting( | 418 final ChildProcessLauncherHelper launcherHelper = |
| 412 context, sProcessWaitArguments, new FileDescriptorInfo[0], creat
ionParams); | 419 ChildProcessLauncherTestUtils.startForTesting( |
| 420 context, sProcessWaitArguments, new FileDescriptorInfo[0
], creationParams); |
| 413 | 421 |
| 414 CriteriaHelper.pollInstrumentationThread( | 422 // Retrieve the connection (this waits for the service to connect). |
| 415 new Criteria("Failed waiting for instrumentation-bound service")
{ | 423 final ChildProcessConnection retryConn = retrieveConnection(launcherHelp
er); |
| 416 @Override | 424 Assert.assertEquals(1, ChildProcessLauncherTestUtils.getConnectionServic
eNumber(retryConn)); |
| 417 public boolean isSatisfied() { | |
| 418 return ChildProcessLauncherTestUtils.getConnectionServic
e(conn) != null; | |
| 419 } | |
| 420 }); | |
| 421 | |
| 422 Assert.assertEquals(0, ChildProcessLauncherTestUtils.getConnectionServic
eNumber(conn)); | |
| 423 | 425 |
| 424 final ChildProcessConnection[] sandboxedConnections = | 426 final ChildProcessConnection[] sandboxedConnections = |
| 425 getSandboxedConnectionArrayForTesting(context, context.getPackag
eName()); | 427 getSandboxedConnectionArrayForTesting(context, context.getPackag
eName()); |
| 426 | 428 |
| 427 // Wait for the retry to succeed. | |
| 428 CriteriaHelper.pollInstrumentationThread( | |
| 429 new Criteria("Failed waiting for both child process services") { | |
| 430 @Override | |
| 431 public boolean isSatisfied() { | |
| 432 boolean allChildrenConnected = true; | |
| 433 for (int i = 0; i <= 1; ++i) { | |
| 434 ChildProcessConnection conn = sandboxedConnections[i
]; | |
| 435 allChildrenConnected &= conn != null | |
| 436 && ChildProcessLauncherTestUtils.getConnecti
onService(conn) | |
| 437 != null; | |
| 438 } | |
| 439 return allChildrenConnected; | |
| 440 } | |
| 441 }); | |
| 442 | |
| 443 // Check that only two connections are created. | 429 // Check that only two connections are created. |
| 444 for (int i = 0; i < sandboxedConnections.length; ++i) { | 430 for (int i = 0; i < sandboxedConnections.length; ++i) { |
| 445 ChildProcessConnection sandboxedConn = sandboxedConnections[i]; | 431 ChildProcessConnection sandboxedConn = sandboxedConnections[i]; |
| 446 if (i <= 1) { | 432 if (i <= 1) { |
| 447 Assert.assertNotNull(sandboxedConn); | 433 Assert.assertNotNull(sandboxedConn); |
| 448 Assert.assertNotNull( | 434 Assert.assertNotNull( |
| 449 ChildProcessLauncherTestUtils.getConnectionService(sandb
oxedConn)); | 435 ChildProcessLauncherTestUtils.getConnectionService(sandb
oxedConn)); |
| 450 } else { | 436 } else { |
| 451 Assert.assertNull(sandboxedConn); | 437 Assert.assertNull(sandboxedConn); |
| 452 } | 438 } |
| 453 } | 439 } |
| 454 | 440 |
| 455 Assert.assertTrue(conn == sandboxedConnections[0]); | 441 Assert.assertTrue(retryConn == sandboxedConnections[1]); |
| 456 final ChildProcessConnection retryConn = sandboxedConnections[1]; | |
| 457 | 442 |
| 458 Assert.assertFalse(conn == retryConn); | 443 ChildProcessConnection conn = sandboxedConnections[0]; |
| 459 | |
| 460 Assert.assertEquals(0, ChildProcessLauncherTestUtils.getConnectionServic
eNumber(conn)); | 444 Assert.assertEquals(0, ChildProcessLauncherTestUtils.getConnectionServic
eNumber(conn)); |
| 461 Assert.assertEquals(0, ChildProcessLauncherTestUtils.getConnectionPid(co
nn)); | 445 Assert.assertEquals(0, ChildProcessLauncherTestUtils.getConnectionPid(co
nn)); |
| 462 Assert.assertFalse(ChildProcessLauncherTestUtils.getConnectionService(co
nn).bindToCaller()); | 446 Assert.assertFalse(ChildProcessLauncherTestUtils.getConnectionService(co
nn).bindToCaller()); |
| 463 | 447 |
| 464 Assert.assertEquals(1, ChildProcessLauncherTestUtils.getConnectionServic
eNumber(retryConn)); | 448 Assert.assertEquals(1, ChildProcessLauncherTestUtils.getConnectionServic
eNumber(retryConn)); |
| 465 CriteriaHelper.pollInstrumentationThread( | 449 CriteriaHelper.pollInstrumentationThread( |
| 466 new Criteria("Failed waiting retry connection to get pid") { | 450 new Criteria("Failed waiting retry connection to get pid") { |
| 467 @Override | 451 @Override |
| 468 public boolean isSatisfied() { | 452 public boolean isSatisfied() { |
| 469 return ChildProcessLauncherTestUtils.getConnectionPid(re
tryConn) > 0; | 453 return ChildProcessLauncherTestUtils.getConnectionPid(re
tryConn) > 0; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 481 public void run() { | 465 public void run() { |
| 482 ChildProcessLauncher.warmUp(context); | 466 ChildProcessLauncher.warmUp(context); |
| 483 } | 467 } |
| 484 }); | 468 }); |
| 485 } | 469 } |
| 486 | 470 |
| 487 @Test | 471 @Test |
| 488 @MediumTest | 472 @MediumTest |
| 489 @Feature({"ProcessManagement"}) | 473 @Feature({"ProcessManagement"}) |
| 490 public void testWarmUp() { | 474 public void testWarmUp() { |
| 491 final Context context = InstrumentationRegistry.getInstrumentation().get
TargetContext(); | 475 Context context = InstrumentationRegistry.getInstrumentation().getTarget
Context(); |
| 492 warmUpOnUiThreadBlocking(context); | 476 warmUpOnUiThreadBlocking(context); |
| 477 |
| 478 Assert.assertEquals(1, allocatedChromeSandboxedConnectionsCount()); |
| 479 |
| 480 ChildProcessLauncherHelper launcherHelper = ChildProcessLauncherTestUtil
s.startForTesting( |
| 481 context, new String[0], new FileDescriptorInfo[0], null); |
| 482 |
| 483 final ChildProcessConnection conn = retrieveConnection(launcherHelper); |
| 484 |
| 485 Assert.assertEquals( |
| 486 1, allocatedChromeSandboxedConnectionsCount()); // Used warmup c
onnection. |
| 487 |
| 493 ChildProcessLauncherTestUtils.runOnLauncherThreadBlocking(new Runnable()
{ | 488 ChildProcessLauncherTestUtils.runOnLauncherThreadBlocking(new Runnable()
{ |
| 494 @Override | 489 @Override |
| 495 public void run() { | 490 public void run() { |
| 496 Assert.assertEquals(1, allocatedChromeSandboxedConnectionsCount(
)); | |
| 497 | |
| 498 final ChildProcessConnection conn = | |
| 499 ChildProcessLauncherTestUtils.startInternalForTesting( | |
| 500 context, new String[0], new FileDescriptorInfo[0
], null); | |
| 501 Assert.assertEquals( | |
| 502 1, allocatedChromeSandboxedConnectionsCount()); // Used
warmup connection. | |
| 503 | |
| 504 ChildProcessLauncher.stop(ChildProcessLauncherTestUtils.getConne
ctionPid(conn)); | 491 ChildProcessLauncher.stop(ChildProcessLauncherTestUtils.getConne
ctionPid(conn)); |
| 505 } | 492 } |
| 506 }); | 493 }); |
| 507 } | 494 } |
| 508 | 495 |
| 509 @Test | 496 @Test |
| 510 @MediumTest | 497 @MediumTest |
| 511 @Feature({"ProcessManagement"}) | 498 @Feature({"ProcessManagement"}) |
| 512 public void testCustomCreationParamDoesNotReuseWarmupConnection() { | 499 public void testCustomCreationParamDoesNotReuseWarmupConnection() { |
| 513 // Since warmUp only uses default params. | 500 // Since warmUp only uses default params. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 550 public boolean isSatisfied() { | 537 public boolean isSatisfied() { |
| 551 return connection.isConnected(); | 538 return connection.isConnected(); |
| 552 } | 539 } |
| 553 }); | 540 }); |
| 554 return connection; | 541 return connection; |
| 555 } | 542 } |
| 556 | 543 |
| 557 private static void startRendererProcess( | 544 private static void startRendererProcess( |
| 558 Context context, int paramId, FileDescriptorInfo[] filesToMap) { | 545 Context context, int paramId, FileDescriptorInfo[] filesToMap) { |
| 559 assert LauncherThread.runningOnLauncherThread(); | 546 assert LauncherThread.runningOnLauncherThread(); |
| 560 ChildProcessLauncher.start(context, paramId, | 547 ChildProcessLauncherHelper.createAndStart(0L /* nativePointer */, paramI
d, |
| 561 new String[] {"--" + ContentSwitches.SWITCH_PROCESS_TYPE + "=" | 548 new String[] {"--" + ContentSwitches.SWITCH_PROCESS_TYPE + "=" |
| 562 + ContentSwitches.SWITCH_RENDERER_PROCESS}, | 549 + ContentSwitches.SWITCH_RENDERER_PROCESS}, |
| 563 filesToMap, null /* launchCallback */); | 550 filesToMap); |
| 564 } | 551 } |
| 565 | 552 |
| 566 private static ChildProcessConnection allocateBoundConnectionForTesting( | 553 private static ChildProcessConnection allocateBoundConnectionForTesting( |
| 567 final Context context, final ChildProcessCreationParams creationPara
ms) { | 554 final Context context, final ChildProcessCreationParams creationPara
ms) { |
| 568 return ChildProcessLauncherTestUtils.runOnLauncherAndGetResult( | 555 return ChildProcessLauncherTestUtils.runOnLauncherAndGetResult( |
| 569 new Callable<ChildProcessConnection>() { | 556 new Callable<ChildProcessConnection>() { |
| 570 @Override | 557 @Override |
| 571 public ChildProcessConnection call() { | 558 public ChildProcessConnection call() { |
| 572 return ChildProcessLauncher.allocateBoundConnection( | 559 return ChildProcessLauncher.allocateBoundConnection( |
| 573 new ChildSpawnData(context, null /* commandLine
*/, | 560 new ChildSpawnData(context, null /* commandLine
*/, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 587 private ChildProcessConnection allocateConnection(final String packageName)
{ | 574 private ChildProcessConnection allocateConnection(final String packageName)
{ |
| 588 return ChildProcessLauncherTestUtils.runOnLauncherAndGetResult( | 575 return ChildProcessLauncherTestUtils.runOnLauncherAndGetResult( |
| 589 new Callable<ChildProcessConnection>() { | 576 new Callable<ChildProcessConnection>() { |
| 590 @Override | 577 @Override |
| 591 public ChildProcessConnection call() { | 578 public ChildProcessConnection call() { |
| 592 // Allocate a new connection. | 579 // Allocate a new connection. |
| 593 Context context = InstrumentationRegistry.getTargetConte
xt(); | 580 Context context = InstrumentationRegistry.getTargetConte
xt(); |
| 594 ChildProcessCreationParams creationParams = | 581 ChildProcessCreationParams creationParams = |
| 595 getDefaultChildProcessCreationParams(packageName
); | 582 getDefaultChildProcessCreationParams(packageName
); |
| 596 return ChildProcessLauncher.allocateConnection( | 583 return ChildProcessLauncher.allocateConnection( |
| 597 new ChildSpawnData(context, null /* commandLine
*/, | 584 new ChildSpawnData(context, null /* serviceBundl
e */, |
| 598 null /* filesToBeMapped */, null /* laun
chCallback */, | 585 null /* connectionBundle */, null /* lau
nchCallback */, |
| 599 null /* childProcessCallback */, true /*
inSandbox */, | 586 null /* childProcessCallback */, true /*
inSandbox */, |
| 600 false /* alwaysInForeground */, creation
Params), | 587 false /* alwaysInForeground */, creation
Params), |
| 601 ChildProcessLauncher.createCommonParamsBundle(cr
eationParams), | |
| 602 false /* forWarmUp */); | 588 false /* forWarmUp */); |
| 603 } | 589 } |
| 604 }); | 590 }); |
| 605 } | 591 } |
| 606 | 592 |
| 607 private static void enqueuePendingSpawnForTesting(final Context context, | 593 private static void enqueuePendingSpawnForTesting(final Context context, |
| 608 final String[] commandLine, final ChildProcessCreationParams creatio
nParams, | 594 final String[] commandLine, final ChildProcessCreationParams creatio
nParams, |
| 609 final boolean inSandbox) { | 595 final boolean inSandbox) { |
| 610 ChildProcessLauncherTestUtils.runOnLauncherThreadBlocking(new Runnable()
{ | 596 ChildProcessLauncherTestUtils.runOnLauncherThreadBlocking(new Runnable()
{ |
| 611 @Override | 597 @Override |
| 612 public void run() { | 598 public void run() { |
| 613 String packageName = creationParams != null ? creationParams.get
PackageName() | 599 String packageName = creationParams != null ? creationParams.get
PackageName() |
| 614 : context.getPackage
Name(); | 600 : context.getPackage
Name(); |
| 615 ChildConnectionAllocator allocator = ChildProcessLauncher.getCon
nectionAllocator( | 601 ChildConnectionAllocator allocator = ChildProcessLauncher.getCon
nectionAllocator( |
| 616 context, packageName, inSandbox); | 602 context, packageName, inSandbox); |
| 617 allocator.enqueuePendingQueueForTesting(new ChildSpawnData(conte
xt, commandLine, | 603 |
| 618 new FileDescriptorInfo[0], null /* launchCallback */, | 604 allocator.enqueuePendingQueueForTesting(new ChildSpawnData(conte
xt, |
| 619 null /* childProcessCallback */, true /* inSandbox */, | 605 null /* serviceBundle */, null /* connectionBundle */, |
| 620 false /* alwaysInForeground */, creationParams)); | 606 null /* launchCallback */, null /* childProcessCallback
*/, |
| 607 true /* inSandbox */, false /* alwaysInForeground */, cr
eationParams)); |
| 621 } | 608 } |
| 622 }); | 609 }); |
| 623 } | 610 } |
| 624 | 611 |
| 625 private static int allocatedSandboxedConnectionsCountForTesting( | 612 private static int allocatedSandboxedConnectionsCountForTesting( |
| 626 final Context context, final String packageName) { | 613 final Context context, final String packageName) { |
| 627 return ChildProcessLauncherTestUtils.runOnLauncherAndGetResult( | 614 return ChildProcessLauncherTestUtils.runOnLauncherAndGetResult( |
| 628 new Callable<Integer>() { | 615 new Callable<Integer>() { |
| 629 @Override | 616 @Override |
| 630 public Integer call() { | 617 public Integer call() { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 671 | 658 |
| 672 private ChildProcessCreationParams getDefaultChildProcessCreationParams(Stri
ng packageName) { | 659 private ChildProcessCreationParams getDefaultChildProcessCreationParams(Stri
ng packageName) { |
| 673 return new ChildProcessCreationParams(packageName, false /* isExternalSe
rvice */, | 660 return new ChildProcessCreationParams(packageName, false /* isExternalSe
rvice */, |
| 674 LibraryProcessType.PROCESS_CHILD, false /* bindToCallerCheck */)
; | 661 LibraryProcessType.PROCESS_CHILD, false /* bindToCallerCheck */)
; |
| 675 } | 662 } |
| 676 | 663 |
| 677 private void triggerConnectionSetup(final ChildProcessConnection connection)
{ | 664 private void triggerConnectionSetup(final ChildProcessConnection connection)
{ |
| 678 ChildProcessLauncherTestUtils.runOnLauncherThreadBlocking(new Runnable()
{ | 665 ChildProcessLauncherTestUtils.runOnLauncherThreadBlocking(new Runnable()
{ |
| 679 @Override | 666 @Override |
| 680 public void run() { | 667 public void run() { |
| 681 ChildProcessLauncher.triggerConnectionSetup(connection, sProcess
WaitArguments, | 668 Bundle connectionBundle = ChildProcessLauncherHelper.createConne
ctionBundle( |
| 682 new FileDescriptorInfo[0], null /* launchCallback */, | 669 sProcessWaitArguments, new FileDescriptorInfo[0]); |
| 683 null /* childProcessCallback */, true /* addToBindingMan
ager */); | 670 ChildProcessLauncher.triggerConnectionSetup(connection, connecti
onBundle, |
| 671 null /* launchCallback */, null /* childProcessCallback
*/, |
| 672 true /* addToBindingmanager */); |
| 684 } | 673 } |
| 685 }); | 674 }); |
| 686 } | 675 } |
| 676 |
| 677 private static ChildProcessConnection retrieveConnection( |
| 678 final ChildProcessLauncherHelper launcherHelper) { |
| 679 CriteriaHelper.pollInstrumentationThread( |
| 680 new Criteria("Failed waiting for child process to connect") { |
| 681 @Override |
| 682 public boolean isSatisfied() { |
| 683 return ChildProcessLauncherTestUtils.getConnection(launc
herHelper) != null; |
| 684 } |
| 685 }); |
| 686 |
| 687 return ChildProcessLauncherTestUtils.getConnection(launcherHelper); |
| 688 } |
| 687 } | 689 } |
| OLD | NEW |