| 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 static android.content.ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; | 
|  | 8 import static android.content.ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; | 
|  | 9 import static android.content.ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; | 
|  | 10 | 
|  | 11 import android.app.Application; | 
| 7 import android.os.Bundle; | 12 import android.os.Bundle; | 
| 8 import android.test.InstrumentationTestCase; | 13 import android.test.InstrumentationTestCase; | 
| 9 import android.test.suitebuilder.annotation.SmallTest; | 14 import android.test.suitebuilder.annotation.SmallTest; | 
|  | 15 import android.util.Pair; | 
| 10 | 16 | 
| 11 import org.chromium.base.test.util.Feature; | 17 import org.chromium.base.test.util.Feature; | 
| 12 import org.chromium.content.common.IChildProcessCallback; | 18 import org.chromium.content.common.IChildProcessCallback; | 
| 13 import org.chromium.content.common.IChildProcessService; | 19 import org.chromium.content.common.IChildProcessService; | 
| 14 | 20 | 
|  | 21 import java.util.ArrayList; | 
|  | 22 | 
| 15 /** | 23 /** | 
| 16  * Unit tests for BindingManagerImpl. The tests run agains mock ChildProcessConn
     ection | 24  * Unit tests for BindingManagerImpl. The tests run agains mock ChildProcessConn
     ection | 
| 17  * implementation, thus testing only the BindingManagerImpl itself. | 25  * implementation, thus testing only the BindingManagerImpl itself. | 
| 18  * | 26  * | 
| 19  * Default property of being low-end device is overriden, so that both low-end a
     nd high-end policies | 27  * Default property of being low-end device is overriden, so that both low-end a
     nd high-end policies | 
| 20  * are tested. Unbinding delays are set to 0, so that we don't need to deal with
      waiting, but we | 28  * are tested. Unbinding delays are set to 0, so that we don't need to deal with
      waiting, but we | 
| 21  * still can test if the unbinding tasks are posted or executed synchronously. | 29  * still can test if the unbinding tasks are posted or executed synchronously. | 
| 22  */ | 30  */ | 
| 23 public class BindingManagerImplTest extends InstrumentationTestCase { | 31 public class BindingManagerImplTest extends InstrumentationTestCase { | 
| 24     private static class MockChildProcessConnection implements ChildProcessConne
     ction { | 32     private static class MockChildProcessConnection implements ChildProcessConne
     ction { | 
| 25         boolean mInitialBindingBound; | 33         boolean mInitialBindingBound; | 
|  | 34         boolean mModerateBindingBound; | 
| 26         int mStrongBindingCount; | 35         int mStrongBindingCount; | 
| 27         final int mPid; | 36         final int mPid; | 
| 28 | 37 | 
| 29         /** | 38         /** | 
| 30          * Creates a mock binding corresponding to real ChildProcessConnectionIm
     pl after the | 39          * Creates a mock binding corresponding to real ChildProcessConnectionIm
     pl after the | 
| 31          * connection is established: with initial binding bound and no strong b
     inding. | 40          * connection is established: with initial binding bound and no strong b
     inding. | 
| 32          */ | 41          */ | 
| 33         MockChildProcessConnection(int pid) { | 42         MockChildProcessConnection(int pid) { | 
| 34             mInitialBindingBound = true; | 43             mInitialBindingBound = true; | 
| 35             mStrongBindingCount = 0; | 44             mStrongBindingCount = 0; | 
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 79         } | 88         } | 
| 80 | 89 | 
| 81         @Override | 90         @Override | 
| 82         public void stop() { | 91         public void stop() { | 
| 83             mInitialBindingBound = false; | 92             mInitialBindingBound = false; | 
| 84             mStrongBindingCount = 0; | 93             mStrongBindingCount = 0; | 
| 85         } | 94         } | 
| 86 | 95 | 
| 87         @Override | 96         @Override | 
| 88         public int getServiceNumber() { | 97         public int getServiceNumber() { | 
| 89             throw new UnsupportedOperationException(); | 98             return mPid; | 
| 90         } | 99         } | 
| 91 | 100 | 
| 92         @Override | 101         @Override | 
| 93         public boolean isInSandbox() { | 102         public boolean isInSandbox() { | 
| 94             throw new UnsupportedOperationException(); | 103             return true; | 
| 95         } | 104         } | 
| 96 | 105 | 
| 97         @Override | 106         @Override | 
| 98         public IChildProcessService getService() { | 107         public IChildProcessService getService() { | 
| 99             throw new UnsupportedOperationException(); | 108             throw new UnsupportedOperationException(); | 
| 100         } | 109         } | 
| 101 | 110 | 
| 102         @Override | 111         @Override | 
| 103         public void start(String[] commandLine) { | 112         public void start(String[] commandLine) { | 
| 104             throw new UnsupportedOperationException(); | 113             throw new UnsupportedOperationException(); | 
| 105         } | 114         } | 
| 106 | 115 | 
| 107         @Override | 116         @Override | 
| 108         public void setupConnection(String[] commandLine, FileDescriptorInfo[] f
     ilesToBeMapped, | 117         public void setupConnection(String[] commandLine, FileDescriptorInfo[] f
     ilesToBeMapped, | 
| 109                 IChildProcessCallback processCallback, ConnectionCallback connec
     tionCallbacks, | 118                 IChildProcessCallback processCallback, ConnectionCallback connec
     tionCallbacks, | 
| 110                 Bundle sharedRelros) { | 119                 Bundle sharedRelros) { | 
| 111             throw new UnsupportedOperationException(); | 120             throw new UnsupportedOperationException(); | 
| 112         } | 121         } | 
|  | 122 | 
|  | 123         @Override | 
|  | 124         public void addModerateBinding() { | 
|  | 125             mModerateBindingBound = true; | 
|  | 126         } | 
|  | 127 | 
|  | 128         @Override | 
|  | 129         public void removeModerateBinding() { | 
|  | 130             mModerateBindingBound = false; | 
|  | 131         } | 
|  | 132 | 
|  | 133         @Override | 
|  | 134         public boolean isModerateBindingBound() { | 
|  | 135             return mModerateBindingBound; | 
|  | 136         } | 
| 113     } | 137     } | 
| 114 | 138 | 
| 115     /** | 139     /** | 
| 116      * Helper class that stores a manager along with its text label. This is use
     d for tests that | 140      * Helper class that stores a manager along with its text label. This is use
     d for tests that | 
| 117      * iterate over all managers to indicate which manager was being tested when
      an assertion | 141      * iterate over all managers to indicate which manager was being tested when
      an assertion | 
| 118      * failed. | 142      * failed. | 
| 119      */ | 143      */ | 
| 120     private static class ManagerEntry { | 144     private static class ManagerEntry { | 
| 121         BindingManagerImpl mManager; | 145         BindingManagerImpl mManager; | 
| 122         String mLabel;  // Name of the manager. | 146         String mLabel;  // Name of the manager. | 
| 123 | 147 | 
| 124         ManagerEntry(BindingManagerImpl manager, String label) { | 148         ManagerEntry(BindingManagerImpl manager, String label) { | 
| 125             mManager = manager; | 149             mManager = manager; | 
| 126             mLabel = label; | 150             mLabel = label; | 
| 127         } | 151         } | 
| 128 | 152 | 
| 129         String getErrorMessage() { | 153         String getErrorMessage() { | 
| 130             return "Failed for the " + mLabel + " manager."; | 154             return "Failed for the " + mLabel + " manager."; | 
| 131         } | 155         } | 
| 132     } | 156     } | 
| 133 | 157 | 
| 134     // The managers are created in setUp() for convenience. | 158     // The managers are created in setUp() for convenience. | 
| 135     BindingManagerImpl mLowEndManager; | 159     BindingManagerImpl mLowEndManager; | 
| 136     BindingManagerImpl mHighEndManager; | 160     BindingManagerImpl mHighEndManager; | 
|  | 161     BindingManagerImpl mModerateBindingManager; | 
| 137     ManagerEntry[] mAllManagers; | 162     ManagerEntry[] mAllManagers; | 
| 138 | 163 | 
| 139     @Override | 164     @Override | 
| 140     protected void setUp() { | 165     protected void setUp() { | 
| 141         mLowEndManager = BindingManagerImpl.createBindingManagerForTesting(true)
     ; | 166         mLowEndManager = BindingManagerImpl.createBindingManagerForTesting(true)
     ; | 
| 142         mHighEndManager = BindingManagerImpl.createBindingManagerForTesting(fals
     e); | 167         mHighEndManager = BindingManagerImpl.createBindingManagerForTesting(fals
     e); | 
|  | 168         mModerateBindingManager = BindingManagerImpl.createBindingManagerForTest
     ing(false); | 
|  | 169         mModerateBindingManager.startModerateBindingManagement( | 
|  | 170                 getInstrumentation().getTargetContext(), 4, 0.25f, 0.5f); | 
| 143         mAllManagers = new ManagerEntry[] { | 171         mAllManagers = new ManagerEntry[] { | 
| 144             new ManagerEntry(mLowEndManager, "low-end"), | 172                 new ManagerEntry(mLowEndManager, "low-end"), | 
| 145             new ManagerEntry(mHighEndManager, "high-end")}; | 173                 new ManagerEntry(mHighEndManager, "high-end"), | 
|  | 174                 new ManagerEntry(mModerateBindingManager, "moderate-binding")}; | 
| 146     } | 175     } | 
| 147 | 176 | 
| 148     /** | 177     /** | 
| 149      * Verifies that when running on low-end, the binding manager drops the oom 
     bindings for the | 178      * Verifies that when running on low-end, the binding manager drops the oom 
     bindings for the | 
| 150      * previously bound connection when a new connection is used in foreground. | 179      * previously bound connection when a new connection is used in foreground. | 
| 151      */ | 180      */ | 
| 152     @SmallTest | 181     @SmallTest | 
| 153     @Feature({"ProcessManagement"}) | 182     @Feature({"ProcessManagement"}) | 
| 154     public void testNewConnectionDropsPreviousOnLowEnd() { | 183     public void testNewConnectionDropsPreviousOnLowEnd() { | 
| 155         // This test applies only to the low-end manager. | 184         // This test applies only to the low-end manager. | 
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 247 | 276 | 
| 248         // Wait until the posted unbinding tasks get executed and verify that th
     e strong binding was | 277         // Wait until the posted unbinding tasks get executed and verify that th
     e strong binding was | 
| 249         // removed while the initial binding is not affected. Note that this wor
     ks only because the | 278         // removed while the initial binding is not affected. Note that this wor
     ks only because the | 
| 250         // test binding manager has the unbinding delay set to 0. | 279         // test binding manager has the unbinding delay set to 0. | 
| 251         getInstrumentation().waitForIdleSync(); | 280         getInstrumentation().waitForIdleSync(); | 
| 252         assertFalse(connection.isStrongBindingBound()); | 281         assertFalse(connection.isStrongBindingBound()); | 
| 253         assertTrue(connection.isInitialBindingBound()); | 282         assertTrue(connection.isInitialBindingBound()); | 
| 254     } | 283     } | 
| 255 | 284 | 
| 256     /** | 285     /** | 
|  | 286      * Verifies the strong binding removal policies with moderate binding manage
     ment, where the | 
|  | 287      * moderate binding should be bound. | 
|  | 288      */ | 
|  | 289     @SmallTest | 
|  | 290     @Feature({"ProcessManagement"}) | 
|  | 291     public void testStrongBindingRemovalWithModerateBinding() throws Throwable { | 
|  | 292         // This test applies only to the moderate-binding manager. | 
|  | 293         final BindingManagerImpl manager = mModerateBindingManager; | 
|  | 294 | 
|  | 295         // Add a connection to the manager. | 
|  | 296         final MockChildProcessConnection connection = new MockChildProcessConnec
     tion(1); | 
|  | 297         manager.addNewConnection(connection.getPid(), connection); | 
|  | 298         assertTrue(connection.isInitialBindingBound()); | 
|  | 299         assertFalse(connection.isStrongBindingBound()); | 
|  | 300         assertFalse(connection.isModerateBindingBound()); | 
|  | 301         // This has to happen on the UI thread, so that we can check the binding
      status right after | 
|  | 302         // the call to remove it, before the any other task is executed on the m
     ain thread. | 
|  | 303         runTestOnUiThread(new Runnable() { | 
|  | 304             @Override | 
|  | 305             public void run() { | 
|  | 306                 // Add a strong binding, verify that the initial binding is not 
     removed. | 
|  | 307                 manager.setInForeground(connection.getPid(), true); | 
|  | 308                 assertTrue(connection.isStrongBindingBound()); | 
|  | 309                 assertTrue(connection.isInitialBindingBound()); | 
|  | 310                 assertFalse(connection.isModerateBindingBound()); | 
|  | 311 | 
|  | 312                 // Remove the strong binding, verify that the strong binding is 
     not removed | 
|  | 313                 // immediately. | 
|  | 314                 manager.setInForeground(connection.getPid(), false); | 
|  | 315                 assertTrue(connection.isStrongBindingBound()); | 
|  | 316                 assertTrue(connection.isInitialBindingBound()); | 
|  | 317                 assertFalse(connection.isModerateBindingBound()); | 
|  | 318             } | 
|  | 319         }); | 
|  | 320 | 
|  | 321         // Wait until the posted unbinding tasks get executed and verify that th
     e strong binding was | 
|  | 322         // removed while the initial binding is not affected, and the moderate b
     inding is bound. | 
|  | 323         getInstrumentation().waitForIdleSync(); | 
|  | 324         assertFalse(connection.isStrongBindingBound()); | 
|  | 325         assertTrue(connection.isInitialBindingBound()); | 
|  | 326         assertTrue(connection.isModerateBindingBound()); | 
|  | 327     } | 
|  | 328 | 
|  | 329     /** | 
| 257      * Verifies that the initial binding is removed after determinedVisibility()
      is called. | 330      * Verifies that the initial binding is removed after determinedVisibility()
      is called. | 
| 258      */ | 331      */ | 
| 259     @SmallTest | 332     @SmallTest | 
| 260     @Feature({"ProcessManagement"}) | 333     @Feature({"ProcessManagement"}) | 
| 261     public void testInitialBindingRemoval() { | 334     public void testInitialBindingRemoval() { | 
| 262         // This test applies to both low-end and high-end policies. | 335         // This test applies to low-end, high-end and moderate-binding policies. | 
| 263         for (ManagerEntry managerEntry : mAllManagers) { | 336         for (ManagerEntry managerEntry : mAllManagers) { | 
| 264             BindingManagerImpl manager = managerEntry.mManager; | 337             BindingManagerImpl manager = managerEntry.mManager; | 
| 265             String message = managerEntry.getErrorMessage(); | 338             String message = managerEntry.getErrorMessage(); | 
| 266 | 339 | 
| 267             // Add a connection to the manager. | 340             // Add a connection to the manager. | 
| 268             MockChildProcessConnection connection = new MockChildProcessConnecti
     on(1); | 341             MockChildProcessConnection connection = new MockChildProcessConnecti
     on(1); | 
| 269             manager.addNewConnection(connection.getPid(), connection); | 342             manager.addNewConnection(connection.getPid(), connection); | 
| 270 | 343 | 
| 271             // Verify that the initial binding is held. | 344             // Verify that the initial binding is held. | 
| 272             assertTrue(connection.isInitialBindingBound()); | 345             assertTrue(connection.isInitialBindingBound()); | 
| 273 | 346 | 
| 274             // Call determinedVisibility() and verify that the initial binding w
     as released. | 347             // Call determinedVisibility() and verify that the initial binding w
     as released. | 
| 275             manager.determinedVisibility(connection.getPid()); | 348             manager.determinedVisibility(connection.getPid()); | 
| 276             assertFalse(connection.isInitialBindingBound()); | 349             assertFalse(connection.isInitialBindingBound()); | 
| 277         } | 350         } | 
| 278     } | 351     } | 
| 279 | 352 | 
| 280     /** | 353     /** | 
| 281      * Verifies that BindingManagerImpl correctly stashes the status of the conn
     ection oom bindings | 354      * Verifies that BindingManagerImpl correctly stashes the status of the conn
     ection oom bindings | 
| 282      * when the connection is cleared. BindingManagerImpl should reply to isOomP
     rotected() queries | 355      * when the connection is cleared. BindingManagerImpl should reply to isOomP
     rotected() queries | 
| 283      * with live status of the connection while it's still around and reply with
      stashed status | 356      * with live status of the connection while it's still around and reply with
      stashed status | 
| 284      * after clearConnection() is called. | 357      * after clearConnection() is called. | 
| 285      * | 358      * | 
| 286      * This test corresponds to a process crash scenario: after a process dies a
     nd its connection is | 359      * This test corresponds to a process crash scenario: after a process dies a
     nd its connection is | 
| 287      * cleared, isOomProtected() may be called to decide if it was a crash or ou
     t-of-memory kill. | 360      * cleared, isOomProtected() may be called to decide if it was a crash or ou
     t-of-memory kill. | 
| 288      */ | 361      */ | 
| 289     @SmallTest | 362     @SmallTest | 
| 290     @Feature({"ProcessManagement"}) | 363     @Feature({"ProcessManagement"}) | 
| 291     public void testIsOomProtected() { | 364     public void testIsOomProtected() { | 
| 292         // This test applies to both low-end and high-end policies. | 365         // This test applies to low-end, high-end and moderate-binding policies. | 
| 293         for (ManagerEntry managerEntry : mAllManagers) { | 366         for (ManagerEntry managerEntry : mAllManagers) { | 
| 294             BindingManagerImpl manager = managerEntry.mManager; | 367             BindingManagerImpl manager = managerEntry.mManager; | 
| 295             String message = managerEntry.getErrorMessage(); | 368             String message = managerEntry.getErrorMessage(); | 
| 296 | 369 | 
| 297             // Add a connection to the manager. | 370             // Add a connection to the manager. | 
| 298             MockChildProcessConnection connection = new MockChildProcessConnecti
     on(1); | 371             MockChildProcessConnection connection = new MockChildProcessConnecti
     on(1); | 
| 299             manager.addNewConnection(connection.getPid(), connection); | 372             manager.addNewConnection(connection.getPid(), connection); | 
| 300 | 373 | 
| 301             // Initial binding is an oom binding. | 374             // Initial binding is an oom binding. | 
| 302             assertTrue(message, manager.isOomProtected(connection.getPid())); | 375             assertTrue(message, manager.isOomProtected(connection.getPid())); | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
| 332      * period. | 405      * period. | 
| 333      * | 406      * | 
| 334      * The renderer that will be bound for the background period should be the o
     ne that was most | 407      * The renderer that will be bound for the background period should be the o
     ne that was most | 
| 335      * recendly bound using .setInForeground(), even if there is one that was ad
     ded using | 408      * recendly bound using .setInForeground(), even if there is one that was ad
     ded using | 
| 336      * .addNewConnection() after that. Otherwise we would bound a background ren
     derer when user | 409      * .addNewConnection() after that. Otherwise we would bound a background ren
     derer when user | 
| 337      * loads a new tab in background and leaves the browser. | 410      * loads a new tab in background and leaves the browser. | 
| 338      */ | 411      */ | 
| 339     @SmallTest | 412     @SmallTest | 
| 340     @Feature({"ProcessManagement"}) | 413     @Feature({"ProcessManagement"}) | 
| 341     public void testBackgroundPeriodBinding() { | 414     public void testBackgroundPeriodBinding() { | 
| 342         // This test applies to both low-end and high-end policies. | 415         // This test applies to low-end, high-end and moderate-binding policies. | 
| 343         for (ManagerEntry managerEntry : mAllManagers) { | 416         for (ManagerEntry managerEntry : mAllManagers) { | 
| 344             BindingManagerImpl manager = managerEntry.mManager; | 417             BindingManagerImpl manager = managerEntry.mManager; | 
| 345             String message = managerEntry.getErrorMessage(); | 418             String message = managerEntry.getErrorMessage(); | 
| 346 | 419 | 
| 347             // Add two connections, bind and release each. | 420             // Add two connections, bind and release each. | 
| 348             MockChildProcessConnection firstConnection = new MockChildProcessCon
     nection(1); | 421             MockChildProcessConnection firstConnection = new MockChildProcessCon
     nection(1); | 
| 349             manager.addNewConnection(firstConnection.getPid(), firstConnection); | 422             manager.addNewConnection(firstConnection.getPid(), firstConnection); | 
| 350             manager.setInForeground(firstConnection.getPid(), true); | 423             manager.setInForeground(firstConnection.getPid(), true); | 
| 351             manager.setInForeground(firstConnection.getPid(), false); | 424             manager.setInForeground(firstConnection.getPid(), false); | 
| 352 | 425 | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
| 376             assertFalse(message, thirdConnection.isStrongBindingBound()); | 449             assertFalse(message, thirdConnection.isStrongBindingBound()); | 
| 377 | 450 | 
| 378             // Call onBroughtToForeground() and verify that the strong binding w
     as removed. | 451             // Call onBroughtToForeground() and verify that the strong binding w
     as removed. | 
| 379             manager.onBroughtToForeground(); | 452             manager.onBroughtToForeground(); | 
| 380             getInstrumentation().waitForIdleSync(); | 453             getInstrumentation().waitForIdleSync(); | 
| 381             assertFalse(message, firstConnection.isStrongBindingBound()); | 454             assertFalse(message, firstConnection.isStrongBindingBound()); | 
| 382             assertFalse(message, secondConnection.isStrongBindingBound()); | 455             assertFalse(message, secondConnection.isStrongBindingBound()); | 
| 383             assertFalse(message, thirdConnection.isStrongBindingBound()); | 456             assertFalse(message, thirdConnection.isStrongBindingBound()); | 
| 384         } | 457         } | 
| 385     } | 458     } | 
|  | 459 | 
|  | 460     /** | 
|  | 461      * Verifies that onSentToBackground() drops all the moderate bindings, and | 
|  | 462      * onBroughtToForeground() doesn't recover them. | 
|  | 463      */ | 
|  | 464     @SmallTest | 
|  | 465     @Feature({"ProcessManagement"}) | 
|  | 466     public void testModerateBindingDropOnBackground() { | 
|  | 467         // This test applies only to the moderate-binding manager. | 
|  | 468         final BindingManagerImpl manager = mModerateBindingManager; | 
|  | 469 | 
|  | 470         MockChildProcessConnection[] connections = new MockChildProcessConnectio
     n[4]; | 
|  | 471         for (int i = 0; i < connections.length; i++) { | 
|  | 472             connections[i] = new MockChildProcessConnection(i + 1); | 
|  | 473             manager.addNewConnection(connections[i].getPid(), connections[i]); | 
|  | 474         } | 
|  | 475 | 
|  | 476         // Verify that each connection has a moderate binding after binding and 
     releasing a strong | 
|  | 477         // binding. | 
|  | 478         for (MockChildProcessConnection connection : connections) { | 
|  | 479             manager.setInForeground(connection.getPid(), true); | 
|  | 480             manager.setInForeground(connection.getPid(), false); | 
|  | 481             getInstrumentation().waitForIdleSync(); | 
|  | 482             assertTrue(connection.isModerateBindingBound()); | 
|  | 483         } | 
|  | 484 | 
|  | 485         // Call onSentToBackground() and verify that all the moderate bindings d
     rop. | 
|  | 486         manager.onSentToBackground(); | 
|  | 487         for (MockChildProcessConnection connection : connections) { | 
|  | 488             assertFalse(connection.isModerateBindingBound()); | 
|  | 489         } | 
|  | 490 | 
|  | 491         // Call onBroughtToForeground() and verify that the previous moderate bi
     ndings aren't | 
|  | 492         // recovered. | 
|  | 493         manager.onBroughtToForeground(); | 
|  | 494         for (MockChildProcessConnection connection : connections) { | 
|  | 495             assertFalse(connection.isModerateBindingBound()); | 
|  | 496         } | 
|  | 497     } | 
|  | 498 | 
|  | 499     /** | 
|  | 500      * Verifies that onLowMemory() drops all the moderate bindings. | 
|  | 501      */ | 
|  | 502     @SmallTest | 
|  | 503     @Feature({"ProcessManagement"}) | 
|  | 504     public void testModerateBindingDropOnLowMemory() { | 
|  | 505         final Application app = | 
|  | 506                 (Application) getInstrumentation().getTargetContext().getApplica
     tionContext(); | 
|  | 507         // This test applies only to the moderate-binding manager. | 
|  | 508         final BindingManagerImpl manager = mModerateBindingManager; | 
|  | 509 | 
|  | 510         MockChildProcessConnection[] connections = new MockChildProcessConnectio
     n[4]; | 
|  | 511         for (int i = 0; i < connections.length; i++) { | 
|  | 512             connections[i] = new MockChildProcessConnection(i + 1); | 
|  | 513             manager.addNewConnection(connections[i].getPid(), connections[i]); | 
|  | 514         } | 
|  | 515 | 
|  | 516         // Verify that each connection has a moderate binding after binding and 
     releasing a strong | 
|  | 517         // binding. | 
|  | 518         for (MockChildProcessConnection connection : connections) { | 
|  | 519             manager.setInForeground(connection.getPid(), true); | 
|  | 520             manager.setInForeground(connection.getPid(), false); | 
|  | 521             getInstrumentation().waitForIdleSync(); | 
|  | 522             assertTrue(connection.isModerateBindingBound()); | 
|  | 523         } | 
|  | 524 | 
|  | 525         // Call onLowMemory() and verify that all the moderate bindings drop. | 
|  | 526         app.onLowMemory(); | 
|  | 527         for (MockChildProcessConnection connection : connections) { | 
|  | 528             assertFalse(connection.isModerateBindingBound()); | 
|  | 529         } | 
|  | 530     } | 
|  | 531 | 
|  | 532     /** | 
|  | 533      * Verifies that onTrimMemory() drops moderate bindings properly. | 
|  | 534      */ | 
|  | 535     @SmallTest | 
|  | 536     @Feature({"ProcessManagement"}) | 
|  | 537     public void testModerateBindingDropOnTrimMemory() { | 
|  | 538         final Application app = | 
|  | 539                 (Application) getInstrumentation().getTargetContext().getApplica
     tionContext(); | 
|  | 540         // This test applies only to the moderate-binding manager. | 
|  | 541         final BindingManagerImpl manager = mModerateBindingManager; | 
|  | 542 | 
|  | 543         ArrayList<Pair<Integer, Integer>> levelAndExpectedVictimCountList = | 
|  | 544                 new ArrayList<Pair<Integer, Integer>>(); | 
|  | 545         levelAndExpectedVictimCountList.add( | 
|  | 546                 new Pair<Integer, Integer>(TRIM_MEMORY_RUNNING_MODERATE, 1)); | 
|  | 547         levelAndExpectedVictimCountList.add(new Pair<Integer, Integer>(TRIM_MEMO
     RY_RUNNING_LOW, 2)); | 
|  | 548         levelAndExpectedVictimCountList.add( | 
|  | 549                 new Pair<Integer, Integer>(TRIM_MEMORY_RUNNING_CRITICAL, 4)); | 
|  | 550 | 
|  | 551         MockChildProcessConnection[] connections = new MockChildProcessConnectio
     n[4]; | 
|  | 552         for (int i = 0; i < connections.length; i++) { | 
|  | 553             connections[i] = new MockChildProcessConnection(i + 1); | 
|  | 554             manager.addNewConnection(connections[i].getPid(), connections[i]); | 
|  | 555         } | 
|  | 556 | 
|  | 557         for (Pair<Integer, Integer> pair : levelAndExpectedVictimCountList) { | 
|  | 558             String message = String.format("Failed for the level=%d", pair.first
     ); | 
|  | 559             // Verify that each connection has a moderate binding after binding 
     and releasing a | 
|  | 560             // strong binding. | 
|  | 561             for (MockChildProcessConnection connection : connections) { | 
|  | 562                 manager.setInForeground(connection.getPid(), true); | 
|  | 563                 manager.setInForeground(connection.getPid(), false); | 
|  | 564                 getInstrumentation().waitForIdleSync(); | 
|  | 565                 assertTrue(message, connection.isModerateBindingBound()); | 
|  | 566             } | 
|  | 567 | 
|  | 568             app.onTrimMemory(pair.first); | 
|  | 569             // Verify that some of moderate bindings drop. | 
|  | 570             for (int i = 0; i < connections.length; i++) { | 
|  | 571                 assertEquals(message, i >= pair.second, connections[i].isModerat
     eBindingBound()); | 
|  | 572             } | 
|  | 573         } | 
|  | 574     } | 
| 386 } | 575 } | 
| OLD | NEW | 
|---|