|
1 /* Any copyright is dedicated to the Public Domain. |
|
2 http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
3 |
|
4 package org.mozilla.gecko.background.helpers; |
|
5 |
|
6 import android.app.AlarmManager; |
|
7 import android.app.PendingIntent; |
|
8 import android.app.Service; |
|
9 import android.content.Context; |
|
10 import android.content.Intent; |
|
11 import android.content.SharedPreferences; |
|
12 import android.test.ServiceTestCase; |
|
13 import java.util.concurrent.BrokenBarrierException; |
|
14 import java.util.concurrent.CyclicBarrier; |
|
15 import java.util.UUID; |
|
16 |
|
17 import org.mozilla.gecko.background.common.GlobalConstants; |
|
18 |
|
19 /** |
|
20 * An abstract test class for testing background services. Since we have to wait for background |
|
21 * services to finish before asserting the changed state, this class provides much of the |
|
22 * functionality to do this. Extending classes need still need to implement some of the components - |
|
23 * see {@link TestHealthReportBroadcastService} for an example. |
|
24 */ |
|
25 public abstract class BackgroundServiceTestCase<T extends Service> extends ServiceTestCase<T> { |
|
26 private static final String SHARED_PREFS_PREFIX = "BackgroundServiceTestCase-"; |
|
27 // Ideally, this would not be static so multiple test classes can be run in parallel. However, |
|
28 // mServiceClass can only retrieve this reference statically because mServiceClass cannot get a |
|
29 // reference to the Test* class as ServiceTestCase instantiates it via reflection and we can't |
|
30 // pass it as a constructor arg. |
|
31 protected static String sharedPrefsName; |
|
32 |
|
33 private final Class<T> mServiceClass; |
|
34 |
|
35 protected static CyclicBarrier barrier; |
|
36 protected Intent intent; |
|
37 |
|
38 public BackgroundServiceTestCase(Class<T> serviceClass) { |
|
39 super(serviceClass); |
|
40 mServiceClass = serviceClass; |
|
41 } |
|
42 |
|
43 @Override |
|
44 public void setUp() throws Exception { |
|
45 barrier = new CyclicBarrier(2); |
|
46 intent = new Intent(getContext(), mServiceClass); |
|
47 sharedPrefsName = SHARED_PREFS_PREFIX + mServiceClass.getName() + "-" + UUID.randomUUID(); |
|
48 } |
|
49 |
|
50 @Override |
|
51 public void tearDown() throws Exception { |
|
52 barrier = null; |
|
53 intent = null; |
|
54 clearSharedPrefs(); // Not necessary but reduces file system cruft. |
|
55 } |
|
56 |
|
57 protected SharedPreferences getSharedPreferences() { |
|
58 return getContext().getSharedPreferences(sharedPrefsName, |
|
59 GlobalConstants.SHARED_PREFERENCES_MODE); |
|
60 } |
|
61 |
|
62 protected void clearSharedPrefs() { |
|
63 getSharedPreferences().edit() |
|
64 .clear() |
|
65 .commit(); |
|
66 } |
|
67 |
|
68 protected void await() { |
|
69 try { |
|
70 barrier.await(); |
|
71 } catch (InterruptedException e) { |
|
72 fail("Test runner thread should not be interrupted."); |
|
73 } catch (BrokenBarrierException e) { |
|
74 fail("Background services should not timeout or be interrupted"); |
|
75 } |
|
76 } |
|
77 |
|
78 protected void cancelAlarm(Intent intent) { |
|
79 final AlarmManager am = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE); |
|
80 final PendingIntent pi = PendingIntent.getService(getContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); |
|
81 am.cancel(pi); |
|
82 pi.cancel(); |
|
83 } |
|
84 |
|
85 protected boolean isServiceAlarmSet(Intent intent) { |
|
86 return PendingIntent.getService(getContext(), 0, intent, PendingIntent.FLAG_NO_CREATE) != null; |
|
87 } |
|
88 } |