ServiceTestCase.java revision 7aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.test;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.Application;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.Service;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ComponentName;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.test.mock.MockApplication;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.lang.reflect.Field;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Random;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This test case provides a framework in which you can test Service classes in
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a controlled environment.  It provides basic support for the lifecycle of a
347d433aabb731a790fc8d06d260c826751215113fJoe Malin * Service, and hooks with which you can inject various dependencies and control
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the environment in which your Service is tested.
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p><b>Lifecycle Support.</b>
387d433aabb731a790fc8d06d260c826751215113fJoe Malin * A Service is accessed with a specific sequence of
397aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main * calls, as described in the
407aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main * <a href="http://developer.android.com/guide/topics/fundamentals/services.html">Services</a>
417aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main * document. In order to support the lifecycle of a Service,
427d433aabb731a790fc8d06d260c826751215113fJoe Malin * <code>ServiceTestCase</code> enforces this protocol:
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
447d433aabb731a790fc8d06d260c826751215113fJoe Malin * <ul>
457d433aabb731a790fc8d06d260c826751215113fJoe Malin *      <li>
467d433aabb731a790fc8d06d260c826751215113fJoe Malin *          The {@link #setUp()} method is called before each test method. The base implementation
477d433aabb731a790fc8d06d260c826751215113fJoe Malin *          gets the system context. If you override <code>setUp()</code>, you must call
487d433aabb731a790fc8d06d260c826751215113fJoe Malin *          <code>super.setUp()</code> as the first statement in your override.
497d433aabb731a790fc8d06d260c826751215113fJoe Malin *      </li>
507d433aabb731a790fc8d06d260c826751215113fJoe Malin *      <li>
517d433aabb731a790fc8d06d260c826751215113fJoe Malin *          The test case waits to call {@link android.app.Service#onCreate()} until one of your
527d433aabb731a790fc8d06d260c826751215113fJoe Malin *          test methods calls {@link #startService} or {@link #bindService}.  This gives you an
537d433aabb731a790fc8d06d260c826751215113fJoe Malin *          opportunity to set up or adjust any additional framework or test logic before you test
547d433aabb731a790fc8d06d260c826751215113fJoe Malin *          the running service.
557d433aabb731a790fc8d06d260c826751215113fJoe Malin *      </li>
567d433aabb731a790fc8d06d260c826751215113fJoe Malin *      <li>
577d433aabb731a790fc8d06d260c826751215113fJoe Malin *          When one of your test methods calls {@link #startService ServiceTestCase.startService()}
587d433aabb731a790fc8d06d260c826751215113fJoe Malin *          or {@link #bindService  ServiceTestCase.bindService()}, the test case calls
597d433aabb731a790fc8d06d260c826751215113fJoe Malin *          {@link android.app.Service#onCreate() Service.onCreate()} and then calls either
607d433aabb731a790fc8d06d260c826751215113fJoe Malin *          {@link android.app.Service#startService(Intent) Service.startService(Intent)} or
617d433aabb731a790fc8d06d260c826751215113fJoe Malin *          {@link android.app.Service#bindService(Intent, ServiceConnection, int)
627d433aabb731a790fc8d06d260c826751215113fJoe Malin *          Service.bindService(Intent, ServiceConnection, int)}, as appropriate. It also stores
637d433aabb731a790fc8d06d260c826751215113fJoe Malin *          values needed to track and support the lifecycle.
647d433aabb731a790fc8d06d260c826751215113fJoe Malin *      </li>
657d433aabb731a790fc8d06d260c826751215113fJoe Malin *      <li>
667d433aabb731a790fc8d06d260c826751215113fJoe Malin *          After each test method finishes, the test case calls the {@link #tearDown} method. This
677d433aabb731a790fc8d06d260c826751215113fJoe Malin *          method stops and destroys the service with the appropriate calls, depending on how the
687d433aabb731a790fc8d06d260c826751215113fJoe Malin *          service was started. If you override <code>tearDown()</code>, your must call the
697d433aabb731a790fc8d06d260c826751215113fJoe Malin *          <code>super.tearDown()</code> as the last statement in your override.
707d433aabb731a790fc8d06d260c826751215113fJoe Malin *      </li>
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul>
727d433aabb731a790fc8d06d260c826751215113fJoe Malin *
737d433aabb731a790fc8d06d260c826751215113fJoe Malin * <p>
747d433aabb731a790fc8d06d260c826751215113fJoe Malin *      <strong>Dependency Injection.</strong>
757d433aabb731a790fc8d06d260c826751215113fJoe Malin *      A service has two inherent dependencies, its {@link android.content.Context Context} and its
767d433aabb731a790fc8d06d260c826751215113fJoe Malin *      associated {@link android.app.Application Application}. The ServiceTestCase framework
777d433aabb731a790fc8d06d260c826751215113fJoe Malin *      allows you to inject modified, mock, or isolated replacements for these dependencies, and
787d433aabb731a790fc8d06d260c826751215113fJoe Malin *      thus perform unit tests with controlled dependencies in an isolated environment.
797d433aabb731a790fc8d06d260c826751215113fJoe Malin * </p>
807d433aabb731a790fc8d06d260c826751215113fJoe Malin * <p>
817d433aabb731a790fc8d06d260c826751215113fJoe Malin *      By default, the test case is injected with a full system context and a generic
827d433aabb731a790fc8d06d260c826751215113fJoe Malin *      {@link android.test.mock.MockApplication MockApplication} object. You can inject
837d433aabb731a790fc8d06d260c826751215113fJoe Malin *      alternatives to either of these by invoking
847d433aabb731a790fc8d06d260c826751215113fJoe Malin *      {@link AndroidTestCase#setContext(Context) setContext()} or
857d433aabb731a790fc8d06d260c826751215113fJoe Malin *      {@link #setApplication setApplication()}.  You must do this <em>before</em> calling
867d433aabb731a790fc8d06d260c826751215113fJoe Malin *      startService() or bindService().  The test framework provides a
877d433aabb731a790fc8d06d260c826751215113fJoe Malin *      number of alternatives for Context, including
887d433aabb731a790fc8d06d260c826751215113fJoe Malin *      {link android.test.mock.MockContext MockContext},
897d433aabb731a790fc8d06d260c826751215113fJoe Malin *      {@link android.test.RenamingDelegatingContext RenamingDelegatingContext},
907d433aabb731a790fc8d06d260c826751215113fJoe Malin *      {@link android.content.ContextWrapper ContextWrapper}, and
917d433aabb731a790fc8d06d260c826751215113fJoe Malin *      {@link android.test.IsolatedContext}.
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic abstract class ServiceTestCase<T extends Service> extends AndroidTestCase {
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Class<T> mServiceClass;
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Context mSystemContext;
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Application mApplication;
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1007d433aabb731a790fc8d06d260c826751215113fJoe Malin    /**
1017d433aabb731a790fc8d06d260c826751215113fJoe Malin     * Constructor
1027d433aabb731a790fc8d06d260c826751215113fJoe Malin     * @param serviceClass The type of the service under test.
1037d433aabb731a790fc8d06d260c826751215113fJoe Malin     */
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ServiceTestCase(Class<T> serviceClass) {
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mServiceClass = serviceClass;
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private T mService;
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mServiceAttached = false;
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mServiceCreated = false;
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mServiceStarted = false;
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mServiceBound = false;
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Intent mServiceIntent = null;
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mServiceId;
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1177d433aabb731a790fc8d06d260c826751215113fJoe Malin     * @return An instance of the service under test. This instance is created automatically when
1187d433aabb731a790fc8d06d260c826751215113fJoe Malin     * a test calls {@link #startService} or {@link #bindService}.
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public T getService() {
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mService;
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1257d433aabb731a790fc8d06d260c826751215113fJoe Malin     * Gets the current system context and stores it.
1267d433aabb731a790fc8d06d260c826751215113fJoe Malin     *
1277d433aabb731a790fc8d06d260c826751215113fJoe Malin     * Extend this method to do your own test initialization. If you do so, you
1287d433aabb731a790fc8d06d260c826751215113fJoe Malin     * must call <code>super.setUp()</code> as the first statement in your override. The method is
1297d433aabb731a790fc8d06d260c826751215113fJoe Malin     * called before each test method is executed.
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void setUp() throws Exception {
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.setUp();
1347d433aabb731a790fc8d06d260c826751215113fJoe Malin
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // get the real context, before the individual tests have a chance to muck with it
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mSystemContext = getContext();
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1397d433aabb731a790fc8d06d260c826751215113fJoe Malin
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1417d433aabb731a790fc8d06d260c826751215113fJoe Malin     * Creates the service under test and attaches all injected dependencies
1427d433aabb731a790fc8d06d260c826751215113fJoe Malin     * (Context, Application) to it.  This is called automatically by {@link #startService} or
1437d433aabb731a790fc8d06d260c826751215113fJoe Malin     * by {@link #bindService}.
1447d433aabb731a790fc8d06d260c826751215113fJoe Malin     * If you need to call {@link AndroidTestCase#setContext(Context) setContext()} or
1457d433aabb731a790fc8d06d260c826751215113fJoe Malin     * {@link #setApplication setApplication()}, do so before calling this method.
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void setupService() {
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mService = null;
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mService = mServiceClass.newInstance();
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (Exception e) {
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            assertNotNull(mService);
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (getApplication() == null) {
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setApplication(new MockApplication());
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mService.attach(
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                getContext(),
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                null,               // ActivityThread not actually used in Service
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mServiceClass.getName(),
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                null,               // token not needed when not talking with the activity manager
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                getApplication(),
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                null                // mocked services don't talk with the activity manager
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                );
1657d433aabb731a790fc8d06d260c826751215113fJoe Malin
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertNotNull(mService);
1677d433aabb731a790fc8d06d260c826751215113fJoe Malin
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mServiceId = new Random().nextInt();
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mServiceAttached = true;
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1717d433aabb731a790fc8d06d260c826751215113fJoe Malin
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1737d433aabb731a790fc8d06d260c826751215113fJoe Malin     * Starts the service under test, in the same way as if it were started by
1747d433aabb731a790fc8d06d260c826751215113fJoe Malin     * {@link android.content.Context#startService(Intent) Context.startService(Intent)} with
1757d433aabb731a790fc8d06d260c826751215113fJoe Malin     * an {@link android.content.Intent} that identifies a service.
1767d433aabb731a790fc8d06d260c826751215113fJoe Malin     * If you use this method to start the service, it is automatically stopped by
1777d433aabb731a790fc8d06d260c826751215113fJoe Malin     * {@link #tearDown}.
1787d433aabb731a790fc8d06d260c826751215113fJoe Malin     *
1797d433aabb731a790fc8d06d260c826751215113fJoe Malin     * @param intent An Intent that identifies a service, of the same form as the Intent passed to
1807d433aabb731a790fc8d06d260c826751215113fJoe Malin     * {@link android.content.Context#startService(Intent) Context.startService(Intent)}.
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void startService(Intent intent) {
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mServiceAttached) {
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setupService();
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertNotNull(mService);
1877d433aabb731a790fc8d06d260c826751215113fJoe Malin
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mServiceCreated) {
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mService.onCreate();
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mServiceCreated = true;
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19271be4b5ed994030171fb3bd3f08fbc8c43c47567Evan Millar        mService.onStartCommand(intent, 0, mServiceId);
1937d433aabb731a790fc8d06d260c826751215113fJoe Malin
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mServiceStarted = true;
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1977d433aabb731a790fc8d06d260c826751215113fJoe Malin    /**
1987d433aabb731a790fc8d06d260c826751215113fJoe Malin     * <p>
1997d433aabb731a790fc8d06d260c826751215113fJoe Malin     *      Starts the service under test, in the same way as if it were started by
2007d433aabb731a790fc8d06d260c826751215113fJoe Malin     *      {@link android.content.Context#bindService(Intent, ServiceConnection, int)
2017d433aabb731a790fc8d06d260c826751215113fJoe Malin     *      Context.bindService(Intent, ServiceConnection, flags)} with an
2027d433aabb731a790fc8d06d260c826751215113fJoe Malin     *      {@link android.content.Intent} that identifies a service.
2037d433aabb731a790fc8d06d260c826751215113fJoe Malin     * </p>
2047d433aabb731a790fc8d06d260c826751215113fJoe Malin     * <p>
2057d433aabb731a790fc8d06d260c826751215113fJoe Malin     *      Notice that the parameters are different. You do not provide a
2067d433aabb731a790fc8d06d260c826751215113fJoe Malin     *      {@link android.content.ServiceConnection} object or the flags parameter. Instead,
2077d433aabb731a790fc8d06d260c826751215113fJoe Malin     *      you only provide the Intent. The method returns an object whose type is a
2087d433aabb731a790fc8d06d260c826751215113fJoe Malin     *      subclass of {@link android.os.IBinder}, or null if the method fails. An IBinder
2097d433aabb731a790fc8d06d260c826751215113fJoe Malin     *      object refers to a communication channel between the application and
2107d433aabb731a790fc8d06d260c826751215113fJoe Malin     *      the service. The flag is assumed to be {@link android.content.Context#BIND_AUTO_CREATE}.
2117d433aabb731a790fc8d06d260c826751215113fJoe Malin     * </p>
2127d433aabb731a790fc8d06d260c826751215113fJoe Malin     * <p>
2137d433aabb731a790fc8d06d260c826751215113fJoe Malin     *      See <a href="{@docRoot}guide/developing/tools/aidl.html">Designing a Remote Interface
2147d433aabb731a790fc8d06d260c826751215113fJoe Malin     *      Using AIDL</a> for more information about the communication channel object returned
2157d433aabb731a790fc8d06d260c826751215113fJoe Malin     *      by this method.
2167d433aabb731a790fc8d06d260c826751215113fJoe Malin     * </p>
2177d433aabb731a790fc8d06d260c826751215113fJoe Malin     * Note:  To be able to use bindService in a test, the service must implement getService()
2187d433aabb731a790fc8d06d260c826751215113fJoe Malin     * method. An example of this is in the ApiDemos sample application, in the
2197d433aabb731a790fc8d06d260c826751215113fJoe Malin     * LocalService demo.
2207d433aabb731a790fc8d06d260c826751215113fJoe Malin     *
2217d433aabb731a790fc8d06d260c826751215113fJoe Malin     * @param intent An Intent object of the form expected by
2227d433aabb731a790fc8d06d260c826751215113fJoe Malin     * {@link android.content.Context#bindService}.
2237d433aabb731a790fc8d06d260c826751215113fJoe Malin     *
2247d433aabb731a790fc8d06d260c826751215113fJoe Malin     * @return An object whose type is a subclass of IBinder, for making further calls into
2257d433aabb731a790fc8d06d260c826751215113fJoe Malin     * the service.
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected IBinder bindService(Intent intent) {
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mServiceAttached) {
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setupService();
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertNotNull(mService);
2327d433aabb731a790fc8d06d260c826751215113fJoe Malin
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mServiceCreated) {
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mService.onCreate();
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mServiceCreated = true;
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // no extras are expected by unbind
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mServiceIntent = intent.cloneFilter();
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IBinder result = mService.onBind(intent);
2407d433aabb731a790fc8d06d260c826751215113fJoe Malin
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mServiceBound = true;
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return result;
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2447d433aabb731a790fc8d06d260c826751215113fJoe Malin
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2467d433aabb731a790fc8d06d260c826751215113fJoe Malin     * Makes the necessary calls to stop (or unbind) the service under test, and
2477d433aabb731a790fc8d06d260c826751215113fJoe Malin     * calls onDestroy().  Ordinarily this is called automatically (by {@link #tearDown}, but
2487d433aabb731a790fc8d06d260c826751215113fJoe Malin     * you can call it directly from your test in order to check for proper shutdown behavior.
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void shutdownService() {
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mServiceStarted) {
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mService.stopSelf();
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mServiceStarted = false;
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (mServiceBound) {
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mService.onUnbind(mServiceIntent);
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mServiceBound = false;
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mServiceCreated) {
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mService.onDestroy();
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2627d433aabb731a790fc8d06d260c826751215113fJoe Malin
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2647d433aabb731a790fc8d06d260c826751215113fJoe Malin     * <p>
2657d433aabb731a790fc8d06d260c826751215113fJoe Malin     *      Shuts down the service under test.  Ensures all resources are cleaned up and
2667d433aabb731a790fc8d06d260c826751215113fJoe Malin     *      garbage collected before moving on to the next test. This method is called after each
2677d433aabb731a790fc8d06d260c826751215113fJoe Malin     *      test method.
2687d433aabb731a790fc8d06d260c826751215113fJoe Malin     * </p>
2697d433aabb731a790fc8d06d260c826751215113fJoe Malin     * <p>
2707d433aabb731a790fc8d06d260c826751215113fJoe Malin     *      Subclasses that override this method must call <code>super.tearDown()</code> as their
2717d433aabb731a790fc8d06d260c826751215113fJoe Malin     *      last statement.
2727d433aabb731a790fc8d06d260c826751215113fJoe Malin     * </p>
2737d433aabb731a790fc8d06d260c826751215113fJoe Malin     *
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws Exception
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void tearDown() throws Exception {
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        shutdownService();
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mService = null;
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2817d433aabb731a790fc8d06d260c826751215113fJoe Malin        // Scrub out members - protects against memory leaks in the case where someone
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // creates a non-static inner class (thus referencing the test case) and gives it to
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // someone else to hold onto
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        scrubClass(ServiceTestCase.class);
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.tearDown();
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2887d433aabb731a790fc8d06d260c826751215113fJoe Malin
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2907d433aabb731a790fc8d06d260c826751215113fJoe Malin     * Sets the application that is used during the test.  If you do not call this method,
2917d433aabb731a790fc8d06d260c826751215113fJoe Malin     * a new {@link android.test.mock.MockApplication MockApplication} object is used.
2927d433aabb731a790fc8d06d260c826751215113fJoe Malin     *
2937d433aabb731a790fc8d06d260c826751215113fJoe Malin     * @param application The Application object that is used by the service under test.
2947d433aabb731a790fc8d06d260c826751215113fJoe Malin     *
2957d433aabb731a790fc8d06d260c826751215113fJoe Malin     * @see #getApplication()
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setApplication(Application application) {
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mApplication = application;
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3027d433aabb731a790fc8d06d260c826751215113fJoe Malin     * Returns the Application object in use by the service under test.
3037d433aabb731a790fc8d06d260c826751215113fJoe Malin     *
3047d433aabb731a790fc8d06d260c826751215113fJoe Malin     * @return The application object.
3057d433aabb731a790fc8d06d260c826751215113fJoe Malin     *
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setApplication
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Application getApplication() {
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mApplication;
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3117d433aabb731a790fc8d06d260c826751215113fJoe Malin
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3137d433aabb731a790fc8d06d260c826751215113fJoe Malin     * Returns the real system context that is saved by {@link #setUp()}. Use it to create
3147d433aabb731a790fc8d06d260c826751215113fJoe Malin     * mock or other types of context objects for the service under test.
3157d433aabb731a790fc8d06d260c826751215113fJoe Malin     *
3167d433aabb731a790fc8d06d260c826751215113fJoe Malin     * @return A normal system context.
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Context getSystemContext() {
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mSystemContext;
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3227d433aabb731a790fc8d06d260c826751215113fJoe Malin    /**
3237d433aabb731a790fc8d06d260c826751215113fJoe Malin     * Tests that {@link #setupService()} runs correctly and issues an
3247d433aabb731a790fc8d06d260c826751215113fJoe Malin     * {@link junit.framework.Assert#assertNotNull(String, Object)} if it does.
3257d433aabb731a790fc8d06d260c826751215113fJoe Malin     * You can override this test method if you wish.
3267d433aabb731a790fc8d06d260c826751215113fJoe Malin     *
3277d433aabb731a790fc8d06d260c826751215113fJoe Malin     * @throws Exception
3287d433aabb731a790fc8d06d260c826751215113fJoe Malin     */
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void testServiceTestCaseSetUpProperly() throws Exception {
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setupService();
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertNotNull("service should be launched successfully", mService);
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
334