Merge "[MS41.2] Add unit test for query history APIs"
diff --git a/tests/unit/java/android/app/usage/NetworkStatsManagerTest.java b/tests/unit/java/android/app/usage/NetworkStatsManagerTest.java
index 6e51069..561e621 100644
--- a/tests/unit/java/android/app/usage/NetworkStatsManagerTest.java
+++ b/tests/unit/java/android/app/usage/NetworkStatsManagerTest.java
@@ -240,6 +240,27 @@
         assertFalse(stats.hasNextBucket());
     }
 
+
+    @Test
+    public void testQueryDetailsForDevice() throws Exception {
+        final long startTime = 1;
+        final long endTime = 100;
+
+        reset(mStatsSession);
+        when(mService.openSessionForUsageStats(anyInt(), anyString())).thenReturn(mStatsSession);
+        when(mStatsSession.getHistoryIntervalForNetwork(any(NetworkTemplate.class),
+                anyInt(), anyLong(), anyLong()))
+                .thenReturn(new NetworkStatsHistory(10, 0));
+        final NetworkTemplate template = new NetworkTemplate.Builder(NetworkTemplate.MATCH_MOBILE)
+                .setMeteredness(NetworkStats.Bucket.METERED_YES).build();
+        NetworkStats stats = mManager.queryDetailsForDevice(template, startTime, endTime);
+
+        verify(mStatsSession, times(1)).getHistoryIntervalForNetwork(
+                eq(template), eq(NetworkStatsHistory.FIELD_ALL), eq(startTime), eq(endTime));
+
+        assertFalse(stats.hasNextBucket());
+    }
+
     private void assertBucketMatches(Entry expected, NetworkStats.Bucket actual) {
         assertEquals(expected.uid, actual.getUid());
         assertEquals(expected.rxBytes, actual.getRxBytes());
diff --git a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
index 40587c5..3765bf0 100644
--- a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -66,8 +66,10 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.anyString;
@@ -119,6 +121,7 @@
 
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.test.BroadcastInterceptingContext;
+import com.android.net.module.util.LocationPermissionChecker;
 import com.android.server.net.NetworkStatsService.AlertObserver;
 import com.android.server.net.NetworkStatsService.NetworkStatsSettings;
 import com.android.server.net.NetworkStatsService.NetworkStatsSettings.Config;
@@ -193,6 +196,8 @@
     @Mock
     private NetworkStatsSubscriptionsMonitor mNetworkStatsSubscriptionsMonitor;
     private HandlerThread mHandlerThread;
+    @Mock
+    private LocationPermissionChecker mLocationPermissionChecker;
 
     private NetworkStatsService mService;
     private INetworkStatsSession mSession;
@@ -262,6 +267,8 @@
         MockitoAnnotations.initMocks(this);
         final Context context = InstrumentationRegistry.getContext();
         mServiceContext = new MockContext(context);
+        when(mLocationPermissionChecker.checkCallersLocationPermission(
+                any(), any(), anyInt(), anyBoolean(), any())).thenReturn(true);
         when(sWifiInfo.getCurrentNetworkKey()).thenReturn(TEST_WIFI_NETWORK_KEY);
         mStatsDir = TestIoUtils.createTemporaryDirectory(getClass().getSimpleName());
 
@@ -334,6 +341,10 @@
                 return mContentObserver = super.makeContentObserver(handler, settings, monitor);
             }
 
+            @Override
+            public LocationPermissionChecker makeLocationPermissionChecker(final Context context) {
+                return mLocationPermissionChecker;
+            }
         };
     }
 
@@ -1688,6 +1699,28 @@
         provider.expectOnRequestStatsUpdate(0 /* unused */);
     }
 
+    /**
+     * Verify the service will throw exceptions if the template is location sensitive but
+     * the permission is not granted.
+     */
+    @Test
+    public void testEnforceTemplateLocationPermission() throws Exception {
+        when(mLocationPermissionChecker.checkCallersLocationPermission(
+                any(), any(), anyInt(), anyBoolean(), any())).thenReturn(false);
+        initWifiStats(buildWifiState(true, TEST_IFACE, IMSI_1));
+        assertThrows(SecurityException.class, () ->
+                assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0));
+        // Templates w/o wifi network keys can query stats as usual.
+        assertNetworkTotal(sTemplateCarrierWifi1, 0L, 0L, 0L, 0L, 0);
+        assertNetworkTotal(sTemplateImsi1, 0L, 0L, 0L, 0L, 0);
+
+        when(mLocationPermissionChecker.checkCallersLocationPermission(
+                any(), any(), anyInt(), anyBoolean(), any())).thenReturn(true);
+        assertNetworkTotal(sTemplateCarrierWifi1, 0L, 0L, 0L, 0L, 0);
+        assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
+        assertNetworkTotal(sTemplateImsi1, 0L, 0L, 0L, 0L, 0);
+    }
+
     private static File getBaseDir(File statsDir) {
         File baseDir = new File(statsDir, "netstats");
         baseDir.mkdirs();
@@ -1703,7 +1736,8 @@
     private void assertNetworkTotal(NetworkTemplate template, long start, long end, long rxBytes,
             long rxPackets, long txBytes, long txPackets, int operations) throws Exception {
         // verify history API
-        final NetworkStatsHistory history = mSession.getHistoryForNetwork(template, FIELD_ALL);
+        final NetworkStatsHistory history =
+                mSession.getHistoryIntervalForNetwork(template, FIELD_ALL, start, end);
         assertValues(history, start, end, rxBytes, rxPackets, txBytes, txPackets, operations);
 
         // verify summary API