blob: 3c4e333b6be94e484cc52f150b99fd37c2836c0b [file] [log] [blame]
Jason Monk74f5e362017-12-06 08:56:33 -05001package com.android.server.slice;
2
3import static org.junit.Assert.assertArrayEquals;
4import static org.junit.Assert.assertEquals;
5import static org.junit.Assert.assertFalse;
6import static org.junit.Assert.assertNull;
7import static org.junit.Assert.assertTrue;
8import static org.mockito.ArgumentMatchers.any;
Jason Monk9e3b8642018-01-21 20:54:00 -05009import static org.mockito.ArgumentMatchers.anyInt;
Jason Monk74f5e362017-12-06 08:56:33 -050010import static org.mockito.ArgumentMatchers.anyString;
11import static org.mockito.ArgumentMatchers.argThat;
12import static org.mockito.ArgumentMatchers.eq;
Jason Monk3a1d2e972018-01-29 16:58:11 -050013import static org.mockito.Mockito.doReturn;
Jason Monk74f5e362017-12-06 08:56:33 -050014import static org.mockito.Mockito.mock;
15import static org.mockito.Mockito.verify;
16import static org.mockito.Mockito.when;
17
18import android.app.slice.ISliceListener;
Jason Monk74f5e362017-12-06 08:56:33 -050019import android.app.slice.SliceProvider;
20import android.app.slice.SliceSpec;
21import android.content.ContentProvider;
22import android.content.IContentProvider;
23import android.net.Uri;
Jason Monk9e3b8642018-01-21 20:54:00 -050024import android.os.Binder;
Jason Monk74f5e362017-12-06 08:56:33 -050025import android.os.Handler;
Jason Monk9e3b8642018-01-21 20:54:00 -050026import android.os.IBinder;
27import android.os.IBinder.DeathRecipient;
Jason Monk74f5e362017-12-06 08:56:33 -050028import android.os.RemoteException;
29import android.support.test.filters.SmallTest;
30import android.testing.AndroidTestingRunner;
31import android.testing.TestableLooper;
32import android.testing.TestableLooper.RunWithLooper;
33
34import com.android.server.UiServiceTestCase;
35
36import org.junit.Before;
37import org.junit.Test;
38import org.junit.runner.RunWith;
Jason Monk9e3b8642018-01-21 20:54:00 -050039import org.mockito.ArgumentCaptor;
Jason Monk74f5e362017-12-06 08:56:33 -050040
41@SmallTest
42@RunWith(AndroidTestingRunner.class)
43@RunWithLooper
44public class PinnedSliceStateTest extends UiServiceTestCase {
45
46 private static final String AUTH = "my.authority";
47 private static final Uri TEST_URI = Uri.parse("content://" + AUTH + "/path");
48
49 private static final SliceSpec[] FIRST_SPECS = new SliceSpec[]{
50 new SliceSpec("spec1", 3),
51 new SliceSpec("spec2", 3),
52 new SliceSpec("spec3", 2),
53 new SliceSpec("spec4", 1),
54 };
55
56 private static final SliceSpec[] SECOND_SPECS = new SliceSpec[]{
57 new SliceSpec("spec2", 1),
58 new SliceSpec("spec3", 2),
59 new SliceSpec("spec4", 3),
60 new SliceSpec("spec5", 4),
61 };
62
63 private SliceManagerService mSliceService;
64 private PinnedSliceState mPinnedSliceManager;
65 private IContentProvider mIContentProvider;
66 private ContentProvider mContentProvider;
Jason Monk38df2802018-02-22 19:28:12 -050067 private IBinder mToken = new Binder();
Jason Monk74f5e362017-12-06 08:56:33 -050068
69 @Before
70 public void setup() {
71 mSliceService = mock(SliceManagerService.class);
Jason Monk74f5e362017-12-06 08:56:33 -050072 when(mSliceService.getContext()).thenReturn(mContext);
Jason Monk3a1d2e972018-01-29 16:58:11 -050073 when(mSliceService.getLock()).thenReturn(new Object());
Jason Monk74f5e362017-12-06 08:56:33 -050074 when(mSliceService.getHandler()).thenReturn(new Handler(TestableLooper.get(this).getLooper()));
75 mContentProvider = mock(ContentProvider.class);
76 mIContentProvider = mock(IContentProvider.class);
77 when(mContentProvider.getIContentProvider()).thenReturn(mIContentProvider);
78 mContext.getContentResolver().addProvider(AUTH, mContentProvider);
Jason Monkf88d25e2018-03-06 20:13:24 -050079 mPinnedSliceManager = new PinnedSliceState(mSliceService, TEST_URI, "pkg");
Jason Monk74f5e362017-12-06 08:56:33 -050080 }
81
82 @Test
83 public void testMergeSpecs() {
84 // No annotations to start.
85 assertNull(mPinnedSliceManager.getSpecs());
86
87 mPinnedSliceManager.mergeSpecs(FIRST_SPECS);
88 assertArrayEquals(FIRST_SPECS, mPinnedSliceManager.getSpecs());
89
90 mPinnedSliceManager.mergeSpecs(SECOND_SPECS);
91 assertArrayEquals(new SliceSpec[]{
92 // spec1 is gone because it's not in the second set.
93 new SliceSpec("spec2", 1), // spec2 is 1 because it's smaller in the second set.
94 new SliceSpec("spec3", 2), // spec3 is the same in both sets
95 new SliceSpec("spec4", 1), // spec4 is 1 because it's smaller in the first set.
96 // spec5 is gone because it's not in the first set.
97 }, mPinnedSliceManager.getSpecs());
98 }
99
100 @Test
Jason Monk3a1d2e972018-01-29 16:58:11 -0500101 public void testSendPinnedOnPin() throws RemoteException {
102 TestableLooper.get(this).processAllMessages();
103
104 // When pinned for the first time, a pinned message should be sent.
Jason Monk38df2802018-02-22 19:28:12 -0500105 mPinnedSliceManager.pin("pkg", FIRST_SPECS, mToken);
Jason Monk74f5e362017-12-06 08:56:33 -0500106 TestableLooper.get(this).processAllMessages();
107
108 verify(mIContentProvider).call(anyString(), eq(SliceProvider.METHOD_PIN), eq(null),
109 argThat(b -> {
110 assertEquals(TEST_URI, b.getParcelable(SliceProvider.EXTRA_BIND_URI));
111 return true;
112 }));
113 }
114
115 @Test
Jason Monk74f5e362017-12-06 08:56:33 -0500116 public void testPkgPin() {
Jason Monk3a1d2e972018-01-29 16:58:11 -0500117 assertFalse(mPinnedSliceManager.hasPinOrListener());
Jason Monk74f5e362017-12-06 08:56:33 -0500118
Jason Monk38df2802018-02-22 19:28:12 -0500119 mPinnedSliceManager.pin("pkg", FIRST_SPECS, mToken);
Jason Monk3a1d2e972018-01-29 16:58:11 -0500120 assertTrue(mPinnedSliceManager.hasPinOrListener());
Jason Monk74f5e362017-12-06 08:56:33 -0500121
Jason Monk38df2802018-02-22 19:28:12 -0500122 assertTrue(mPinnedSliceManager.unpin("pkg", mToken));
Jason Monk3a1d2e972018-01-29 16:58:11 -0500123 assertFalse(mPinnedSliceManager.hasPinOrListener());
Jason Monk74f5e362017-12-06 08:56:33 -0500124 }
125
126 @Test
127 public void testMultiPkgPin() {
Jason Monk38df2802018-02-22 19:28:12 -0500128 IBinder t2 = new Binder();
Jason Monk3a1d2e972018-01-29 16:58:11 -0500129 assertFalse(mPinnedSliceManager.hasPinOrListener());
Jason Monk74f5e362017-12-06 08:56:33 -0500130
Jason Monk38df2802018-02-22 19:28:12 -0500131 mPinnedSliceManager.pin("pkg", FIRST_SPECS, mToken);
Jason Monk3a1d2e972018-01-29 16:58:11 -0500132 assertTrue(mPinnedSliceManager.hasPinOrListener());
Jason Monk38df2802018-02-22 19:28:12 -0500133 mPinnedSliceManager.pin("pkg2", FIRST_SPECS, t2);
Jason Monk74f5e362017-12-06 08:56:33 -0500134
Jason Monk38df2802018-02-22 19:28:12 -0500135 assertFalse(mPinnedSliceManager.unpin("pkg", mToken));
136 assertTrue(mPinnedSliceManager.unpin("pkg2", t2));
Jason Monk3a1d2e972018-01-29 16:58:11 -0500137 assertFalse(mPinnedSliceManager.hasPinOrListener());
Jason Monk74f5e362017-12-06 08:56:33 -0500138 }
139
140 @Test
Jason Monk9e3b8642018-01-21 20:54:00 -0500141 public void testListenerDeath() throws RemoteException {
142 ISliceListener listener = mock(ISliceListener.class);
143 IBinder binder = mock(IBinder.class);
144 when(binder.isBinderAlive()).thenReturn(true);
145 when(listener.asBinder()).thenReturn(binder);
Jason Monk3a1d2e972018-01-29 16:58:11 -0500146 assertFalse(mPinnedSliceManager.hasPinOrListener());
Jason Monk9e3b8642018-01-21 20:54:00 -0500147
Jason Monk38df2802018-02-22 19:28:12 -0500148 mPinnedSliceManager.pin(mContext.getPackageName(), FIRST_SPECS, binder);
Jason Monk3a1d2e972018-01-29 16:58:11 -0500149 assertTrue(mPinnedSliceManager.hasPinOrListener());
Jason Monk9e3b8642018-01-21 20:54:00 -0500150
151 ArgumentCaptor<DeathRecipient> arg = ArgumentCaptor.forClass(DeathRecipient.class);
152 verify(binder).linkToDeath(arg.capture(), anyInt());
153
154 when(binder.isBinderAlive()).thenReturn(false);
155 arg.getValue().binderDied();
156
157 verify(mSliceService).removePinnedSlice(eq(TEST_URI));
Jason Monk3a1d2e972018-01-29 16:58:11 -0500158 assertFalse(mPinnedSliceManager.hasPinOrListener());
Jason Monk9e3b8642018-01-21 20:54:00 -0500159 }
Jason Monkf88d25e2018-03-06 20:13:24 -0500160}