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