1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 * except in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the 10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11 * KIND, either express or implied. See the License for the specific language governing 12 * permissions and limitations under the License. 13 */ 14 15 package com.android.server.slice; 16 17 import static android.content.ContentProvider.maybeAddUserId; 18 import static android.content.pm.PackageManager.PERMISSION_DENIED; 19 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20 21 import static org.junit.Assert.assertEquals; 22 import static org.mockito.ArgumentMatchers.any; 23 import static org.mockito.ArgumentMatchers.anyInt; 24 import static org.mockito.ArgumentMatchers.anyString; 25 import static org.mockito.ArgumentMatchers.eq; 26 import static org.mockito.Mockito.doReturn; 27 import static org.mockito.Mockito.mock; 28 import static org.mockito.Mockito.never; 29 import static org.mockito.Mockito.spy; 30 import static org.mockito.Mockito.times; 31 import static org.mockito.Mockito.verify; 32 import static org.mockito.Mockito.when; 33 34 import android.app.AppOpsManager; 35 import android.app.slice.SliceSpec; 36 import android.app.usage.UsageStatsManagerInternal; 37 import android.net.Uri; 38 import android.os.Binder; 39 import android.os.IBinder; 40 import android.os.Process; 41 import android.os.RemoteException; 42 import android.testing.AndroidTestingRunner; 43 import android.testing.TestableContext; 44 import android.testing.TestableLooper; 45 import android.testing.TestableLooper.RunWithLooper; 46 47 import androidx.test.filters.SmallTest; 48 49 import com.android.server.LocalServices; 50 import com.android.server.UiServiceTestCase; 51 52 import org.junit.After; 53 import org.junit.Before; 54 import org.junit.Ignore; 55 import org.junit.Test; 56 import org.junit.runner.RunWith; 57 58 @SmallTest 59 @RunWith(AndroidTestingRunner.class) 60 @RunWithLooper 61 public class SliceManagerServiceTest extends UiServiceTestCase { 62 63 private static final String AUTH = "com.android.services.uitests"; 64 private static final Uri TEST_URI = Uri.parse("content://" + AUTH + "/path"); 65 66 private static final SliceSpec[] EMPTY_SPECS = new SliceSpec[]{ 67 }; 68 69 private SliceManagerService mService; 70 private PinnedSliceState mCreatedSliceState; 71 private IBinder mToken = new Binder(); 72 private TestableContext mContextSpy; 73 74 @Before setUp()75 public void setUp() { 76 LocalServices.addService(UsageStatsManagerInternal.class, 77 mock(UsageStatsManagerInternal.class)); 78 mContext.addMockSystemService(AppOpsManager.class, mock(AppOpsManager.class)); 79 80 mContextSpy = spy(mContext); 81 mService = spy(new SliceManagerService(mContextSpy, TestableLooper.get(this).getLooper())); 82 mCreatedSliceState = mock(PinnedSliceState.class); 83 doReturn(mCreatedSliceState).when(mService).createPinnedSlice(eq(TEST_URI), anyString()); 84 } 85 86 @After teardown()87 public void teardown() { 88 LocalServices.removeServiceForTest(UsageStatsManagerInternal.class); 89 } 90 91 @Ignore("b/253871109") 92 @Test testAddPinCreatesPinned()93 public void testAddPinCreatesPinned() throws RemoteException { 94 grantSlicePermission(); 95 doReturn("pkg").when(mService).getDefaultHome(anyInt()); 96 97 mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS, mToken); 98 mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS, mToken); 99 verify(mService, times(1)).createPinnedSlice(eq(maybeAddUserId(TEST_URI, 0)), anyString()); 100 } 101 102 @Ignore("b/253871109") 103 @Test testRemovePinDestroysPinned()104 public void testRemovePinDestroysPinned() throws RemoteException { 105 grantSlicePermission(); 106 doReturn("pkg").when(mService).getDefaultHome(anyInt()); 107 108 mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS, mToken); 109 110 when(mCreatedSliceState.unpin(eq("pkg"), eq(mToken))).thenReturn(false); 111 mService.unpinSlice("pkg", TEST_URI, mToken); 112 verify(mCreatedSliceState, never()).destroy(); 113 } 114 115 @Ignore("b/253871109") 116 @Test testCheckAutoGrantPermissions()117 public void testCheckAutoGrantPermissions() throws RemoteException { 118 String[] testPerms = new String[] { 119 "perm1", 120 "perm2", 121 }; 122 when(mContextSpy.checkUriPermission(any(), anyInt(), anyInt(), anyInt())) 123 .thenReturn(PERMISSION_DENIED); 124 when(mContextSpy.checkPermission("perm1", Process.myPid(), Process.myUid())) 125 .thenReturn(PERMISSION_DENIED); 126 when(mContextSpy.checkPermission("perm2", Process.myPid(), Process.myUid())) 127 .thenReturn(PERMISSION_GRANTED); 128 mService.checkSlicePermission(TEST_URI, mContext.getPackageName(), 129 Process.myPid(), Process.myUid(), testPerms); 130 131 verify(mContextSpy).checkPermission(eq("perm1"), eq(Process.myPid()), eq(Process.myUid())); 132 verify(mContextSpy).checkPermission(eq("perm2"), eq(Process.myPid()), eq(Process.myUid())); 133 } 134 135 @Ignore("b/253871109") 136 @Test(expected = IllegalStateException.class) testNoPinThrow()137 public void testNoPinThrow() throws Exception { 138 grantSlicePermission(); 139 mService.getPinnedSpecs(TEST_URI, "pkg"); 140 } 141 142 @Ignore("b/253871109") 143 @Test testGetPinnedSpecs()144 public void testGetPinnedSpecs() throws Exception { 145 grantSlicePermission(); 146 SliceSpec[] specs = new SliceSpec[] { 147 new SliceSpec("Something", 1) }; 148 mService.pinSlice("pkg", TEST_URI, specs, mToken); 149 150 when(mCreatedSliceState.getSpecs()).thenReturn(specs); 151 assertEquals(specs, mService.getPinnedSpecs(TEST_URI, "pkg")); 152 } 153 grantSlicePermission()154 private void grantSlicePermission() { 155 doReturn(PERMISSION_GRANTED).when(mService).checkSlicePermission( 156 eq(TEST_URI), anyString(), anyInt(), anyInt(), any()); 157 doReturn(PERMISSION_GRANTED).when(mService).checkAccess( 158 anyString(), eq(TEST_URI), anyInt(), anyInt()); 159 } 160 } 161