blob: 4c2822af264cdcc5beabadbba8c1e7dbb073f212 [file] [log] [blame]
Jason Monk74f5e362017-12-06 08:56:33 -05001package com.android.server.slice;
2
Jason Monke1c0c2c2018-07-03 11:08:32 -04003import static android.testing.TestableContentResolver.UNSTABLE;
4
Jason Monk74f5e362017-12-06 08:56:33 -05005import static org.junit.Assert.assertArrayEquals;
6import static org.junit.Assert.assertEquals;
7import static org.junit.Assert.assertFalse;
8import static org.junit.Assert.assertNull;
9import static org.junit.Assert.assertTrue;
Jason Monk9e3b8642018-01-21 20:54:00 -050010import static org.mockito.ArgumentMatchers.anyInt;
Jason Monk74f5e362017-12-06 08:56:33 -050011import static org.mockito.ArgumentMatchers.anyString;
12import static org.mockito.ArgumentMatchers.argThat;
13import static org.mockito.ArgumentMatchers.eq;
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;
Jason Monk74f5e362017-12-06 08:56:33 -050029import android.testing.AndroidTestingRunner;
30import android.testing.TestableLooper;
31import android.testing.TestableLooper.RunWithLooper;
32
Brett Chabot84151d92019-02-27 15:37:59 -080033import androidx.test.filters.SmallTest;
34
Jason Monk74f5e362017-12-06 08:56:33 -050035import com.android.server.UiServiceTestCase;
36
37import org.junit.Before;
38import org.junit.Test;
39import org.junit.runner.RunWith;
Jason Monk9e3b8642018-01-21 20:54:00 -050040import org.mockito.ArgumentCaptor;
Jason Monk74f5e362017-12-06 08:56:33 -050041
42@SmallTest
43@RunWith(AndroidTestingRunner.class)
44@RunWithLooper
45public class PinnedSliceStateTest extends UiServiceTestCase {
46
47 private static final String AUTH = "my.authority";
48 private static final Uri TEST_URI = Uri.parse("content://" + AUTH + "/path");
49
50 private static final SliceSpec[] FIRST_SPECS = new SliceSpec[]{
51 new SliceSpec("spec1", 3),
52 new SliceSpec("spec2", 3),
53 new SliceSpec("spec3", 2),
54 new SliceSpec("spec4", 1),
55 };
56
57 private static final SliceSpec[] SECOND_SPECS = new SliceSpec[]{
58 new SliceSpec("spec2", 1),
59 new SliceSpec("spec3", 2),
60 new SliceSpec("spec4", 3),
61 new SliceSpec("spec5", 4),
62 };
63
64 private SliceManagerService mSliceService;
65 private PinnedSliceState mPinnedSliceManager;
66 private IContentProvider mIContentProvider;
67 private ContentProvider mContentProvider;
Jason Monk38df2802018-02-22 19:28:12 -050068 private IBinder mToken = new Binder();
Jason Monk74f5e362017-12-06 08:56:33 -050069
70 @Before
71 public void setup() {
72 mSliceService = mock(SliceManagerService.class);
Jason Monk74f5e362017-12-06 08:56:33 -050073 when(mSliceService.getContext()).thenReturn(mContext);
Jason Monk3a1d2e972018-01-29 16:58:11 -050074 when(mSliceService.getLock()).thenReturn(new Object());
Jason Monke1c0c2c2018-07-03 11:08:32 -040075 when(mSliceService.getHandler()).thenReturn(
76 new Handler(TestableLooper.get(this).getLooper()));
Jason Monk74f5e362017-12-06 08:56:33 -050077 mContentProvider = mock(ContentProvider.class);
78 mIContentProvider = mock(IContentProvider.class);
79 when(mContentProvider.getIContentProvider()).thenReturn(mIContentProvider);
Jason Monke1c0c2c2018-07-03 11:08:32 -040080 mContext.getContentResolver().addProvider(AUTH, mContentProvider, UNSTABLE);
Jason Monkf88d25e2018-03-06 20:13:24 -050081 mPinnedSliceManager = new PinnedSliceState(mSliceService, TEST_URI, "pkg");
Jason Monk74f5e362017-12-06 08:56:33 -050082 }
83
84 @Test
85 public void testMergeSpecs() {
86 // No annotations to start.
87 assertNull(mPinnedSliceManager.getSpecs());
88
89 mPinnedSliceManager.mergeSpecs(FIRST_SPECS);
90 assertArrayEquals(FIRST_SPECS, mPinnedSliceManager.getSpecs());
91
92 mPinnedSliceManager.mergeSpecs(SECOND_SPECS);
93 assertArrayEquals(new SliceSpec[]{
94 // spec1 is gone because it's not in the second set.
95 new SliceSpec("spec2", 1), // spec2 is 1 because it's smaller in the second set.
96 new SliceSpec("spec3", 2), // spec3 is the same in both sets
97 new SliceSpec("spec4", 1), // spec4 is 1 because it's smaller in the first set.
98 // spec5 is gone because it's not in the first set.
99 }, mPinnedSliceManager.getSpecs());
100 }
101
102 @Test
Jason Monk3a1d2e972018-01-29 16:58:11 -0500103 public void testSendPinnedOnPin() throws RemoteException {
104 TestableLooper.get(this).processAllMessages();
105
106 // When pinned for the first time, a pinned message should be sent.
Jason Monk38df2802018-02-22 19:28:12 -0500107 mPinnedSliceManager.pin("pkg", FIRST_SPECS, mToken);
Jason Monk74f5e362017-12-06 08:56:33 -0500108 TestableLooper.get(this).processAllMessages();
109
Jeff Sharkey633a13e2018-12-07 12:00:45 -0700110 verify(mIContentProvider).call(anyString(), anyString(), eq(SliceProvider.METHOD_PIN),
111 eq(null), argThat(b -> {
Jason Monk74f5e362017-12-06 08:56:33 -0500112 assertEquals(TEST_URI, b.getParcelable(SliceProvider.EXTRA_BIND_URI));
113 return true;
114 }));
115 }
116
117 @Test
Jason Monk74f5e362017-12-06 08:56:33 -0500118 public void testPkgPin() {
Jason Monk3a1d2e972018-01-29 16:58:11 -0500119 assertFalse(mPinnedSliceManager.hasPinOrListener());
Jason Monk74f5e362017-12-06 08:56:33 -0500120
Jason Monk38df2802018-02-22 19:28:12 -0500121 mPinnedSliceManager.pin("pkg", FIRST_SPECS, mToken);
Jason Monk3a1d2e972018-01-29 16:58:11 -0500122 assertTrue(mPinnedSliceManager.hasPinOrListener());
Jason Monk74f5e362017-12-06 08:56:33 -0500123
Jason Monk38df2802018-02-22 19:28:12 -0500124 assertTrue(mPinnedSliceManager.unpin("pkg", mToken));
Jason Monk3a1d2e972018-01-29 16:58:11 -0500125 assertFalse(mPinnedSliceManager.hasPinOrListener());
Jason Monk74f5e362017-12-06 08:56:33 -0500126 }
127
128 @Test
129 public void testMultiPkgPin() {
Jason Monk38df2802018-02-22 19:28:12 -0500130 IBinder t2 = new Binder();
Jason Monk3a1d2e972018-01-29 16:58:11 -0500131 assertFalse(mPinnedSliceManager.hasPinOrListener());
Jason Monk74f5e362017-12-06 08:56:33 -0500132
Jason Monk38df2802018-02-22 19:28:12 -0500133 mPinnedSliceManager.pin("pkg", FIRST_SPECS, mToken);
Jason Monk3a1d2e972018-01-29 16:58:11 -0500134 assertTrue(mPinnedSliceManager.hasPinOrListener());
Jason Monk38df2802018-02-22 19:28:12 -0500135 mPinnedSliceManager.pin("pkg2", FIRST_SPECS, t2);
Jason Monk74f5e362017-12-06 08:56:33 -0500136
Jason Monk38df2802018-02-22 19:28:12 -0500137 assertFalse(mPinnedSliceManager.unpin("pkg", mToken));
138 assertTrue(mPinnedSliceManager.unpin("pkg2", t2));
Jason Monk3a1d2e972018-01-29 16:58:11 -0500139 assertFalse(mPinnedSliceManager.hasPinOrListener());
Jason Monk74f5e362017-12-06 08:56:33 -0500140 }
141
142 @Test
Jason Monk9e3b8642018-01-21 20:54:00 -0500143 public void testListenerDeath() throws RemoteException {
144 ISliceListener listener = mock(ISliceListener.class);
145 IBinder binder = mock(IBinder.class);
146 when(binder.isBinderAlive()).thenReturn(true);
147 when(listener.asBinder()).thenReturn(binder);
Jason Monk3a1d2e972018-01-29 16:58:11 -0500148 assertFalse(mPinnedSliceManager.hasPinOrListener());
Jason Monk9e3b8642018-01-21 20:54:00 -0500149
Jason Monk38df2802018-02-22 19:28:12 -0500150 mPinnedSliceManager.pin(mContext.getPackageName(), FIRST_SPECS, binder);
Jason Monk3a1d2e972018-01-29 16:58:11 -0500151 assertTrue(mPinnedSliceManager.hasPinOrListener());
Jason Monk9e3b8642018-01-21 20:54:00 -0500152
153 ArgumentCaptor<DeathRecipient> arg = ArgumentCaptor.forClass(DeathRecipient.class);
154 verify(binder).linkToDeath(arg.capture(), anyInt());
155
156 when(binder.isBinderAlive()).thenReturn(false);
157 arg.getValue().binderDied();
158
159 verify(mSliceService).removePinnedSlice(eq(TEST_URI));
Jason Monk3a1d2e972018-01-29 16:58:11 -0500160 assertFalse(mPinnedSliceManager.hasPinOrListener());
Jason Monk9e3b8642018-01-21 20:54:00 -0500161 }
Jason Monkf88d25e2018-03-06 20:13:24 -0500162}