1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.contacts.interactions;
18 
19 import android.app.LoaderManager;
20 
21 import com.google.common.annotations.VisibleForTesting;
22 
23 /**
24  * A {@link LoaderManager} that records which loaders have been completed.
25  * <p>
26  * You should wrap the existing LoaderManager with an instance of this class, which will then
27  * delegate to the original object.
28  * <p>
29  * Typically, one would override {@link android.app.Activity#getLoaderManager()} to return the
30  * TestLoaderManager and ensuring it wraps the {@link LoaderManager} for this object, e.g.:
31  * <pre>
32  *   private TestLoaderManager mTestLoaderManager;
33  *
34  *   public LoaderManager getLoaderManager() {
35  *     LoaderManager loaderManager = super.getLoaderManager();
36  *     if (mTestLoaderManager != null) {
37  *       mTestLoaderManager.setDelegate(loaderManager);
38  *       return mTestLoaderManager;
39  *     } else {
40  *       return loaderManager;
41  *     }
42  *   }
43  *
44  *   void setTestLoaderManager(TestLoaderManager testLoaderManager) {
45  *     mTestLoaderManager = testLoaderManager;
46  *   }
47  * </pre>
48  * In the tests, one would set the TestLoaderManager upon creating the activity, and then wait for
49  * the loader to complete.
50  * <pre>
51  *   public void testLoadedCorrect() {
52  *     TestLoaderManager testLoaderManager = new TestLoaderManager();
53  *     getActivity().setTestLoaderManager(testLoaderManager);
54  *     runOnUiThread(new Runnable() { public void run() { getActivity().startLoading(); } });
55  *     testLoaderManager.waitForLoader(R.id.test_loader_id);
56  *   }
57  * </pre>
58  * If the loader completes before the call to {@link #waitForLoaders(int...)}, the TestLoaderManager
59  * will have stored the fact that the loader has completed and correctly terminate immediately.
60  * <p>
61  * It one needs to wait for the same loader multiple times, call {@link #reset()} between the them
62  * as in:
63  * <pre>
64  *   public void testLoadedCorrect() {
65  *     TestLoaderManager testLoaderManager = new TestLoaderManager();
66  *     getActivity().setTestLoaderManager(testLoaderManager);
67  *     runOnUiThread(new Runnable() { public void run() { getActivity().startLoading(); } });
68  *     testLoaderManager.waitForLoader(R.id.test_loader_id);
69  *     testLoaderManager.reset();
70  *     // Load and wait again.
71  *     runOnUiThread(new Runnable() { public void run() { getActivity().startLoading(); } });
72  *     testLoaderManager.waitForLoader(R.id.test_loader_id);
73  *   }
74  * </pre>
75  */
76 @VisibleForTesting
77 abstract class TestLoaderManagerBase extends LoaderManager {
78 
79     /**
80      * Waits for the specified loaders to complete loading.
81      */
waitForLoaders(int... loaderIds)82     public abstract void waitForLoaders(int... loaderIds);
83 
84     /**
85      * Sets the object to which we delegate the actual work.
86      * <p>
87      * It can not be set to null. Once set, it cannot be changed (but it allows setting it to the
88      * same value again).
89      */
90     @VisibleForTesting
setDelegate(LoaderManager delegate)91     public abstract void setDelegate(LoaderManager delegate);
92 
93 }
94