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 android.ext.services.storage; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.mockito.Mockito.when; 22 23 import android.app.usage.CacheQuotaHint; 24 import android.app.usage.UsageStats; 25 import android.content.Context; 26 import android.content.ContextWrapper; 27 import android.content.Intent; 28 import android.os.Environment; 29 import android.os.UserHandle; 30 import android.os.storage.StorageManager; 31 import android.os.storage.StorageVolume; 32 import android.test.ServiceTestCase; 33 34 import org.junit.Before; 35 import org.junit.Test; 36 import org.mockito.Answers; 37 import org.mockito.Mock; 38 import org.mockito.Mockito; 39 import org.mockito.MockitoAnnotations; 40 41 import java.io.File; 42 import java.util.ArrayList; 43 import java.util.List; 44 45 public class CacheQuotaServiceImplTest extends ServiceTestCase<CacheQuotaServiceImpl> { 46 private static final String sTestVolUuid = "uuid"; 47 private static final String sSecondTestVolUuid = "otherUuid"; 48 49 private List<StorageVolume> mStorageVolumes = new ArrayList<>(); 50 @Mock private Context mContext; 51 @Mock private File mFile; 52 @Mock(answer = Answers.RETURNS_DEEP_STUBS) private StorageManager mStorageManager; 53 CacheQuotaServiceImplTest()54 public CacheQuotaServiceImplTest() { 55 super(CacheQuotaServiceImpl.class); 56 } 57 58 @Before setUp()59 public void setUp() throws Exception { 60 super.setUp(); 61 MockitoAnnotations.initMocks(this); 62 mContext = Mockito.spy(new ContextWrapper(getSystemContext())); 63 setContext(mContext); 64 mStorageVolumes.add(makeNewStorageVolume("1", mFile, sTestVolUuid)); 65 66 when(mContext.getSystemService(Context.STORAGE_SERVICE)).thenReturn(mStorageManager); 67 when(mStorageManager.getStorageVolumes()).thenReturn(mStorageVolumes); 68 when(mFile.getUsableSpace()).thenReturn(10000L); 69 70 Intent intent = new Intent(getContext(), CacheQuotaServiceImpl.class); 71 startService(intent); 72 } 73 74 @Test testNoApps()75 public void testNoApps() { 76 CacheQuotaServiceImpl service = getService(); 77 assertEquals(service.onComputeCacheQuotaHints(new ArrayList()).size(), 0); 78 } 79 80 @Test testOneApp()81 public void testOneApp() throws Exception { 82 ArrayList<CacheQuotaHint> requests = new ArrayList<>(); 83 CacheQuotaHint request = makeNewRequest("com.test", sTestVolUuid, 1001, 100L); 84 requests.add(request); 85 86 List<CacheQuotaHint> output = getService().onComputeCacheQuotaHints(requests); 87 88 assertThat(output).hasSize(1); 89 assertThat(output.get(0).getQuota()).isEqualTo(1500L); 90 } 91 92 @Test testTwoAppsOneVolume()93 public void testTwoAppsOneVolume() throws Exception { 94 ArrayList<CacheQuotaHint> requests = new ArrayList<>(); 95 requests.add(makeNewRequest("com.test", sTestVolUuid, 1001, 100L)); 96 requests.add(makeNewRequest("com.test2", sTestVolUuid, 1002, 99L)); 97 98 List<CacheQuotaHint> output = getService().onComputeCacheQuotaHints(requests); 99 100 // Note that the sizes are just the cache area split up. 101 assertThat(output).hasSize(2); 102 assertThat(output.get(0).getQuota()).isEqualTo(883); 103 assertThat(output.get(1).getQuota()).isEqualTo(1500 - 883); 104 } 105 106 @Test testTwoAppsTwoVolumes()107 public void testTwoAppsTwoVolumes() throws Exception { 108 mStorageVolumes.add(makeNewStorageVolume("2", mFile, sSecondTestVolUuid)); 109 ArrayList<CacheQuotaHint> requests = new ArrayList<>(); 110 requests.add(makeNewRequest("com.test", sTestVolUuid, 1001, 100L)); 111 requests.add(makeNewRequest("com.test2", sSecondTestVolUuid, 1002, 99L)); 112 113 List<CacheQuotaHint> output = getService().onComputeCacheQuotaHints(requests); 114 115 assertThat(output).hasSize(2); 116 assertThat(output.get(0).getQuota()).isEqualTo(1500); 117 assertThat(output.get(1).getQuota()).isEqualTo(1500); 118 } 119 120 @Test testMultipleAppsPerUidIsCollated()121 public void testMultipleAppsPerUidIsCollated() throws Exception { 122 ArrayList<CacheQuotaHint> requests = new ArrayList<>(); 123 requests.add(makeNewRequest("com.test", sTestVolUuid, 1001, 100L)); 124 requests.add(makeNewRequest("com.test2", sTestVolUuid, 1001, 99L)); 125 126 List<CacheQuotaHint> output = getService().onComputeCacheQuotaHints(requests); 127 128 assertThat(output).hasSize(1); 129 assertThat(output.get(0).getQuota()).isEqualTo(1500); 130 } 131 132 @Test testTwoAppsTwoVolumesTwoUuidsShouldBESeparate()133 public void testTwoAppsTwoVolumesTwoUuidsShouldBESeparate() throws Exception { 134 mStorageVolumes.add(makeNewStorageVolume("2", mFile, sSecondTestVolUuid)); 135 ArrayList<CacheQuotaHint> requests = new ArrayList<>(); 136 requests.add(makeNewRequest("com.test", sTestVolUuid, 1001, 100L)); 137 requests.add(makeNewRequest("com.test2", sSecondTestVolUuid, 1001, 99L)); 138 139 List<CacheQuotaHint> output = getService().onComputeCacheQuotaHints(requests); 140 141 assertThat(output).hasSize(2); 142 assertThat(output.get(0).getQuota()).isEqualTo(1500); 143 assertThat(output.get(1).getQuota()).isEqualTo(1500); 144 } 145 makeNewRequest(String packageName, String uuid, int uid, long foregroundTime)146 private CacheQuotaHint makeNewRequest(String packageName, String uuid, int uid, 147 long foregroundTime) { 148 UsageStats stats = new UsageStats(); 149 stats.mPackageName = packageName; 150 stats.mTotalTimeInForeground = foregroundTime; 151 return new CacheQuotaHint.Builder() 152 .setVolumeUuid(uuid).setUid(uid).setUsageStats(stats).setQuota(-1).build(); 153 } 154 makeNewStorageVolume(String id, File path, String fsUuid)155 private StorageVolume makeNewStorageVolume(String id, File path, String fsUuid) { 156 return new StorageVolume(id, path, path, /* description */ "", /* primary */ false, 157 /* removable */ false, /* emulated */ true, /* allowMassStorage */ false, 158 /* maxFileSize */ -1, UserHandle.CURRENT, fsUuid, Environment.MEDIA_MOUNTED); 159 } 160 } 161