OSDN Git Service

[DPM] DO uses batch token to retrieve network logs, and can retrieve
authorMichal Karpinski <mkarpinski@google.com>
Thu, 3 Nov 2016 15:46:17 +0000 (15:46 +0000)
committerMichal Karpinski <mkarpinski@google.com>
Mon, 14 Nov 2016 10:26:55 +0000 (10:26 +0000)
the same batch many times

This allows DO to:
a) know that some logs were dropped (by trying with token and not
getting anything)
b) know how many logs were there in each batch (useful especially
for the dropped ones)
c) retry batch retrieval if it failed

Test: will be CTS tested once APIs unhidden
Bug: 29748723
Change-Id: I788359242e3b2a4cb638edb25e5db8b25646c29f

core/java/android/app/admin/DeviceAdminReceiver.java
core/java/android/app/admin/DevicePolicyManager.java
core/java/android/app/admin/IDevicePolicyManager.aidl
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
services/devicepolicy/java/com/android/server/devicepolicy/NetworkLogger.java
services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java

index 360087c..cbd5a6d 100644 (file)
@@ -285,6 +285,27 @@ public class DeviceAdminReceiver extends BroadcastReceiver {
             = "android.app.action.NETWORK_LOGS_AVAILABLE";
 
     /**
+     * A {@code long} containing a token of the current batch of network logs, that has to be used
+     * to retrieve the batch of logs by the device owner.
+     *
+     * @see #ACTION_NETWORK_LOGS_AVAILABLE
+     * @see DevicePolicyManager#retrieveNetworkLogs
+     * @hide
+     */
+    public static final String EXTRA_NETWORK_LOGS_TOKEN =
+            "android.app.extra.EXTRA_NETWORK_LOGS_TOKEN";
+
+    /**
+     * An {@code int} count representing a total count of network logs inside the current batch of
+     * network logs.
+     *
+     * @see #ACTION_NETWORK_LOGS_AVAILABLE
+     * @hide
+     */
+    public static final String EXTRA_NETWORK_LOGS_COUNT =
+            "android.app.extra.EXTRA_NETWORK_LOGS_COUNT";
+
+    /**
      * A string containing the SHA-256 hash of the bugreport file.
      *
      * @see #ACTION_BUGREPORT_SHARE
@@ -644,19 +665,22 @@ public class DeviceAdminReceiver extends BroadcastReceiver {
     }
 
     /**
-     * Called when a new batch of network logs can be retrieved. This callback method will only ever
-     * be called when network logging is enabled. The logs can only be retrieved while network
+     * Called each time a new batch of network logs can be retrieved. This callback method will only
+     * ever be called when network logging is enabled. The logs can only be retrieved while network
      * logging is enabled.
      *
      * <p>This callback is only applicable to device owners.
      *
      * @param context The running context as per {@link #onReceive}.
      * @param intent The received intent as per {@link #onReceive}.
+     * @param batchToken The token representing the current batch of network logs.
+     * @param networkLogsCount The total count of events in the current batch of network logs.
      * @see DevicePolicyManager#retrieveNetworkLogs(ComponentName)
      *
      * @hide
      */
-    public void onNetworkLogsAvailable(Context context, Intent intent) {
+    public void onNetworkLogsAvailable(Context context, Intent intent, long batchToken,
+            int networkLogsCount) {
     }
 
     /**
@@ -714,7 +738,9 @@ public class DeviceAdminReceiver extends BroadcastReceiver {
         } else if (ACTION_SECURITY_LOGS_AVAILABLE.equals(action)) {
             onSecurityLogsAvailable(context, intent);
         } else if (ACTION_NETWORK_LOGS_AVAILABLE.equals(action)) {
-            onNetworkLogsAvailable(context, intent);
+            long batchToken = intent.getLongExtra(EXTRA_NETWORK_LOGS_TOKEN, -1);
+            int networkLogsCount = intent.getIntExtra(EXTRA_NETWORK_LOGS_COUNT, 0);
+            onNetworkLogsAvailable(context, intent, batchToken, networkLogsCount);
         }
     }
 }
index 538e52b..1ab809d 100644 (file)
@@ -6649,8 +6649,6 @@ public class DevicePolicyManager {
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param enabled whether network logging should be enabled or not.
      * @throws {@link SecurityException} if {@code admin} is not a device owner.
-     * @throws {@link RemoteException} if network logging could not be enabled or disabled due to
-     *         the logging service not being available
      * @see #retrieveNetworkLogs
      *
      * @hide
@@ -6683,7 +6681,10 @@ public class DevicePolicyManager {
     }
 
     /**
-     * Called by device owner to retrieve a new batch of network logging events.
+     * Called by device owner to retrieve the most recent batch of network logging events.
+     * A device owner has to provide a batchToken provided as part of
+     * {@link DeviceAdminReceiver#onNetworkLogsAvailable} callback. If the token doesn't match the
+     * token of the most recent available batch of logs, {@code null} will be returned.
      *
      * <p> {@link NetworkEvent} can be one of {@link DnsEvent} or {@link ConnectEvent}.
      *
@@ -6694,16 +6695,20 @@ public class DevicePolicyManager {
      * {@link DeviceAdminReceiver#onNetworkLogsAvailable}.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param batchToken A token of the batch to retrieve
      * @return A new batch of network logs which is a list of {@link NetworkEvent}. Returns
-     * {@code null} if there's no batch currently awaiting for retrieval or if logging is disabled.
+     *        {@code null} if the batch represented by batchToken is no longer available or if
+     *        logging is disabled.
      * @throws {@link SecurityException} if {@code admin} is not a device owner.
+     * @see DeviceAdminReceiver#onNetworkLogsAvailable
      *
      * @hide
      */
-    public List<NetworkEvent> retrieveNetworkLogs(@NonNull ComponentName admin) {
+    public @Nullable List<NetworkEvent> retrieveNetworkLogs(@NonNull ComponentName admin,
+            long batchToken) {
         throwIfParentInstance("retrieveNetworkLogs");
         try {
-            return mService.retrieveNetworkLogs(admin);
+            return mService.retrieveNetworkLogs(admin, batchToken);
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
         }
index b0aec8c..729d12b 100644 (file)
@@ -318,5 +318,5 @@ interface IDevicePolicyManager {
 
     void setNetworkLoggingEnabled(in ComponentName admin, boolean enabled);
     boolean isNetworkLoggingEnabled(in ComponentName admin);
-    List<NetworkEvent> retrieveNetworkLogs(in ComponentName admin);
+    List<NetworkEvent> retrieveNetworkLogs(in ComponentName admin, long batchToken);
 }
index 7f8b9b8..b687e09 100644 (file)
@@ -490,9 +490,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
              * to listen for events.
              */
             if (Intent.ACTION_USER_STARTED.equals(action)
-                    && userHandle == mOwners.getDeviceOwnerUserId()
-                    && isNetworkLoggingEnabledInternal()) {
-                setNetworkLoggingActiveInternal(true);
+                    && userHandle == mOwners.getDeviceOwnerUserId()) {
+                synchronized (DevicePolicyManagerService.this) {
+                    if (isNetworkLoggingEnabledInternalLocked()) {
+                        setNetworkLoggingActiveInternal(true);
+                    }
+                }
             }
             if (Intent.ACTION_BOOT_COMPLETED.equals(action)
                     && userHandle == mOwners.getDeviceOwnerUserId()
@@ -9515,7 +9518,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
         Preconditions.checkNotNull(admin);
         ensureDeviceOwnerManagingSingleUser(admin);
 
-        if (enabled == isNetworkLoggingEnabledInternal()) {
+        if (enabled == isNetworkLoggingEnabledInternalLocked()) {
             // already in the requested state
             return;
         }
@@ -9556,11 +9559,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
         Preconditions.checkNotNull(admin);
         synchronized (this) {
             getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
-            return isNetworkLoggingEnabledInternal();
+            return isNetworkLoggingEnabledInternalLocked();
         }
     }
 
-    private synchronized boolean isNetworkLoggingEnabledInternal() {
+    private boolean isNetworkLoggingEnabledInternalLocked() {
         ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked();
         return (deviceOwner != null) && deviceOwner.isNetworkLoggingEnabled;
     }
@@ -9571,7 +9574,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
      * Ideally this would be done with ParceledList, however it only supports homogeneous types.
      */
     @Override
-    public synchronized List<NetworkEvent> retrieveNetworkLogs(ComponentName admin) {
+    public synchronized List<NetworkEvent> retrieveNetworkLogs(ComponentName admin,
+            long batchToken) {
         if (!mHasFeature) {
             return null;
         }
@@ -9581,6 +9585,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
         if (mNetworkLogger == null) {
             return null;
         }
-        return isNetworkLoggingEnabledInternal() ? mNetworkLogger.retrieveLogs() : null;
+        return isNetworkLoggingEnabledInternalLocked()
+                ? mNetworkLogger.retrieveLogs(batchToken)
+                : null;
     }
 }
index 185ccc2..8cb13da 100644 (file)
@@ -147,7 +147,7 @@ final class NetworkLogger {
         }
     }
 
-    List<NetworkEvent> retrieveLogs() {
-        return mNetworkLoggingHandler.retrieveFullLogBatch();
+    List<NetworkEvent> retrieveLogs(long batchToken) {
+        return mNetworkLoggingHandler.retrieveFullLogBatch(batchToken);
     }
 }
index 96884e6..98e5570 100644 (file)
@@ -55,11 +55,15 @@ final class NetworkLoggingHandler extends Handler {
     private final DevicePolicyManagerService mDpm;
 
     // threadsafe as it's Handler's thread confined
+    @GuardedBy("this")
     private ArrayList<NetworkEvent> mNetworkEvents = new ArrayList<NetworkEvent>();
 
     @GuardedBy("this")
     private ArrayList<NetworkEvent> mFullBatch;
 
+    @GuardedBy("this")
+    private long currentFullBatchToken;
+
     NetworkLoggingHandler(Looper looper, DevicePolicyManagerService dpm) {
         super(looper);
         mDpm = dpm;
@@ -97,17 +101,21 @@ final class NetworkLoggingHandler extends Handler {
         scheduleBatchFinalization(BATCH_FINALIZATION_TIMEOUT_MS);
         // notify DO that there's a new non-empty batch waiting
         if (mFullBatch.size() > 0) {
-            mDpm.sendDeviceOwnerCommand(DeviceAdminReceiver.ACTION_NETWORK_LOGS_AVAILABLE,
-                    /* extras */ null);
+            currentFullBatchToken++;
+            Bundle extras = new Bundle();
+            extras.putLong(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_TOKEN, currentFullBatchToken);
+            extras.putInt(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_COUNT, mFullBatch.size());
+            mDpm.sendDeviceOwnerCommand(DeviceAdminReceiver.ACTION_NETWORK_LOGS_AVAILABLE, extras);
         } else {
             mFullBatch = null;
         }
     }
 
-    synchronized List<NetworkEvent> retrieveFullLogBatch() {
-        List<NetworkEvent> ret = mFullBatch;
-        mFullBatch = null;
-        return ret;
+    synchronized List<NetworkEvent> retrieveFullLogBatch(long batchToken) {
+        if (batchToken != currentFullBatchToken) {
+            return null;
+        }
+        return mFullBatch;
     }
 }