1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.internal.app; 18 19 import static org.hamcrest.CoreMatchers.is; 20 import static org.hamcrest.MatcherAssert.assertThat; 21 import static org.mockito.Matchers.any; 22 import static org.mockito.Matchers.anyInt; 23 import static org.mockito.Matchers.anyLong; 24 import static org.mockito.Matchers.anyString; 25 import static org.mockito.Mockito.doAnswer; 26 import static org.mockito.Mockito.when; 27 28 import org.junit.Before; 29 import org.junit.Test; 30 import org.junit.runner.RunWith; 31 32 import org.mockito.invocation.InvocationOnMock; 33 import org.mockito.Mock; 34 import org.mockito.Mockito; 35 import org.mockito.MockitoAnnotations; 36 import org.mockito.stubbing.Answer; 37 38 import android.app.usage.IUsageStatsManager; 39 import android.app.usage.UsageStats; 40 import android.app.usage.UsageStatsManager; 41 import android.content.Context; 42 import android.content.pm.PackageManager; 43 import android.content.pm.ParceledListSlice; 44 import android.content.pm.ResolveInfo; 45 import android.content.res.Configuration; 46 import android.content.res.Resources; 47 import android.content.Intent; 48 import android.os.RemoteException; 49 import android.os.UserHandle; 50 import android.support.test.runner.AndroidJUnit4; 51 import android.util.ArrayMap; 52 53 import java.io.File; 54 import java.util.ArrayList; 55 import java.util.HashMap; 56 import java.util.List; 57 import java.util.Locale; 58 import java.util.Map; 59 60 /** 61 * ResolverListController Test. 62 */ 63 @RunWith(AndroidJUnit4.class) 64 public class ResolverListControllerTest { 65 66 @Mock private Context mMockContext; 67 @Mock private PackageManager mMockPackageManager; 68 @Mock private Resources mMockResources; 69 @Mock private IUsageStatsManager mMockService; 70 71 private ResolverListController mController; 72 private UsageStatsManager mUsm; 73 74 @Before 75 public void setUp() throws Exception { 76 MockitoAnnotations.initMocks(this); 77 Configuration config = new Configuration(); 78 config.locale = Locale.getDefault(); 79 List<ResolveInfo> services = new ArrayList<>(); 80 when(mMockPackageManager.queryIntentServices(any(), anyInt())).thenReturn(services); 81 when(mMockResources.getConfiguration()).thenReturn(config); 82 when(mMockContext.getResources()).thenReturn(mMockResources); 83 when(mMockContext.getPackageName()).thenReturn("android"); 84 when(mMockContext.getUserId()).thenReturn(54321); 85 when(mMockContext.getSharedPreferences(anyString(), anyInt())).thenReturn(null); 86 when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager); 87 } 88 89 @Test 90 public void reportChooserSelection() throws InterruptedException, RemoteException { 91 String annotation = "test_annotation"; 92 Intent sendIntent = createSendImageIntent(annotation); 93 String refererPackage = "test_referer_package"; 94 String packageName = "test_package"; 95 String action = "test_action"; 96 final int initialCount = 1234; 97 UsageStats packageStats = initStats(packageName, action, annotation, initialCount); 98 UsageStats oneClickStats = initStats(packageName, action, annotation, 1); 99 final List<UsageStats> slices = new ArrayList<>(); 100 slices.add(packageStats); 101 ParceledListSlice<UsageStats> stats = new ParceledListSlice<>(slices); 102 when(mMockService.queryUsageStats(anyInt(), anyLong(), anyLong(), anyString())) 103 .thenReturn(stats); 104 Answer<Void> answer = new Answer<Void>() { 105 @Override 106 public Void answer(InvocationOnMock invocation) throws Throwable { 107 slices.add(oneClickStats); 108 return null; 109 } 110 }; 111 doAnswer(answer).when(mMockService).reportChooserSelection( 112 anyString(), anyInt(), anyString(), any(), anyString()); 113 when(mMockContext.getOpPackageName()).thenReturn(refererPackage); 114 mUsm = new UsageStatsManager(mMockContext, mMockService); 115 when(mMockContext.getSystemService(Context.USAGE_STATS_SERVICE)).thenReturn(mUsm); 116 mController = new ResolverListController(mMockContext, mMockPackageManager, sendIntent, 117 refererPackage, UserHandle.USER_CURRENT); 118 mController.sort(new ArrayList<ResolverActivity.ResolvedComponentInfo>()); 119 long beforeReport = getCount(mUsm, packageName, action, annotation); 120 mController.updateChooserCounts(packageName, UserHandle.USER_CURRENT, action); 121 long afterReport = getCount(mUsm, packageName, action, annotation); 122 assertThat(afterReport, is(beforeReport + 1l)); 123 } 124 125 private UsageStats initStats(String packageName, String action, 126 String annotation, int count) { 127 ArrayMap<String, ArrayMap<String, Integer>> chooserCounts = new ArrayMap<>(); 128 ArrayMap<String, Integer> counts = new ArrayMap<>(); 129 counts.put(annotation, count); 130 chooserCounts.put(action, counts); 131 UsageStats packageStats = new UsageStats(); 132 packageStats.mPackageName = packageName; 133 packageStats.mChooserCounts = chooserCounts; 134 return packageStats; 135 } 136 137 private Intent createSendImageIntent(String annotation) { 138 Intent sendIntent = new Intent(); 139 sendIntent.setAction(Intent.ACTION_SEND); 140 sendIntent.putExtra(Intent.EXTRA_TEXT, "testing intent sending"); 141 sendIntent.setType("image/jpeg"); 142 ArrayList<String> annotations = new ArrayList<>(); 143 annotations.add(annotation); 144 sendIntent.putStringArrayListExtra(Intent.EXTRA_CONTENT_ANNOTATIONS, annotations); 145 return sendIntent; 146 } 147 148 private Integer getCount( 149 UsageStatsManager usm, String packageName, String action, String annotation) { 150 if (usm == null) { 151 return 0; 152 } 153 Map<String, UsageStats> stats = 154 usm.queryAndAggregateUsageStats(Long.MIN_VALUE, Long.MAX_VALUE); 155 UsageStats packageStats = stats.get(packageName); 156 if (packageStats == null || packageStats.mChooserCounts == null 157 || packageStats.mChooserCounts.get(action) == null) { 158 return 0; 159 } 160 return packageStats.mChooserCounts.get(action).getOrDefault(annotation, 0); 161 } 162 }