• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.robolectric.shadows;
2 
3 import static android.app.PendingIntent.FLAG_CANCEL_CURRENT;
4 import static android.app.PendingIntent.FLAG_IMMUTABLE;
5 import static android.app.PendingIntent.FLAG_NO_CREATE;
6 import static android.app.PendingIntent.FLAG_ONE_SHOT;
7 import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
8 import static com.google.common.truth.Truth.assertThat;
9 import static org.junit.Assert.fail;
10 import static org.robolectric.Shadows.shadowOf;
11 
12 import android.app.Activity;
13 import android.app.Application;
14 import android.app.PendingIntent;
15 import android.app.PendingIntent.CanceledException;
16 import android.content.BroadcastReceiver;
17 import android.content.ComponentName;
18 import android.content.Context;
19 import android.content.Intent;
20 import android.content.IntentFilter;
21 import android.os.Build;
22 import android.os.Bundle;
23 import android.os.Handler;
24 import android.os.HandlerThread;
25 import android.os.Looper;
26 import android.os.Parcel;
27 import androidx.test.core.app.ApplicationProvider;
28 import androidx.test.ext.junit.runners.AndroidJUnit4;
29 import java.util.concurrent.atomic.AtomicBoolean;
30 import java.util.concurrent.atomic.AtomicInteger;
31 import org.junit.Before;
32 import org.junit.Test;
33 import org.junit.runner.RunWith;
34 import org.robolectric.Robolectric;
35 import org.robolectric.annotation.Config;
36 import org.robolectric.shadows.ShadowActivity.IntentForResult;
37 
38 @SuppressWarnings("deprecation")
39 @RunWith(AndroidJUnit4.class)
40 public class ShadowPendingIntentTest {
41 
42   private Context context;
43 
44   @Before
setUp()45   public void setUp() {
46     context = ApplicationProvider.getApplicationContext();
47   }
48 
49   @Test
getBroadcast_shouldCreateIntentForBroadcast()50   public void getBroadcast_shouldCreateIntentForBroadcast() {
51     Intent intent = new Intent();
52     PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 99, intent, 0);
53 
54     ShadowPendingIntent shadow = shadowOf(pendingIntent);
55     assertThat(shadow.isActivityIntent()).isFalse();
56     assertThat(shadow.isBroadcastIntent()).isTrue();
57     assertThat(shadow.isServiceIntent()).isFalse();
58     assertThat(shadow.isForegroundServiceIntent()).isFalse();
59     assertThat(intent).isEqualTo(shadow.getSavedIntent());
60     assertThat(context).isEqualTo(shadow.getSavedContext());
61     assertThat(shadow.getRequestCode()).isEqualTo(99);
62     assertThat(shadow.getFlags()).isEqualTo(0);
63   }
64 
65   @Test
getActivity_withBundle_shouldCreateIntentForBroadcast()66   public void getActivity_withBundle_shouldCreateIntentForBroadcast() {
67     Intent intent = new Intent();
68     Bundle bundle = new Bundle();
69     bundle.putInt("weight", 741);
70     bundle.putString("name", "Ada");
71     PendingIntent pendingIntent = PendingIntent.getActivity(context, 99, intent, 0, bundle);
72 
73     ShadowPendingIntent shadow = shadowOf(pendingIntent);
74     assertThat(shadow.isActivityIntent()).isTrue();
75     assertThat(shadow.isBroadcastIntent()).isFalse();
76     assertThat(shadow.isServiceIntent()).isFalse();
77     assertThat(shadow.isForegroundServiceIntent()).isFalse();
78     assertThat(intent).isEqualTo(shadow.getSavedIntent());
79     assertThat(context).isEqualTo(shadow.getSavedContext());
80     assertThat(shadow.getRequestCode()).isEqualTo(99);
81     assertThat(shadow.getFlags()).isEqualTo(0);
82     assertThat(shadow.getOptions().getInt("weight")).isEqualTo(741);
83     assertThat(shadow.getOptions().getString("name")).isEqualTo("Ada");
84   }
85 
86   @Test
getActivities_shouldCreateIntentForBroadcast()87   public void getActivities_shouldCreateIntentForBroadcast() throws Exception {
88     Intent[] intents = {new Intent(Intent.ACTION_VIEW), new Intent(Intent.ACTION_PICK)};
89     PendingIntent pendingIntent = PendingIntent.getActivities(context, 99, intents, 0);
90 
91     ShadowPendingIntent shadow = shadowOf(pendingIntent);
92     assertThat(shadow.getSavedIntents()).isEqualTo(intents);
93 
94     pendingIntent.send();
95     ShadowApplication application =
96         shadowOf((Application) ApplicationProvider.getApplicationContext());
97     assertThat(application.getNextStartedActivity()).isEqualTo(intents[1]);
98     assertThat(application.getNextStartedActivity()).isEqualTo(intents[0]);
99   }
100 
101   @Test
getActivities_withBundle_shouldCreateIntentForBroadcast()102   public void getActivities_withBundle_shouldCreateIntentForBroadcast() throws Exception {
103     Intent[] intents = {new Intent(Intent.ACTION_VIEW), new Intent(Intent.ACTION_PICK)};
104     Bundle bundle = new Bundle();
105     bundle.putInt("weight", 741);
106     bundle.putString("name", "Ada");
107     PendingIntent pendingIntent = PendingIntent.getActivities(context, 99, intents, 0, bundle);
108 
109     ShadowPendingIntent shadow = shadowOf(pendingIntent);
110     assertThat(shadow.getSavedIntents()).isEqualTo(intents);
111 
112     pendingIntent.send();
113     ShadowApplication application =
114         shadowOf((Application) ApplicationProvider.getApplicationContext());
115     assertThat(application.getNextStartedActivity()).isEqualTo(intents[1]);
116     assertThat(application.getNextStartedActivity()).isEqualTo(intents[0]);
117     assertThat(shadow.getOptions().getInt("weight")).isEqualTo(741);
118     assertThat(shadow.getOptions().getString("name")).isEqualTo("Ada");
119   }
120 
121   @Test
getService_shouldCreateIntentForBroadcast()122   public void getService_shouldCreateIntentForBroadcast() {
123     Intent intent = new Intent().setPackage("dummy.package");
124     PendingIntent pendingIntent = PendingIntent.getService(context, 99, intent, 0);
125 
126     ShadowPendingIntent shadow = shadowOf(pendingIntent);
127     assertThat(shadow.isActivityIntent()).isFalse();
128     assertThat(shadow.isBroadcastIntent()).isFalse();
129     assertThat(shadow.isForegroundServiceIntent()).isFalse();
130     assertThat(shadow.isServiceIntent()).isTrue();
131     assertThat(intent).isEqualTo(shadow.getSavedIntent());
132     assertThat(context).isEqualTo(shadow.getSavedContext());
133     assertThat(shadow.getRequestCode()).isEqualTo(99);
134     assertThat(shadow.getFlags()).isEqualTo(0);
135   }
136 
137   @Test
138   @Config(minSdk = Build.VERSION_CODES.O)
getForegroundService_shouldCreateIntentForBroadcast()139   public void getForegroundService_shouldCreateIntentForBroadcast() {
140     Intent intent = new Intent().setPackage("dummy.package");
141     PendingIntent pendingIntent = PendingIntent.getForegroundService(context, 99, intent, 0);
142 
143     ShadowPendingIntent shadow = shadowOf(pendingIntent);
144     assertThat(shadow.isActivityIntent()).isFalse();
145     assertThat(shadow.isBroadcastIntent()).isFalse();
146     assertThat(shadow.isForegroundServiceIntent()).isTrue();
147     assertThat(shadow.isServiceIntent()).isFalse();
148     assertThat(intent).isEqualTo(shadow.getSavedIntent());
149     assertThat(context).isEqualTo(shadow.getSavedContext());
150     assertThat(shadow.getRequestCode()).isEqualTo(99);
151     assertThat(shadow.getFlags()).isEqualTo(0);
152   }
153 
154   @Test
getActivities_nullIntent()155   public void getActivities_nullIntent() {
156     try {
157       PendingIntent.getActivities(context, 99, null, 0);
158       fail("Expected NullPointerException when creating PendingIntent with null Intent[]");
159     } catch (NullPointerException ignore) {
160       // expected
161     }
162   }
163 
164   @Test
getActivities_withBundle_nullIntent()165   public void getActivities_withBundle_nullIntent() {
166     try {
167       PendingIntent.getActivities(context, 99, null, 0, Bundle.EMPTY);
168       fail("Expected NullPointerException when creating PendingIntent with null Intent[]");
169     } catch (NullPointerException ignore) {
170       // expected
171     }
172   }
173 
174   @Test
send_shouldFillInIntentData()175   public void send_shouldFillInIntentData() throws Exception {
176     Intent intent = new Intent("action");
177     Context context = Robolectric.setupActivity(Activity.class);
178     PendingIntent pendingIntent = PendingIntent.getActivity(context, 99, intent, 0);
179 
180     Activity otherContext = Robolectric.setupActivity(Activity.class);
181     Intent fillIntent = new Intent().putExtra("TEST", 23);
182     pendingIntent.send(otherContext, 0, fillIntent);
183 
184     Intent i = shadowOf(otherContext).getNextStartedActivity();
185     assertThat(i).isNotNull();
186     assertThat(i.filterEquals(intent)).isTrue(); // Ignore extras.
187     assertThat(i.getIntExtra("TEST", -1)).isEqualTo(23);
188   }
189 
190   @Test
send_shouldNotReusePreviouslyFilledInIntentData()191   public void send_shouldNotReusePreviouslyFilledInIntentData() throws Exception {
192     Intent intent = new Intent("action");
193     Context context = Robolectric.setupActivity(Activity.class);
194     PendingIntent pendingIntent = PendingIntent.getActivity(context, 99, intent, 0);
195 
196     Activity otherContext = Robolectric.setupActivity(Activity.class);
197     Intent firstFillIntent = new Intent().putExtra("KEY1", 23).putExtra("KEY2", 24);
198     pendingIntent.send(otherContext, 0, firstFillIntent);
199 
200     ShadowActivity shadowActivity = shadowOf(otherContext);
201     shadowActivity.clearNextStartedActivities();
202 
203     Intent secondFillIntent = new Intent().putExtra("KEY1", 50);
204     pendingIntent.send(otherContext, 0, secondFillIntent);
205 
206     Intent i = shadowActivity.getNextStartedActivity();
207     assertThat(i).isNotNull();
208     assertThat(i.filterEquals(intent)).isTrue(); // Ignore extras.
209     assertThat(i.getIntExtra("KEY1", -1)).isEqualTo(50);
210     assertThat(i.hasExtra("KEY2")).isFalse();
211   }
212 
213   @Test
send_shouldFillInLastIntentData()214   public void send_shouldFillInLastIntentData() throws Exception {
215     Intent[] intents = {new Intent("first"), new Intent("second")};
216     Context context = Robolectric.setupActivity(Activity.class);
217     PendingIntent pendingIntent = PendingIntent.getActivities(context, 99, intents, 0);
218 
219     Activity otherContext = Robolectric.setupActivity(Activity.class);
220     Intent fillIntent = new Intent();
221     fillIntent.putExtra("TEST", 23);
222     pendingIntent.send(otherContext, 0, fillIntent);
223 
224     ShadowActivity shadowActivity = shadowOf(otherContext);
225     Intent second = shadowActivity.getNextStartedActivity();
226     assertThat(second).isNotNull();
227     assertThat(second.filterEquals(intents[1])).isTrue(); // Ignore extras.
228     assertThat(second.getIntExtra("TEST", -1)).isEqualTo(23);
229 
230     Intent first = shadowActivity.getNextStartedActivity();
231     assertThat(first).isNotNull();
232     assertThat(first).isSameInstanceAs(intents[0]);
233     assertThat(first.hasExtra("TEST")).isFalse();
234   }
235 
236   @Test
237   @Config(minSdk = Build.VERSION_CODES.S)
send_shouldFillInIntentData_immutable()238   public void send_shouldFillInIntentData_immutable() throws Exception {
239     Intent[] intents = {new Intent("first")};
240     Context context = Robolectric.setupActivity(Activity.class);
241     PendingIntent pendingIntent = PendingIntent.getActivities(context, 99, intents, FLAG_IMMUTABLE);
242 
243     Activity otherContext = Robolectric.setupActivity(Activity.class);
244     Intent fillIntent = new Intent();
245     fillIntent.putExtra("TEST", 23);
246     pendingIntent.send(otherContext, 0, fillIntent);
247 
248     ShadowActivity shadowActivity = shadowOf(otherContext);
249     Intent first = shadowActivity.getNextStartedActivity();
250     assertThat(first).isNotNull();
251     assertThat(first.filterEquals(intents[0])).isTrue(); // Ignore extras.
252     assertThat(first.hasExtra("TEST")).isFalse();
253   }
254 
255   @Test
send_shouldFillInIntentData_mutable_alreadySet()256   public void send_shouldFillInIntentData_mutable_alreadySet() throws Exception {
257     Intent[] intents = {new Intent("first")};
258     Context context = Robolectric.setupActivity(Activity.class);
259     PendingIntent pendingIntent = PendingIntent.getActivities(context, 99, intents, 0);
260 
261     Activity otherContext = Robolectric.setupActivity(Activity.class);
262     Intent fillIntent = new Intent("first_and");
263     pendingIntent.send(otherContext, 0, fillIntent);
264 
265     ShadowActivity shadowActivity = shadowOf(otherContext);
266     Intent first = shadowActivity.getNextStartedActivity();
267     assertThat(first).isNotNull();
268     assertThat(first.getAction()).isEqualTo("first");
269   }
270 
271   @Test
send_shouldFillInIntentData_mutable_alreadySet_fillIn()272   public void send_shouldFillInIntentData_mutable_alreadySet_fillIn() throws Exception {
273     Intent[] intents = {new Intent("first")};
274     Context context = Robolectric.setupActivity(Activity.class);
275     PendingIntent pendingIntent =
276         PendingIntent.getActivities(context, 99, intents, Intent.FILL_IN_ACTION);
277 
278     Activity otherContext = Robolectric.setupActivity(Activity.class);
279     Intent fillIntent = new Intent("first_and");
280     pendingIntent.send(otherContext, 0, fillIntent);
281 
282     ShadowActivity shadowActivity = shadowOf(otherContext);
283     Intent first = shadowActivity.getNextStartedActivity();
284     assertThat(first).isNotNull();
285     assertThat(first.getAction()).isEqualTo("first_and");
286   }
287 
288   @Test
send_shouldNotUsePreviouslyFilledInLastIntentData()289   public void send_shouldNotUsePreviouslyFilledInLastIntentData() throws Exception {
290     Intent[] intents = {new Intent("first"), new Intent("second")};
291     Context context = Robolectric.setupActivity(Activity.class);
292     PendingIntent pendingIntent = PendingIntent.getActivities(context, 99, intents, 0);
293 
294     Activity otherContext = Robolectric.setupActivity(Activity.class);
295     Intent firstFillIntent = new Intent();
296     firstFillIntent.putExtra("KEY1", 23);
297     firstFillIntent.putExtra("KEY2", 24);
298     pendingIntent.send(otherContext, 0, firstFillIntent);
299 
300     ShadowActivity shadowActivity = shadowOf(otherContext);
301     shadowActivity.clearNextStartedActivities();
302 
303     Intent secondFillIntent = new Intent();
304     secondFillIntent.putExtra("KEY1", 50);
305     pendingIntent.send(otherContext, 0, secondFillIntent);
306 
307     Intent second = shadowActivity.getNextStartedActivity();
308     assertThat(second).isNotNull();
309     assertThat(second.filterEquals(intents[1])).isTrue(); // Ignore extras.
310     assertThat(second.getIntExtra("KEY1", -1)).isEqualTo(50);
311     assertThat(second.hasExtra("KEY2")).isFalse();
312   }
313 
314   @Test
send_shouldNotFillIn_whenPendingIntentIsImmutable()315   public void send_shouldNotFillIn_whenPendingIntentIsImmutable() throws Exception {
316     Intent intent = new Intent();
317     Context context = Robolectric.setupActivity(Activity.class);
318     PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, FLAG_IMMUTABLE);
319 
320     Activity otherContext = Robolectric.setupActivity(Activity.class);
321     Intent fillIntent = new Intent().putExtra("TEST", 23);
322     pendingIntent.send(otherContext, 0, fillIntent);
323 
324     Intent i = shadowOf(otherContext).getNextStartedActivity();
325     assertThat(i).isNotNull();
326     assertThat(i).isSameInstanceAs(intent);
327     assertThat(i.hasExtra("TEST")).isFalse();
328   }
329 
330   @Test
updatePendingIntent()331   public void updatePendingIntent() {
332     Intent intent = new Intent().putExtra("whatever", 5);
333     PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
334     ShadowPendingIntent shadowPendingIntent = shadowOf(pendingIntent);
335 
336     // Absent FLAG_UPDATE_CURRENT, this should fail to update the Intent extra.
337     intent = new Intent().putExtra("whatever", 77);
338     PendingIntent.getBroadcast(context, 0, intent, 0);
339     assertThat(shadowPendingIntent.getSavedIntent().getIntExtra("whatever", -1)).isEqualTo(5);
340 
341     // With FLAG_UPDATE_CURRENT, this should succeed in updating the Intent extra.
342     PendingIntent.getBroadcast(context, 0, intent, FLAG_UPDATE_CURRENT);
343     assertThat(shadowPendingIntent.getSavedIntent().getIntExtra("whatever", -1)).isEqualTo(77);
344   }
345 
346   @Test
getActivity_withFlagNoCreate_shouldReturnNullIfNoPendingIntentExists()347   public void getActivity_withFlagNoCreate_shouldReturnNullIfNoPendingIntentExists() {
348     Intent intent = new Intent();
349     assertThat(PendingIntent.getActivity(context, 99, intent, FLAG_NO_CREATE)).isNull();
350   }
351 
352   @Test
getActivity_withFlagNoCreate_shouldReturnNullIfRequestCodeIsUnmatched()353   public void getActivity_withFlagNoCreate_shouldReturnNullIfRequestCodeIsUnmatched() {
354     Intent intent = new Intent();
355     PendingIntent.getActivity(context, 99, intent, 0);
356     assertThat(PendingIntent.getActivity(context, 98, intent, FLAG_NO_CREATE)).isNull();
357   }
358 
359   @Test
getActivity_withFlagNoCreate_shouldReturnExistingIntent()360   public void getActivity_withFlagNoCreate_shouldReturnExistingIntent() {
361     Intent intent = new Intent();
362     PendingIntent.getActivity(context, 99, intent, 0);
363 
364     Intent identical = new Intent();
365     PendingIntent saved = PendingIntent.getActivity(context, 99, identical, FLAG_NO_CREATE);
366     assertThat(saved).isNotNull();
367     assertThat(intent).isSameInstanceAs(shadowOf(saved).getSavedIntent());
368   }
369 
370   @Test
getActivity_withNoFlags_shouldReturnExistingIntent()371   public void getActivity_withNoFlags_shouldReturnExistingIntent() {
372     Intent intent = new Intent();
373     PendingIntent.getActivity(context, 99, intent, 0);
374 
375     Intent updated = new Intent();
376     PendingIntent saved = PendingIntent.getActivity(context, 99, updated, 0);
377     assertThat(saved).isNotNull();
378     assertThat(intent).isSameInstanceAs(shadowOf(saved).getSavedIntent());
379   }
380 
381   @Test
getActivities_withFlagNoCreate_shouldReturnNullIfNoPendingIntentExists()382   public void getActivities_withFlagNoCreate_shouldReturnNullIfNoPendingIntentExists() {
383     Intent[] intents = {new Intent(Intent.ACTION_VIEW), new Intent(Intent.ACTION_PICK)};
384     PendingIntent pendingIntent = PendingIntent.getActivities(context, 99, intents, FLAG_NO_CREATE);
385     assertThat(pendingIntent).isNull();
386   }
387 
388   @Test
getActivities_withFlagNoCreate_shouldReturnNullIfRequestCodeIsUnmatched()389   public void getActivities_withFlagNoCreate_shouldReturnNullIfRequestCodeIsUnmatched() {
390     Intent[] intents = {new Intent()};
391     PendingIntent.getActivities(context, 99, intents, 0);
392     assertThat(PendingIntent.getActivities(context, 98, intents, FLAG_NO_CREATE)).isNull();
393   }
394 
395   @Test
getActivities_withFlagNoCreate_shouldReturnExistingIntent()396   public void getActivities_withFlagNoCreate_shouldReturnExistingIntent() {
397     Intent[] intents = {new Intent(Intent.ACTION_VIEW), new Intent(Intent.ACTION_PICK)};
398     PendingIntent.getActivities(ApplicationProvider.getApplicationContext(), 99, intents, 0);
399 
400     Intent[] identicalIntents = {new Intent(Intent.ACTION_VIEW), new Intent(Intent.ACTION_PICK)};
401     PendingIntent saved =
402         PendingIntent.getActivities(context, 99, identicalIntents, FLAG_NO_CREATE);
403     assertThat(saved).isNotNull();
404     assertThat(intents).isSameInstanceAs(shadowOf(saved).getSavedIntents());
405   }
406 
407   @Test
getActivities_withNoFlags_shouldReturnExistingIntent()408   public void getActivities_withNoFlags_shouldReturnExistingIntent() {
409     Intent[] intents = {new Intent(Intent.ACTION_VIEW), new Intent(Intent.ACTION_PICK)};
410     PendingIntent.getActivities(ApplicationProvider.getApplicationContext(), 99, intents, 0);
411 
412     Intent[] identicalIntents = {new Intent(Intent.ACTION_VIEW), new Intent(Intent.ACTION_PICK)};
413     PendingIntent saved = PendingIntent.getActivities(context, 99, identicalIntents, 0);
414     assertThat(saved).isNotNull();
415     assertThat(intents).isSameInstanceAs(shadowOf(saved).getSavedIntents());
416   }
417 
418   @Test
getBroadcast_withFlagNoCreate_shouldReturnNullIfNoPendingIntentExists()419   public void getBroadcast_withFlagNoCreate_shouldReturnNullIfNoPendingIntentExists() {
420     Intent intent = new Intent();
421     PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 99, intent, FLAG_NO_CREATE);
422     assertThat(pendingIntent).isNull();
423   }
424 
425   @Test
getBroadcast_withFlagNoCreate_shouldReturnNullIfRequestCodeIsUnmatched()426   public void getBroadcast_withFlagNoCreate_shouldReturnNullIfRequestCodeIsUnmatched() {
427     Intent intent = new Intent();
428     PendingIntent.getBroadcast(context, 99, intent, 0);
429     assertThat(PendingIntent.getBroadcast(context, 98, intent, FLAG_NO_CREATE)).isNull();
430   }
431 
432   @Test
getBroadcast_withFlagNoCreate_shouldReturnExistingIntent()433   public void getBroadcast_withFlagNoCreate_shouldReturnExistingIntent() {
434     Intent intent = new Intent();
435     PendingIntent.getBroadcast(context, 99, intent, 0);
436 
437     Intent identical = new Intent();
438     PendingIntent saved = PendingIntent.getBroadcast(context, 99, identical, FLAG_NO_CREATE);
439     assertThat(saved).isNotNull();
440     assertThat(intent).isSameInstanceAs(shadowOf(saved).getSavedIntent());
441   }
442 
443   @Test
getBroadcast_withNoFlags_shouldReturnExistingIntent()444   public void getBroadcast_withNoFlags_shouldReturnExistingIntent() {
445     Intent intent = new Intent();
446     PendingIntent.getBroadcast(context, 99, intent, 0);
447 
448     Intent identical = new Intent();
449     PendingIntent saved = PendingIntent.getBroadcast(context, 99, identical, 0);
450     assertThat(saved).isNotNull();
451     assertThat(intent).isSameInstanceAs(shadowOf(saved).getSavedIntent());
452   }
453 
454   @Test
getService_withFlagNoCreate_shouldReturnNullIfNoPendingIntentExists()455   public void getService_withFlagNoCreate_shouldReturnNullIfNoPendingIntentExists() {
456     Intent intent = new Intent().setPackage("dummy.package");
457     PendingIntent pendingIntent = PendingIntent.getService(context, 99, intent, FLAG_NO_CREATE);
458     assertThat(pendingIntent).isNull();
459   }
460 
461   @Test
getService_withFlagNoCreate_shouldReturnNullIfRequestCodeIsUnmatched()462   public void getService_withFlagNoCreate_shouldReturnNullIfRequestCodeIsUnmatched() {
463     Intent intent = new Intent().setPackage("dummy.package");
464     PendingIntent.getService(context, 99, intent, 0);
465     assertThat(PendingIntent.getService(context, 98, intent, FLAG_NO_CREATE)).isNull();
466   }
467 
468   @Test
getService_withFlagNoCreate_shouldReturnExistingIntent()469   public void getService_withFlagNoCreate_shouldReturnExistingIntent() {
470     Intent intent = new Intent().setPackage("dummy.package");
471     PendingIntent.getService(context, 99, intent, 0);
472 
473     Intent identical = new Intent().setPackage("dummy.package");
474     PendingIntent saved = PendingIntent.getService(context, 99, identical, FLAG_NO_CREATE);
475     assertThat(saved).isNotNull();
476     assertThat(intent).isSameInstanceAs(shadowOf(saved).getSavedIntent());
477   }
478 
479   @Test
getService_withNoFlags_shouldReturnExistingIntent()480   public void getService_withNoFlags_shouldReturnExistingIntent() {
481     Intent intent = new Intent().setPackage("dummy.package");
482     PendingIntent.getService(context, 99, intent, 0);
483 
484     Intent identical = new Intent().setPackage("dummy.package");
485     PendingIntent saved = PendingIntent.getService(context, 99, identical, 0);
486     assertThat(saved).isNotNull();
487     assertThat(intent).isSameInstanceAs(shadowOf(saved).getSavedIntent());
488   }
489 
490   @Test
491   @Config(minSdk = Build.VERSION_CODES.O)
getForegroundService_withFlagNoCreate_shouldReturnNullIfNoPendingIntentExists()492   public void getForegroundService_withFlagNoCreate_shouldReturnNullIfNoPendingIntentExists() {
493     Intent intent = new Intent();
494     PendingIntent pendingIntent =
495         PendingIntent.getForegroundService(context, 99, intent, FLAG_NO_CREATE);
496     assertThat(pendingIntent).isNull();
497   }
498 
499   @Test
500   @Config(minSdk = Build.VERSION_CODES.O)
getForegroundService_withFlagNoCreate_shouldReturnNullIfRequestCodeIsUnmatched()501   public void getForegroundService_withFlagNoCreate_shouldReturnNullIfRequestCodeIsUnmatched() {
502     Intent intent = new Intent();
503     PendingIntent.getForegroundService(context, 99, intent, 0);
504     assertThat(PendingIntent.getForegroundService(context, 98, intent, FLAG_NO_CREATE)).isNull();
505   }
506 
507   @Test
508   @Config(minSdk = Build.VERSION_CODES.O)
getForegroundService_withFlagNoCreate_shouldReturnExistingIntent()509   public void getForegroundService_withFlagNoCreate_shouldReturnExistingIntent() {
510     Intent intent = new Intent();
511     PendingIntent.getForegroundService(context, 99, intent, 0);
512 
513     Intent identical = new Intent();
514     PendingIntent saved =
515         PendingIntent.getForegroundService(context, 99, identical, FLAG_NO_CREATE);
516     assertThat(saved).isNotNull();
517     assertThat(intent).isSameInstanceAs(shadowOf(saved).getSavedIntent());
518   }
519 
520   @Test
521   @Config(minSdk = Build.VERSION_CODES.O)
getForegroundService_withNoFlags_shouldReturnExistingIntent()522   public void getForegroundService_withNoFlags_shouldReturnExistingIntent() {
523     Intent intent = new Intent().setPackage("dummy.package");
524     PendingIntent.getForegroundService(context, 99, intent, 0);
525 
526     Intent identical = new Intent().setPackage("dummy.package");
527     PendingIntent saved = PendingIntent.getForegroundService(context, 99, identical, 0);
528     assertThat(saved).isNotNull();
529     assertThat(intent).isSameInstanceAs(shadowOf(saved).getSavedIntent());
530   }
531 
532   @Test
cancel_shouldRemovePendingIntentForBroadcast()533   public void cancel_shouldRemovePendingIntentForBroadcast() {
534     Intent intent = new Intent();
535     PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 99, intent, 0);
536     assertThat(pendingIntent).isNotNull();
537 
538     pendingIntent.cancel();
539     assertThat(PendingIntent.getBroadcast(context, 99, intent, FLAG_NO_CREATE)).isNull();
540   }
541 
542   @Test
cancel_shouldRemovePendingIntentForActivity()543   public void cancel_shouldRemovePendingIntentForActivity() {
544     Intent intent = new Intent();
545     PendingIntent pendingIntent = PendingIntent.getActivity(context, 99, intent, 0);
546     assertThat(pendingIntent).isNotNull();
547 
548     pendingIntent.cancel();
549     assertThat(PendingIntent.getActivity(context, 99, intent, FLAG_NO_CREATE)).isNull();
550   }
551 
552   @Test
cancel_shouldRemovePendingIntentForActivities()553   public void cancel_shouldRemovePendingIntentForActivities() {
554     Intent[] intents = {new Intent(Intent.ACTION_VIEW), new Intent(Intent.ACTION_PICK)};
555     PendingIntent pendingIntent = PendingIntent.getActivities(context, 99, intents, 0);
556     assertThat(pendingIntent).isNotNull();
557 
558     pendingIntent.cancel();
559     assertThat(PendingIntent.getActivities(context, 99, intents, FLAG_NO_CREATE)).isNull();
560   }
561 
562   @Test
cancel_shouldRemovePendingIntentForService()563   public void cancel_shouldRemovePendingIntentForService() {
564     Intent intent = new Intent().setPackage("dummy.package");
565     PendingIntent pendingIntent = PendingIntent.getService(context, 99, intent, 0);
566     assertThat(pendingIntent).isNotNull();
567 
568     pendingIntent.cancel();
569     assertThat(PendingIntent.getService(context, 99, intent, FLAG_NO_CREATE)).isNull();
570   }
571 
572   @Test
573   @Config(minSdk = Build.VERSION_CODES.O)
cancel_shouldRemovePendingIntentForForegroundService()574   public void cancel_shouldRemovePendingIntentForForegroundService() {
575     Intent intent = new Intent();
576     PendingIntent pendingIntent = PendingIntent.getForegroundService(context, 99, intent, 0);
577     assertThat(pendingIntent).isNotNull();
578 
579     pendingIntent.cancel();
580     assertThat(PendingIntent.getForegroundService(context, 99, intent, FLAG_NO_CREATE)).isNull();
581   }
582 
583   @Test
584   @Config(minSdk = Build.VERSION_CODES.S)
isActivity_activityPendingIntent_returnsTrue()585   public void isActivity_activityPendingIntent_returnsTrue() {
586     Intent intent = new Intent();
587     assertThat(PendingIntent.getActivity(context, 99, intent, 0).isActivity()).isTrue();
588   }
589 
590   @Test
591   @Config(minSdk = Build.VERSION_CODES.S)
isActivity_broadcastPendingIntent_returnsFalse()592   public void isActivity_broadcastPendingIntent_returnsFalse() {
593     Intent intent = new Intent();
594     assertThat(PendingIntent.getBroadcast(context, 99, intent, 0).isActivity()).isFalse();
595   }
596 
597   @Test
598   @Config(minSdk = Build.VERSION_CODES.S)
isBroadcast_broadcastPendingIntent_returnsTrue()599   public void isBroadcast_broadcastPendingIntent_returnsTrue() {
600     Intent intent = new Intent();
601     assertThat(PendingIntent.getBroadcast(context, 99, intent, 0).isBroadcast()).isTrue();
602   }
603 
604   @Test
605   @Config(minSdk = Build.VERSION_CODES.S)
isBroadcast_activityPendingIntent_returnsFalse()606   public void isBroadcast_activityPendingIntent_returnsFalse() {
607     Intent intent = new Intent();
608     assertThat(PendingIntent.getActivity(context, 99, intent, 0).isBroadcast()).isFalse();
609   }
610 
611   @Test
612   @Config(minSdk = Build.VERSION_CODES.S)
isForegroundService_foregroundServicePendingIntent_returnsTrue()613   public void isForegroundService_foregroundServicePendingIntent_returnsTrue() {
614     Intent intent = new Intent();
615     assertThat(PendingIntent.getForegroundService(context, 99, intent, 0).isForegroundService())
616         .isTrue();
617   }
618 
619   @Test
620   @Config(minSdk = Build.VERSION_CODES.S)
isForegroundService_normalServicePendingIntent_returnsFalse()621   public void isForegroundService_normalServicePendingIntent_returnsFalse() {
622     Intent intent = new Intent();
623     assertThat(PendingIntent.getService(context, 99, intent, 0).isForegroundService()).isFalse();
624   }
625 
626   @Test
627   @Config(minSdk = Build.VERSION_CODES.S)
isService_servicePendingIntent_returnsTrue()628   public void isService_servicePendingIntent_returnsTrue() {
629     Intent intent = new Intent();
630     assertThat(PendingIntent.getService(context, 99, intent, 0).isService()).isTrue();
631   }
632 
633   @Test
634   @Config(minSdk = Build.VERSION_CODES.S)
isService_foregroundServicePendingIntent_returnsFalse()635   public void isService_foregroundServicePendingIntent_returnsFalse() {
636     Intent intent = new Intent();
637     assertThat(PendingIntent.getForegroundService(context, 99, intent, 0).isService()).isFalse();
638   }
639 
640   @Test
641   @Config(minSdk = Build.VERSION_CODES.S)
isImmutable_pendingIntentWithImmutableFlag_returnsTrue()642   public void isImmutable_pendingIntentWithImmutableFlag_returnsTrue() {
643     Intent intent = new Intent();
644     assertThat(
645             PendingIntent.getActivity(context, 99, intent, PendingIntent.FLAG_IMMUTABLE)
646                 .isImmutable())
647         .isTrue();
648   }
649 
650   @Test
651   @Config(minSdk = Build.VERSION_CODES.S)
isImmutable_pendingIntentWithoutImmutableFlag_returnsFalse()652   public void isImmutable_pendingIntentWithoutImmutableFlag_returnsFalse() {
653     Intent intent = new Intent();
654     assertThat(PendingIntent.getActivity(context, 99, intent, 0).isActivity()).isTrue();
655   }
656 
657   @Test
send_canceledPendingIntent_throwsCanceledException()658   public void send_canceledPendingIntent_throwsCanceledException() throws CanceledException {
659     Intent intent = new Intent().setPackage("dummy.package");
660     PendingIntent canceled = PendingIntent.getService(context, 99, intent, 0);
661     assertThat(canceled).isNotNull();
662 
663     // Cancel the existing PendingIntent and create a new one in its place.
664     PendingIntent current = PendingIntent.getService(context, 99, intent, FLAG_CANCEL_CURRENT);
665     assertThat(current).isNotNull();
666 
667     assertThat(shadowOf(canceled).isCanceled()).isTrue();
668     assertThat(shadowOf(current).isCanceled()).isFalse();
669 
670     // Sending the new PendingIntent should work as expected.
671     current.send();
672 
673     // Sending the canceled PendingIntent should produce a CanceledException.
674     try {
675       canceled.send();
676       fail("CanceledException expected when sending a canceled PendingIntent");
677     } catch (CanceledException ignore) {
678       // expected
679     }
680   }
681 
682   @Test
send_oneShotPendingIntent_shouldCancel()683   public void send_oneShotPendingIntent_shouldCancel() throws CanceledException {
684     Intent intent = new Intent().setPackage("dummy.package");
685     PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, FLAG_ONE_SHOT);
686     assertThat(shadowOf(pendingIntent).isCanceled()).isFalse();
687 
688     pendingIntent.send();
689     assertThat(shadowOf(pendingIntent).isCanceled()).isTrue();
690     assertThat(PendingIntent.getService(context, 0, intent, FLAG_ONE_SHOT | FLAG_NO_CREATE))
691         .isNull();
692   }
693 
694   @Test
send_resultCode()695   public void send_resultCode() throws CanceledException {
696     AtomicInteger resultCode = new AtomicInteger(0);
697     context.registerReceiver(
698         new BroadcastReceiver() {
699           @Override
700           public void onReceive(Context context, Intent intent) {
701             resultCode.set(getResultCode());
702           }
703         },
704         new IntentFilter("foo"));
705 
706     PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, new Intent("foo"), 0);
707     pendingIntent.send(99);
708     shadowOf(Looper.getMainLooper()).idle();
709     assertThat(resultCode.get()).isEqualTo(99);
710   }
711 
712   /** Verify options are sent along with the PendingIntent. */
713   @Test
714   @Config(minSdk = Build.VERSION_CODES.M)
send_broadcastWithOptions()715   public void send_broadcastWithOptions() throws CanceledException {
716     Intent intent = new Intent().setPackage("dummy.package");
717     PendingIntent pendingIntent =
718         PendingIntent.getBroadcast(context, /* requestCode= */ 0, intent, /* flags= */ 0);
719 
720     // Add an option for the PendingIntent broadcast.
721     final String keyDontSendToRestrictedApps = "android:broadcast.dontSendToRestrictedApps";
722     Bundle options = new Bundle();
723     options.putBoolean(keyDontSendToRestrictedApps, true);
724 
725     // Send the pendingIntent with options.
726     pendingIntent.send(
727         context,
728         /* code= */ 0,
729         intent,
730         /* onFinished= */ null,
731         /* handler= */ null,
732         /* requiredPermission= */ null,
733         options);
734 
735     // Verify the options are used when sending the PendingIntent.
736     ShadowApplication shadowApplication = shadowOf((Application) context);
737     Bundle sendOptions = shadowApplication.getBroadcastOptions(intent);
738     assertThat(sendOptions.getBoolean(keyDontSendToRestrictedApps)).isTrue();
739   }
740 
741   /** Verify options are sent along with the Activity PendingIntent. */
742   @Test
743   @Config(minSdk = Build.VERSION_CODES.M)
send_activityWithOptions()744   public void send_activityWithOptions() throws CanceledException {
745     Intent intent = new Intent().setPackage("dummy.package");
746     Bundle creatorOptions = new Bundle();
747     creatorOptions.putBoolean("creator", true);
748     PendingIntent pendingIntent =
749         PendingIntent.getActivity(
750             context, /* requestCode= */ 0, intent, /* flags= */ 0, creatorOptions);
751 
752     // Add an option when sending the Activity PendingIntent.
753     Bundle senderOptions = new Bundle();
754     senderOptions.putBoolean("sender", true);
755 
756     // Send the pendingIntent with options.
757     pendingIntent.send(
758         context,
759         /* code= */ 0,
760         intent,
761         /* onFinished= */ null,
762         /* handler= */ null,
763         /* requiredPermission= */ null,
764         senderOptions);
765     // Verify that PendingIntent.getOptions() are from the creator.
766     assertThat(shadowOf(pendingIntent).getOptions()).isNotNull();
767     assertThat(shadowOf(pendingIntent).getOptions().keySet()).containsExactly("creator");
768 
769     // Verify senderOptions are used when sending the PendingIntent.
770     ShadowApplication shadowApplication = shadowOf((Application) context);
771     IntentForResult intentForResult = shadowApplication.peekNextStartedActivityForResult();
772     assertThat(intentForResult).isNotNull();
773     assertThat(intentForResult.intent).isNotNull();
774     assertThat(intentForResult.intent.getPackage()).isEqualTo("dummy.package");
775     assertThat(intentForResult.options).isNotNull();
776     assertThat(intentForResult.options.keySet()).containsExactly("sender");
777   }
778 
779   @Test
send_withOnFinishedCallback_callbackSavedForLaterInvocation()780   public void send_withOnFinishedCallback_callbackSavedForLaterInvocation()
781       throws CanceledException {
782     final AtomicBoolean onSendFinishedCalled = new AtomicBoolean(false);
783     PendingIntent.OnFinished onFinished =
784         new PendingIntent.OnFinished() {
785           @Override
786           public void onSendFinished(
787               PendingIntent pendingIntent,
788               Intent intent,
789               int resultCode,
790               String resultData,
791               Bundle resultExtras) {
792             onSendFinishedCalled.set(true);
793           }
794         };
795     Intent intent = new Intent();
796     PendingIntent pendingIntent =
797         PendingIntent.getBroadcast(context, /* requestCode= */ 0, intent, /* flags= */ 0);
798 
799     pendingIntent.send(context, /* code= */ 0, intent, onFinished, /* handler= */ null);
800 
801     assertThat(
802             shadowOf(pendingIntent)
803                 .callLastOnFinished(
804                     intent, /* resultCode= */ 0, /* resultData= */ null, /* resultExtras= */ null))
805         .isTrue();
806     assertThat(onSendFinishedCalled.get()).isTrue();
807   }
808 
809   @Test
send_withOnFinishedCallbackAndHandler_callbackSavedForLaterInvocationOnHandler()810   public void send_withOnFinishedCallbackAndHandler_callbackSavedForLaterInvocationOnHandler()
811       throws CanceledException {
812     HandlerThread handlerThread = new HandlerThread("test");
813     handlerThread.start();
814     Handler handler = new Handler(handlerThread.getLooper());
815     final AtomicBoolean onSendFinishedCalled = new AtomicBoolean(false);
816     PendingIntent.OnFinished onFinished =
817         new PendingIntent.OnFinished() {
818           @Override
819           public void onSendFinished(
820               PendingIntent pendingIntent,
821               Intent intent,
822               int resultCode,
823               String resultData,
824               Bundle resultExtras) {
825             onSendFinishedCalled.set(true);
826           }
827         };
828     Intent intent = new Intent();
829     PendingIntent pendingIntent =
830         PendingIntent.getBroadcast(context, /* requestCode= */ 0, intent, /* flags= */ 0);
831 
832     pendingIntent.send(context, /* code= */ 0, intent, onFinished, handler);
833 
834     assertThat(
835             shadowOf(pendingIntent)
836                 .callLastOnFinished(
837                     intent, /* resultCode= */ 0, /* resultData= */ null, /* resultExtras= */ null))
838         .isTrue();
839     shadowOf(handlerThread.getLooper()).idle();
840     assertThat(onSendFinishedCalled.get()).isTrue();
841     handlerThread.quit();
842   }
843 
844   @Test
send_withOutOnFinishedCallback_onFinishedCallbackReset()845   public void send_withOutOnFinishedCallback_onFinishedCallbackReset() throws CanceledException {
846     final AtomicBoolean onSendFinishedCalled = new AtomicBoolean(false);
847     PendingIntent.OnFinished onFinished =
848         new PendingIntent.OnFinished() {
849           @Override
850           public void onSendFinished(
851               PendingIntent pendingIntent,
852               Intent intent,
853               int resultCode,
854               String resultData,
855               Bundle resultExtras) {
856             onSendFinishedCalled.set(true);
857           }
858         };
859     Intent intent = new Intent();
860     PendingIntent pendingIntent =
861         PendingIntent.getBroadcast(context, /* requestCode= */ 0, intent, /* flags= */ 0);
862 
863     pendingIntent.send(context, /* code= */ 0, intent, onFinished, /* handler= */ null);
864     onSendFinishedCalled.set(false);
865     pendingIntent.send(context, /* code= */ 0, intent);
866 
867     assertThat(
868             shadowOf(pendingIntent)
869                 .callLastOnFinished(
870                     intent, /* resultCode= */ 0, /* resultData= */ null, /* resultExtras= */ null))
871         .isFalse();
872     assertThat(onSendFinishedCalled.get()).isFalse();
873   }
874 
875   @Test
oneShotFlag_differentiatesPendingIntents()876   public void oneShotFlag_differentiatesPendingIntents() {
877     Intent intent = new Intent().setPackage("dummy.package");
878     PendingIntent oneShot = PendingIntent.getService(context, 0, intent, FLAG_ONE_SHOT);
879     PendingIntent notOneShot = PendingIntent.getService(context, 0, intent, FLAG_UPDATE_CURRENT);
880     assertThat(oneShot).isNotSameInstanceAs(notOneShot);
881   }
882 
883   @Test
immutableFlag_differentiatesPendingIntents()884   public void immutableFlag_differentiatesPendingIntents() {
885     Intent intent = new Intent().setPackage("dummy.package");
886     PendingIntent immutable = PendingIntent.getService(context, 0, intent, FLAG_IMMUTABLE);
887     PendingIntent notImmutable = PendingIntent.getService(context, 0, intent, FLAG_UPDATE_CURRENT);
888     assertThat(immutable).isNotSameInstanceAs(notImmutable);
889   }
890 
891   @Test
testEquals()892   public void testEquals() {
893     PendingIntent pendingIntent = PendingIntent.getActivity(context, 99, new Intent("activity"), 0);
894 
895     // Same type, requestCode and Intent action implies equality.
896     assertThat(PendingIntent.getActivity(context, 99, new Intent("activity"), FLAG_NO_CREATE))
897         .isSameInstanceAs(pendingIntent);
898 
899     // Mismatched Intent action implies inequality.
900     assertThat(PendingIntent.getActivity(context, 99, new Intent("activity2"), FLAG_NO_CREATE))
901         .isNull();
902 
903     // Mismatched requestCode implies inequality.
904     assertThat(PendingIntent.getActivity(context, 999, new Intent("activity"), FLAG_NO_CREATE))
905         .isNull();
906 
907     // Mismatched types imply inequality.
908     assertThat(PendingIntent.getBroadcast(context, 99, new Intent("activity"), FLAG_NO_CREATE))
909         .isNull();
910     assertThat(PendingIntent.getService(context, 99, new Intent("activity"), FLAG_NO_CREATE))
911         .isNull();
912   }
913 
914   @Test
testEquals_getActivities()915   public void testEquals_getActivities() {
916     Intent[] intents = {new Intent("activity"), new Intent("activity2")};
917     PendingIntent pendingIntent = PendingIntent.getActivities(context, 99, intents, 0);
918 
919     Intent[] forward = {new Intent("activity"), new Intent("activity2")};
920     assertThat(PendingIntent.getActivities(context, 99, forward, FLAG_NO_CREATE))
921         .isSameInstanceAs(pendingIntent);
922 
923     Intent[] irrelevant = {new Intent("irrelevant"), new Intent("activity2")};
924     assertThat(PendingIntent.getActivities(context, 99, irrelevant, FLAG_NO_CREATE))
925         .isSameInstanceAs(pendingIntent);
926 
927     Intent single = new Intent("activity2");
928     assertThat(PendingIntent.getActivity(context, 99, single, FLAG_NO_CREATE))
929         .isSameInstanceAs(pendingIntent);
930 
931     Intent[] backward = {new Intent("activity2"), new Intent("activity")};
932     assertThat(PendingIntent.getActivities(context, 99, backward, FLAG_NO_CREATE)).isNull();
933   }
934 
935   @Test
testGetCreatorPackage_nothingSet()936   public void testGetCreatorPackage_nothingSet() {
937     PendingIntent pendingIntent = PendingIntent.getActivity(context, 99, new Intent("activity"), 0);
938     assertThat(pendingIntent.getCreatorPackage()).isEqualTo(context.getPackageName());
939     assertThat(pendingIntent.getTargetPackage()).isEqualTo(context.getPackageName());
940   }
941 
942   @Test
testGetCreatorPackage_explicitlySetPackage()943   public void testGetCreatorPackage_explicitlySetPackage() {
944     String fakePackage = "some.fake.package";
945     PendingIntent pendingIntent = PendingIntent.getActivity(context, 99, new Intent("activity"), 0);
946     shadowOf(pendingIntent).setCreatorPackage(fakePackage);
947     assertThat(pendingIntent.getCreatorPackage()).isEqualTo(fakePackage);
948     assertThat(pendingIntent.getTargetPackage()).isEqualTo(fakePackage);
949   }
950 
951   @Test
testGetCreatorUid()952   public void testGetCreatorUid() {
953     int fakeUid = 123;
954     PendingIntent pendingIntent = PendingIntent.getActivity(context, 99, new Intent("activity"), 0);
955     shadowOf(pendingIntent).setCreatorUid(fakeUid);
956 
957     assertThat(pendingIntent.getCreatorUid()).isEqualTo(fakeUid);
958   }
959 
960   @Test
testHashCode()961   public void testHashCode() {
962     Context ctx = ApplicationProvider.getApplicationContext();
963     PendingIntent pendingIntent1 = PendingIntent.getActivity(ctx, 99, new Intent("activity"), 0);
964 
965     assertThat(pendingIntent1.hashCode())
966         .isEqualTo(PendingIntent.getActivity(ctx, 99, new Intent("activity"), 0).hashCode());
967 
968     assertThat(pendingIntent1.hashCode())
969         .isNotEqualTo(PendingIntent.getActivity(ctx, 99, new Intent("activity2"), 0).hashCode());
970 
971     assertThat(pendingIntent1.hashCode())
972         .isNotEqualTo(PendingIntent.getActivity(ctx, 999, new Intent("activity"), 0).hashCode());
973   }
974 
975   @Test
writeReadPendingIntentOrNullToParcel_returnsNull_whenWriteIsNull()976   public void writeReadPendingIntentOrNullToParcel_returnsNull_whenWriteIsNull() {
977     Parcel parcel = Parcel.obtain();
978     PendingIntent.writePendingIntentOrNullToParcel(null, parcel);
979 
980     parcel.setDataPosition(0);
981     PendingIntent result = PendingIntent.readPendingIntentOrNullFromParcel(parcel);
982 
983     assertThat(result).isNull();
984   }
985 
986   @Test
writeReadPendingIntentOrNullToParcel()987   public void writeReadPendingIntentOrNullToParcel() {
988     PendingIntent original = PendingIntent.getService(context, 100, new Intent(), 0);
989 
990     Parcel parcel = Parcel.obtain();
991     PendingIntent.writePendingIntentOrNullToParcel(original, parcel);
992 
993     parcel.setDataPosition(0);
994     PendingIntent result = PendingIntent.readPendingIntentOrNullFromParcel(parcel);
995 
996     assertThat(result).isEqualTo(original);
997   }
998 
999   @Test
testWriteToParcel()1000   public void testWriteToParcel() {
1001     Intent embedded = new Intent().setComponent(new ComponentName("pkg", "cls"));
1002     PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, embedded, 0);
1003     Parcel parcel = Parcel.obtain();
1004     parcel.writeParcelable(pendingIntent, 0);
1005     parcel.setDataPosition(0);
1006     PendingIntent result = parcel.readParcelable(PendingIntent.class.getClassLoader());
1007     assertThat(result).isEqualTo(pendingIntent);
1008   }
1009 
1010   @Test
toString_doesNotNPE()1011   public void toString_doesNotNPE() {
1012     assertThat(
1013             PendingIntent.getBroadcast(
1014                     ApplicationProvider.getApplicationContext(),
1015                     100,
1016                     new Intent("action"),
1017                     FLAG_ONE_SHOT)
1018                 .toString())
1019         .startsWith("PendingIntent");
1020   }
1021 
1022   @Test
isTargetedToPackage_returnsFalse()1023   public void isTargetedToPackage_returnsFalse() {
1024     Intent embedded = new Intent().setComponent(new ComponentName("pkg", "cls")).setPackage("pkg");
1025     PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, embedded, 0);
1026 
1027     assertThat(pendingIntent.isTargetedToPackage()).isFalse();
1028   }
1029 
1030   @Test
isTargetedToPackage_returnsTrue_whenOnlyComponentSet()1031   public void isTargetedToPackage_returnsTrue_whenOnlyComponentSet() {
1032     Intent embedded = new Intent().setComponent(new ComponentName("pkg", "cls"));
1033     PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, embedded, 0);
1034 
1035     // This is weird but the implementation checks both component and package and this method should
1036     // really be named `isNotExplicitIntentWithPackageSet`.
1037     assertThat(pendingIntent.isTargetedToPackage()).isTrue();
1038   }
1039 
1040   @Test
isTargetedToPackage_returnsTrue()1041   public void isTargetedToPackage_returnsTrue() {
1042     PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, new Intent("ACTION!"), 0);
1043 
1044     // This is weird as well. `isTargetedToPackage` is really `isNotExplicitIntent`.
1045     assertThat(pendingIntent.isTargetedToPackage()).isTrue();
1046   }
1047 }
1048