1090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi/* 2090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi * Copyright (C) 2016 The Android Open Source Project 3090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi * 4090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi * Licensed under the Apache License, Version 2.0 (the "License"); 5090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi * you may not use this file except in compliance with the License. 6090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi * You may obtain a copy of the License at 7090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi * 8090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi * http://www.apache.org/licenses/LICENSE-2.0 9090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi * 10090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi * Unless required by applicable law or agreed to in writing, software 11090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi * distributed under the License is distributed on an "AS IS" BASIS, 12090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi * See the License for the specific language governing permissions and 14090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi * limitations under the License. 15090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi */ 16090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi 17090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishipackage com.android.server.storage; 18090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi 19090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishiimport static com.google.common.truth.Truth.assertThat; 20090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi 21cf76a16e660a361670745b043198b797ccd86747Daniel Nishiimport static org.mockito.Matchers.any; 22090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishiimport static org.mockito.Matchers.anyInt; 235d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishiimport static org.mockito.Matchers.anyLong; 245d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishiimport static org.mockito.Matchers.anyString; 255d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishiimport static org.mockito.Matchers.isNull; 265d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishiimport static org.mockito.Mockito.doReturn; 273cf3b199e3e120f23f54eb7f9905c8d285cb8a28Daniel Nishiimport static org.mockito.Mockito.mock; 285d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishiimport static org.mockito.Mockito.spy; 29090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishiimport static org.mockito.Mockito.when; 30090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi 31cf76a16e660a361670745b043198b797ccd86747Daniel Nishiimport android.app.job.JobService; 325d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishiimport android.app.job.JobServiceEngine; 335d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishiimport android.app.usage.ExternalStorageStats; 345d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishiimport android.app.usage.StorageStatsManager; 355d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishiimport android.content.Context; 365d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishiimport android.content.pm.PackageManager; 37090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishiimport android.content.pm.PackageStats; 385d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishiimport android.os.BatteryManager; 395d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishiimport android.os.UserHandle; 405d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishiimport android.os.UserManager; 415d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishiimport android.os.storage.StorageManager; 425d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishiimport android.os.storage.VolumeInfo; 435d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishiimport android.provider.Settings; 44090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishiimport android.test.AndroidTestCase; 455d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishiimport android.test.mock.MockContentResolver; 46090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi 475d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishiimport com.android.internal.util.test.FakeSettingsProvider; 48090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishiimport com.android.server.storage.DiskStatsLoggingService.LogRunnable; 49090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi 50090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishiimport libcore.io.IoUtils; 51090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi 52090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishiimport org.json.JSONObject; 53090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishiimport org.junit.Before; 54090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishiimport org.junit.Rule; 55090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishiimport org.junit.Test; 56090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishiimport org.junit.rules.TemporaryFolder; 57090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishiimport org.junit.runner.RunWith; 58090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishiimport org.junit.runners.JUnit4; 59090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishiimport org.mockito.Mock; 60090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishiimport org.mockito.MockitoAnnotations; 61090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi 62090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishiimport java.io.File; 63090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishiimport java.io.PrintStream; 645d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishiimport java.lang.reflect.Field; 65090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishiimport java.util.ArrayList; 66090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi 67090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi@RunWith(JUnit4.class) 68090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishipublic class DiskStatsLoggingServiceTest extends AndroidTestCase { 69090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi @Rule public TemporaryFolder mTemporaryFolder; 70090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi @Rule public TemporaryFolder mDownloads; 71090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi @Mock private AppCollector mCollector; 725d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi @Mock private JobService mJobService; 735d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi @Mock private StorageStatsManager mSsm; 745d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi private ExternalStorageStats mStorageStats; 75090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi private File mInputFile; 76090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi 77090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi 78090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi @Before 79090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi public void setUp() throws Exception { 80090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi super.setUp(); 81090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi MockitoAnnotations.initMocks(this); 82090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi mTemporaryFolder = new TemporaryFolder(); 83090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi mTemporaryFolder.create(); 84090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi mInputFile = mTemporaryFolder.newFile(); 85090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi mDownloads = new TemporaryFolder(); 86090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi mDownloads.create(); 875d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi mStorageStats = new ExternalStorageStats(); 885d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi when(mSsm.queryExternalStatsForUser(isNull(String.class), any(UserHandle.class))) 895d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi .thenReturn(mStorageStats); 905d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi when(mJobService.getSystemService(anyString())).thenReturn(mSsm); 91090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi } 92090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi 93090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi @Test 94090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi public void testEmptyLog() throws Exception { 95090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi LogRunnable task = new LogRunnable(); 96090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi task.setAppCollector(mCollector); 97090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi task.setDownloadsDirectory(mDownloads.getRoot()); 98090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi task.setLogOutputFile(mInputFile); 99090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi task.setSystemSize(0L); 1005d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi task.setContext(mJobService); 101090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi task.run(); 102090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi 103090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi JSONObject json = getJsonOutput(); 104090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi assertThat(json.getLong(DiskStatsFileLogger.PHOTOS_KEY)).isEqualTo(0L); 105090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi assertThat(json.getLong(DiskStatsFileLogger.VIDEOS_KEY)).isEqualTo(0L); 106090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi assertThat(json.getLong(DiskStatsFileLogger.AUDIO_KEY)).isEqualTo(0L); 107090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi assertThat(json.getLong(DiskStatsFileLogger.DOWNLOADS_KEY)).isEqualTo(0L); 108090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi assertThat(json.getLong(DiskStatsFileLogger.SYSTEM_KEY)).isEqualTo(0L); 109090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi assertThat(json.getLong(DiskStatsFileLogger.MISC_KEY)).isEqualTo(0L); 110090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi assertThat(json.getLong(DiskStatsFileLogger.APP_SIZE_AGG_KEY)).isEqualTo(0L); 111090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi assertThat(json.getLong(DiskStatsFileLogger.APP_CACHE_AGG_KEY)).isEqualTo(0L); 112090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi assertThat( 113090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi json.getJSONArray(DiskStatsFileLogger.PACKAGE_NAMES_KEY).length()).isEqualTo(0L); 114090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi assertThat(json.getJSONArray(DiskStatsFileLogger.APP_SIZES_KEY).length()).isEqualTo(0L); 115090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi assertThat(json.getJSONArray(DiskStatsFileLogger.APP_CACHES_KEY).length()).isEqualTo(0L); 116090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi } 117090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi 118090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi @Test 119090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi public void testPopulatedLogTask() throws Exception { 120090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi // Write data to directories. 121090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi writeDataToFile(mDownloads.newFile(), "lol"); 1225d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi mStorageStats.audioBytes = 6L; 1235d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi mStorageStats.imageBytes = 4L; 1245d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi mStorageStats.videoBytes = 5L; 1255d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi mStorageStats.totalBytes = 22L; 126090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi 127090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi // Write apps. 128090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi ArrayList<PackageStats> apps = new ArrayList<>(); 129090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi PackageStats testApp = new PackageStats("com.test.app"); 130090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi testApp.dataSize = 5L; 131090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi testApp.cacheSize = 55L; 132090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi testApp.codeSize = 10L; 1335d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi testApp.userHandle = UserHandle.USER_SYSTEM; 134090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi apps.add(testApp); 1355d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi when(mCollector.getPackageStats(anyLong())).thenReturn(apps); 136090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi 137090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi LogRunnable task = new LogRunnable(); 138090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi task.setAppCollector(mCollector); 139090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi task.setDownloadsDirectory(mDownloads.getRoot()); 140090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi task.setLogOutputFile(mInputFile); 141090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi task.setSystemSize(10L); 1425d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi task.setContext(mJobService); 143090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi task.run(); 144090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi 145090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi JSONObject json = getJsonOutput(); 146090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi assertThat(json.getLong(DiskStatsFileLogger.PHOTOS_KEY)).isEqualTo(4L); 147090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi assertThat(json.getLong(DiskStatsFileLogger.VIDEOS_KEY)).isEqualTo(5L); 148090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi assertThat(json.getLong(DiskStatsFileLogger.AUDIO_KEY)).isEqualTo(6L); 149090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi assertThat(json.getLong(DiskStatsFileLogger.DOWNLOADS_KEY)).isEqualTo(3L); 150090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi assertThat(json.getLong(DiskStatsFileLogger.SYSTEM_KEY)).isEqualTo(10L); 151090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi assertThat(json.getLong(DiskStatsFileLogger.MISC_KEY)).isEqualTo(7L); 152b6cc838142d2390eaec99670bb6caf6bee0ec96fDaniel Nishi assertThat(json.getLong(DiskStatsFileLogger.APP_SIZE_AGG_KEY)).isEqualTo(10L); 153b6cc838142d2390eaec99670bb6caf6bee0ec96fDaniel Nishi assertThat(json.getLong(DiskStatsFileLogger.APP_DATA_SIZE_AGG_KEY)).isEqualTo(5L); 154090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi assertThat(json.getLong(DiskStatsFileLogger.APP_CACHE_AGG_KEY)).isEqualTo(55L); 155090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi assertThat( 156090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi json.getJSONArray(DiskStatsFileLogger.PACKAGE_NAMES_KEY).length()).isEqualTo(1L); 157090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi assertThat(json.getJSONArray(DiskStatsFileLogger.APP_SIZES_KEY).length()).isEqualTo(1L); 158b6cc838142d2390eaec99670bb6caf6bee0ec96fDaniel Nishi assertThat(json.getJSONArray(DiskStatsFileLogger.APP_DATA_KEY).length()).isEqualTo(1L); 159090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi assertThat(json.getJSONArray(DiskStatsFileLogger.APP_CACHES_KEY).length()).isEqualTo(1L); 160090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi } 161090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi 162cf76a16e660a361670745b043198b797ccd86747Daniel Nishi @Test 163cf76a16e660a361670745b043198b797ccd86747Daniel Nishi public void testDontCrashOnPackageStatsTimeout() throws Exception { 164cf76a16e660a361670745b043198b797ccd86747Daniel Nishi when(mCollector.getPackageStats(anyInt())).thenReturn(null); 165cf76a16e660a361670745b043198b797ccd86747Daniel Nishi 166cf76a16e660a361670745b043198b797ccd86747Daniel Nishi LogRunnable task = new LogRunnable(); 167cf76a16e660a361670745b043198b797ccd86747Daniel Nishi task.setAppCollector(mCollector); 168cf76a16e660a361670745b043198b797ccd86747Daniel Nishi task.setDownloadsDirectory(mDownloads.getRoot()); 169cf76a16e660a361670745b043198b797ccd86747Daniel Nishi task.setLogOutputFile(mInputFile); 170cf76a16e660a361670745b043198b797ccd86747Daniel Nishi task.setSystemSize(10L); 1715d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi task.setContext(mJobService); 172cf76a16e660a361670745b043198b797ccd86747Daniel Nishi task.run(); 173cf76a16e660a361670745b043198b797ccd86747Daniel Nishi 174cf76a16e660a361670745b043198b797ccd86747Daniel Nishi // No exception should be thrown. 175cf76a16e660a361670745b043198b797ccd86747Daniel Nishi } 176cf76a16e660a361670745b043198b797ccd86747Daniel Nishi 1775d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi @Test 1785d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi public void testDontCrashOnRun() throws Exception { 1795d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi DiskStatsLoggingService service = spy(new DiskStatsLoggingService()); 1805d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi BatteryManager batteryManager = mock(BatteryManager.class); 1815d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi when(batteryManager.isCharging()).thenReturn(true); 1825d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi doReturn(batteryManager).when(service).getSystemService(Context.BATTERY_SERVICE); 1835d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi UserManager userManager = mock(UserManager.class); 1845d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi when(userManager.getUsers()).thenReturn(new ArrayList<>()); 1855d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi doReturn(userManager).when(service).getSystemService(Context.USER_SERVICE); 1865d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi doReturn(mSsm).when(service).getSystemService(Context.STORAGE_STATS_SERVICE); 1875d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi doReturn(mock(StorageManager.class)) 1885d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi .when(service) 1895d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi .getSystemService(Context.STORAGE_SERVICE); 1905d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi 1915d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi MockContentResolver cr = new MockContentResolver(); 1925d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi cr.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); 1935d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi doReturn(cr).when(service).getContentResolver(); 1945d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi 1955d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi PackageManager pm = mock(PackageManager.class); 1965d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi VolumeInfo volumeInfo = 1975d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi new VolumeInfo(VolumeInfo.ID_PRIVATE_INTERNAL, VolumeInfo.TYPE_PRIVATE, null, null); 1985d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi when(pm.getPrimaryStorageCurrentVolume()).thenReturn(volumeInfo); 1995d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi doReturn(pm).when(service).getPackageManager(); 2005d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi 2015d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi doReturn(0).when(service).getUserId(); 2025d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi 2035d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi // UGGGGGHHHHHHH! jobFinished is a final method on JobService which crashes when called if 2045d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi // the JobService isn't initialized for real. ServiceTestCase doesn't let us initialize a 2055d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi // service which is built into the framework without crashing, though, so we can't make a 2065d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi // real initialized service. 2075d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi // 2085d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi // And so, we use reflection to set the JobServiceEngine, which is used by the final method, 2095d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi // to be something which won't crash when called. 2105d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi final Field field = JobService.class.getDeclaredField("mEngine"); 2115d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi field.setAccessible(true); 2125d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi field.set(service, mock(JobServiceEngine.class)); 2135d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi 2145d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi // Note: This won't clobber your on-device cache file because, technically, 2155d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi // FrameworkServicesTests don't have write permission to actually overwrite the cache file. 2165d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi // We log and fail on the write silently in this case. 2175d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi service.onStartJob(null); 2185d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi } 2195d230dc202cb03185652e12b3024ceea1132dd4dDaniel Nishi 220090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi private void writeDataToFile(File f, String data) throws Exception{ 221090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi PrintStream out = new PrintStream(f); 222090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi out.print(data); 223090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi out.close(); 224090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi } 225090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi 226090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi private JSONObject getJsonOutput() throws Exception { 227090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi return new JSONObject(IoUtils.readFileAsString(mInputFile.getAbsolutePath())); 228090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi } 229090b2d9d6c73ad1b92fd6374aaaa26a384333239Daniel Nishi} 230