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 package com.android.server.net;
17 
18 import static android.net.ConnectivityManager.BLOCKED_REASON_NONE;
19 import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE;
20 import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY;
21 import static android.net.ConnectivityManager.FIREWALL_CHAIN_POWERSAVE;
22 import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED;
23 import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY;
24 import static android.net.INetd.FIREWALL_RULE_ALLOW;
25 import static android.net.INetd.FIREWALL_RULE_DENY;
26 import static android.net.NetworkPolicyManager.ALLOWED_REASON_NONE;
27 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_DOZABLE;
28 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY;
29 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_POWERSAVE;
30 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_RESTRICTED;
31 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_STANDBY;
32 import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
33 import static android.os.PowerExemptionManager.reasonCodeToString;
34 import static android.os.Process.INVALID_UID;
35 
36 import android.annotation.Nullable;
37 import android.app.ActivityManager;
38 import android.app.ActivityManager.ProcessCapability;
39 import android.net.NetworkPolicyManager;
40 import android.os.UserHandle;
41 import android.util.ArraySet;
42 import android.util.Log;
43 import android.util.Slog;
44 
45 import com.android.internal.util.IndentingPrintWriter;
46 import com.android.internal.util.RingBuffer;
47 import com.android.server.am.ProcessList;
48 import com.android.server.net.NetworkPolicyManagerService.UidBlockedState;
49 
50 import java.text.SimpleDateFormat;
51 import java.util.Arrays;
52 import java.util.Date;
53 import java.util.Set;
54 
55 public class NetworkPolicyLogger {
56     static final String TAG = "NetworkPolicy";
57 
58     static final boolean LOGD = Log.isLoggable(TAG, Log.DEBUG);
59     static final boolean LOGV = Log.isLoggable(TAG, Log.VERBOSE);
60 
61     private static final int MAX_LOG_SIZE =
62             ActivityManager.isLowRamDeviceStatic() ? 100 : 400;
63     private static final int MAX_NETWORK_BLOCKED_LOG_SIZE =
64             ActivityManager.isLowRamDeviceStatic() ? 100 : 400;
65 
66     private static final int EVENT_TYPE_GENERIC = 0;
67     private static final int EVENT_NETWORK_BLOCKED = 1;
68     private static final int EVENT_UID_STATE_CHANGED = 2;
69     private static final int EVENT_POLICIES_CHANGED = 3;
70     private static final int EVENT_METEREDNESS_CHANGED = 4;
71     private static final int EVENT_USER_STATE_REMOVED = 5;
72     private static final int EVENT_RESTRICT_BG_CHANGED = 6;
73     private static final int EVENT_DEVICE_IDLE_MODE_ENABLED = 7;
74     private static final int EVENT_APP_IDLE_STATE_CHANGED = 8;
75     private static final int EVENT_PAROLE_STATE_CHANGED = 9;
76     private static final int EVENT_TEMP_POWER_SAVE_WL_CHANGED = 10;
77     private static final int EVENT_UID_FIREWALL_RULE_CHANGED = 11;
78     private static final int EVENT_FIREWALL_CHAIN_ENABLED = 12;
79     private static final int EVENT_UPDATE_METERED_RESTRICTED_PKGS = 13;
80     private static final int EVENT_APP_IDLE_WL_CHANGED = 14;
81     private static final int EVENT_METERED_ALLOWLIST_CHANGED = 15;
82     private static final int EVENT_METERED_DENYLIST_CHANGED = 16;
83     private static final int EVENT_ROAMING_CHANGED = 17;
84     private static final int EVENT_INTERFACES_CHANGED = 18;
85 
86     private final LogBuffer mNetworkBlockedBuffer = new LogBuffer(MAX_NETWORK_BLOCKED_LOG_SIZE);
87     private final LogBuffer mUidStateChangeBuffer = new LogBuffer(MAX_LOG_SIZE);
88     private final LogBuffer mEventsBuffer = new LogBuffer(MAX_LOG_SIZE);
89 
90     private int mDebugUid = INVALID_UID;
91 
92     private final Object mLock = new Object();
93 
networkBlocked(int uid, @Nullable UidBlockedState uidBlockedState)94     void networkBlocked(int uid, @Nullable UidBlockedState uidBlockedState) {
95         synchronized (mLock) {
96             if (LOGD || uid == mDebugUid) {
97                 Slog.d(TAG, "Blocked state of " + uid + ": " + uidBlockedState);
98             }
99             if (uidBlockedState == null) {
100                 mNetworkBlockedBuffer.networkBlocked(uid, BLOCKED_REASON_NONE, ALLOWED_REASON_NONE,
101                         BLOCKED_REASON_NONE);
102             } else {
103                 mNetworkBlockedBuffer.networkBlocked(uid, uidBlockedState.blockedReasons,
104                         uidBlockedState.allowedReasons, uidBlockedState.effectiveBlockedReasons);
105             }
106         }
107     }
108 
uidStateChanged(int uid, int procState, long procStateSeq, @ProcessCapability int capability)109     void uidStateChanged(int uid, int procState, long procStateSeq,
110             @ProcessCapability int capability) {
111         synchronized (mLock) {
112             if (LOGV || uid == mDebugUid) {
113                 Slog.v(TAG, uid + " state changed to "
114                         + ProcessList.makeProcStateString(procState) + ",seq=" + procStateSeq
115                         + ",cap=" + ActivityManager.getCapabilitiesSummary(capability));
116             }
117             mUidStateChangeBuffer.uidStateChanged(uid, procState, procStateSeq, capability);
118         }
119     }
120 
event(String msg)121     void event(String msg) {
122         synchronized (mLock) {
123             if (LOGV) Slog.v(TAG, msg);
124             mEventsBuffer.event(msg);
125         }
126     }
127 
uidPolicyChanged(int uid, int oldPolicy, int newPolicy)128     void uidPolicyChanged(int uid, int oldPolicy, int newPolicy) {
129         synchronized (mLock) {
130             if (LOGV || uid == mDebugUid) {
131                 Slog.v(TAG,
132                         getPolicyChangedLog(uid, oldPolicy, newPolicy));
133             }
134             mEventsBuffer.uidPolicyChanged(uid, oldPolicy, newPolicy);
135         }
136     }
137 
meterednessChanged(int netId, boolean newMetered)138     void meterednessChanged(int netId, boolean newMetered) {
139         synchronized (mLock) {
140             if (LOGD || mDebugUid != INVALID_UID) {
141                 Slog.d(TAG,
142                         getMeterednessChangedLog(netId, newMetered));
143             }
144             mEventsBuffer.meterednessChanged(netId, newMetered);
145         }
146     }
147 
removingUserState(int userId)148     void removingUserState(int userId) {
149         synchronized (mLock) {
150             if (LOGD || mDebugUid != INVALID_UID) {
151                 Slog.d(TAG, getUserRemovedLog(userId));
152             }
153             mEventsBuffer.userRemoved(userId);
154         }
155     }
156 
restrictBackgroundChanged(boolean oldValue, boolean newValue)157     void restrictBackgroundChanged(boolean oldValue, boolean newValue) {
158         synchronized (mLock) {
159             if (LOGD || mDebugUid != INVALID_UID) {
160                 Slog.d(TAG,
161                         getRestrictBackgroundChangedLog(oldValue, newValue));
162             }
163             mEventsBuffer.restrictBackgroundChanged(oldValue, newValue);
164         }
165     }
166 
deviceIdleModeEnabled(boolean enabled)167     void deviceIdleModeEnabled(boolean enabled) {
168         synchronized (mLock) {
169             if (LOGD || mDebugUid != INVALID_UID) {
170                 Slog.d(TAG, getDeviceIdleModeEnabled(enabled));
171             }
172             mEventsBuffer.deviceIdleModeEnabled(enabled);
173         }
174     }
175 
appIdleStateChanged(int uid, boolean idle)176     void appIdleStateChanged(int uid, boolean idle) {
177         synchronized (mLock) {
178             if (LOGD || uid == mDebugUid) {
179                 Slog.d(TAG, getAppIdleChangedLog(uid, idle));
180             }
181             mEventsBuffer.appIdleStateChanged(uid, idle);
182         }
183     }
184 
appIdleWlChanged(int uid, boolean isWhitelisted)185     void appIdleWlChanged(int uid, boolean isWhitelisted) {
186         synchronized (mLock) {
187             if (LOGD || uid == mDebugUid) {
188                 Slog.d(TAG, getAppIdleWlChangedLog(uid, isWhitelisted));
189             }
190             mEventsBuffer.appIdleWlChanged(uid, isWhitelisted);
191         }
192     }
193 
paroleStateChanged(boolean paroleOn)194     void paroleStateChanged(boolean paroleOn) {
195         synchronized (mLock) {
196             if (LOGD || mDebugUid != INVALID_UID) {
197                 Slog.d(TAG, getParoleStateChanged(paroleOn));
198             }
199             mEventsBuffer.paroleStateChanged(paroleOn);
200         }
201     }
202 
tempPowerSaveWlChanged(int appId, boolean added, int reasonCode, String reason)203     void tempPowerSaveWlChanged(int appId, boolean added, int reasonCode, String reason) {
204         synchronized (mLock) {
205             if (LOGV || appId == UserHandle.getAppId(mDebugUid)) {
206                 Slog.v(TAG, getTempPowerSaveWlChangedLog(appId, added, reasonCode, reason));
207             }
208             mEventsBuffer.tempPowerSaveWlChanged(appId, added, reasonCode, reason);
209         }
210     }
211 
uidFirewallRuleChanged(int chain, int uid, int rule)212     void uidFirewallRuleChanged(int chain, int uid, int rule) {
213         synchronized (mLock) {
214             if (LOGV || uid == mDebugUid) {
215                 Slog.v(TAG,
216                         getUidFirewallRuleChangedLog(chain, uid, rule));
217             }
218             mEventsBuffer.uidFirewallRuleChanged(chain, uid, rule);
219         }
220     }
221 
firewallChainEnabled(int chain, boolean enabled)222     void firewallChainEnabled(int chain, boolean enabled) {
223         synchronized (mLock) {
224             if (LOGD || mDebugUid != INVALID_UID) {
225                 Slog.d(TAG,
226                         getFirewallChainEnabledLog(chain, enabled));
227             }
228             mEventsBuffer.firewallChainEnabled(chain, enabled);
229         }
230     }
231 
firewallRulesChanged(int chain, int[] uids, int[] rules)232     void firewallRulesChanged(int chain, int[] uids, int[] rules) {
233         synchronized (mLock) {
234             final String log = "Firewall rules changed for " + getFirewallChainName(chain)
235                     + "; uids=" + Arrays.toString(uids) + "; rules=" + Arrays.toString(rules);
236             if (LOGD || mDebugUid != INVALID_UID) {
237                 Slog.d(TAG, log);
238             }
239             mEventsBuffer.event(log);
240         }
241     }
242 
meteredRestrictedPkgsChanged(Set<Integer> restrictedUids)243     void meteredRestrictedPkgsChanged(Set<Integer> restrictedUids) {
244         synchronized (mLock) {
245             final String log = "Metered restricted uids: " + restrictedUids;
246             if (LOGD || mDebugUid != INVALID_UID) {
247                 Slog.d(TAG, log);
248             }
249             mEventsBuffer.event(log);
250         }
251     }
252 
meteredAllowlistChanged(int uid, boolean added)253     void meteredAllowlistChanged(int uid, boolean added) {
254         synchronized (mLock) {
255             if (LOGD || mDebugUid == uid) {
256                 Slog.d(TAG, getMeteredAllowlistChangedLog(uid, added));
257             }
258             mEventsBuffer.meteredAllowlistChanged(uid, added);
259         }
260     }
261 
meteredDenylistChanged(int uid, boolean added)262     void meteredDenylistChanged(int uid, boolean added) {
263         synchronized (mLock) {
264             if (LOGD || mDebugUid == uid) {
265                 Slog.d(TAG, getMeteredDenylistChangedLog(uid, added));
266             }
267             mEventsBuffer.meteredDenylistChanged(uid, added);
268         }
269     }
270 
roamingChanged(int netId, boolean newRoaming)271     void roamingChanged(int netId, boolean newRoaming) {
272         synchronized (mLock) {
273             if (LOGD || mDebugUid != INVALID_UID) {
274                 Slog.d(TAG, getRoamingChangedLog(netId, newRoaming));
275             }
276             mEventsBuffer.roamingChanged(netId, newRoaming);
277         }
278     }
279 
interfacesChanged(int netId, ArraySet<String> newIfaces)280     void interfacesChanged(int netId, ArraySet<String> newIfaces) {
281         synchronized (mLock) {
282             if (LOGD || mDebugUid != INVALID_UID) {
283                 Slog.d(TAG, getInterfacesChangedLog(netId, newIfaces.toString()));
284             }
285             mEventsBuffer.interfacesChanged(netId, newIfaces.toString());
286         }
287     }
288 
setDebugUid(int uid)289     void setDebugUid(int uid) {
290         mDebugUid = uid;
291     }
292 
dumpLogs(IndentingPrintWriter pw)293     void dumpLogs(IndentingPrintWriter pw) {
294         synchronized (mLock) {
295             pw.println();
296             pw.println("mEventLogs (most recent first):");
297             pw.increaseIndent();
298             mEventsBuffer.reverseDump(pw);
299             pw.decreaseIndent();
300 
301             pw.println();
302             pw.println("mNetworkBlockedLogs (most recent first):");
303             pw.increaseIndent();
304             mNetworkBlockedBuffer.reverseDump(pw);
305             pw.decreaseIndent();
306 
307             pw.println();
308             pw.println("mUidStateChangeLogs (most recent first):");
309             pw.increaseIndent();
310             mUidStateChangeBuffer.reverseDump(pw);
311             pw.decreaseIndent();
312         }
313     }
314 
getPolicyChangedLog(int uid, int oldPolicy, int newPolicy)315     private static String getPolicyChangedLog(int uid, int oldPolicy, int newPolicy) {
316         return "Policy for " + uid + " changed from "
317                 + NetworkPolicyManager.uidPoliciesToString(oldPolicy) + " to "
318                 + NetworkPolicyManager.uidPoliciesToString(newPolicy);
319     }
320 
getMeterednessChangedLog(int netId, boolean newMetered)321     private static String getMeterednessChangedLog(int netId, boolean newMetered) {
322         return "Meteredness of netId=" + netId + " changed to " + newMetered;
323     }
324 
getUserRemovedLog(int userId)325     private static String getUserRemovedLog(int userId) {
326         return "Remove state for u" + userId;
327     }
328 
getRestrictBackgroundChangedLog(boolean oldValue, boolean newValue)329     private static String getRestrictBackgroundChangedLog(boolean oldValue, boolean newValue) {
330         return "Changed restrictBackground: " + oldValue + "->" + newValue;
331     }
332 
getDeviceIdleModeEnabled(boolean enabled)333     private static String getDeviceIdleModeEnabled(boolean enabled) {
334         return "DeviceIdleMode enabled: " + enabled;
335     }
336 
getAppIdleChangedLog(int uid, boolean idle)337     private static String getAppIdleChangedLog(int uid, boolean idle) {
338         return "App idle state of uid " + uid + ": " + idle;
339     }
340 
getAppIdleWlChangedLog(int uid, boolean isWhitelisted)341     private static String getAppIdleWlChangedLog(int uid, boolean isWhitelisted) {
342         return "App idle whitelist state of uid " + uid + ": " + isWhitelisted;
343     }
344 
getParoleStateChanged(boolean paroleOn)345     private static String getParoleStateChanged(boolean paroleOn) {
346         return "Parole state: " + paroleOn;
347     }
348 
getTempPowerSaveWlChangedLog(int appId, boolean added, int reasonCode, String reason)349     private static String getTempPowerSaveWlChangedLog(int appId, boolean added,
350             int reasonCode, String reason) {
351         return "temp-power-save whitelist for " + appId + " changed to: " + added
352                 + "; reason=" + reasonCodeToString(reasonCode) + " <" + reason + ">";
353     }
354 
getUidFirewallRuleChangedLog(int chain, int uid, int rule)355     private static String getUidFirewallRuleChangedLog(int chain, int uid, int rule) {
356         return String.format("Firewall rule changed: %d-%s-%s",
357                 uid, getFirewallChainName(chain), getFirewallRuleName(rule));
358     }
359 
getFirewallChainEnabledLog(int chain, boolean enabled)360     private static String getFirewallChainEnabledLog(int chain, boolean enabled) {
361         return "Firewall chain " + getFirewallChainName(chain) + " state: " + enabled;
362     }
363 
getMeteredAllowlistChangedLog(int uid, boolean added)364     private static String getMeteredAllowlistChangedLog(int uid, boolean added) {
365         return "metered-allowlist for " + uid + " changed to " + added;
366     }
367 
getMeteredDenylistChangedLog(int uid, boolean added)368     private static String getMeteredDenylistChangedLog(int uid, boolean added) {
369         return "metered-denylist for " + uid + " changed to " + added;
370     }
371 
getRoamingChangedLog(int netId, boolean newRoaming)372     private static String getRoamingChangedLog(int netId, boolean newRoaming) {
373         return "Roaming of netId=" + netId + " changed to " + newRoaming;
374     }
375 
getInterfacesChangedLog(int netId, String newIfaces)376     private static String getInterfacesChangedLog(int netId, String newIfaces) {
377         return "Interfaces of netId=" + netId + " changed to " + newIfaces;
378     }
379 
getFirewallChainName(int chain)380     private static String getFirewallChainName(int chain) {
381         switch (chain) {
382             case FIREWALL_CHAIN_DOZABLE:
383                 return FIREWALL_CHAIN_NAME_DOZABLE;
384             case FIREWALL_CHAIN_STANDBY:
385                 return FIREWALL_CHAIN_NAME_STANDBY;
386             case FIREWALL_CHAIN_POWERSAVE:
387                 return FIREWALL_CHAIN_NAME_POWERSAVE;
388             case FIREWALL_CHAIN_RESTRICTED:
389                 return FIREWALL_CHAIN_NAME_RESTRICTED;
390             case FIREWALL_CHAIN_LOW_POWER_STANDBY:
391                 return FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY;
392             default:
393                 return String.valueOf(chain);
394         }
395     }
396 
getFirewallRuleName(int rule)397     private static String getFirewallRuleName(int rule) {
398         switch (rule) {
399             case FIREWALL_RULE_DEFAULT:
400                 return "default";
401             case FIREWALL_RULE_ALLOW:
402                 return "allow";
403             case FIREWALL_RULE_DENY:
404                 return "deny";
405             default:
406                 return String.valueOf(rule);
407         }
408     }
409 
410     private final static class LogBuffer extends RingBuffer<Data> {
411         private static final SimpleDateFormat sFormatter
412                 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss:SSS");
413         private static final Date sDate = new Date();
414 
LogBuffer(int capacity)415         public LogBuffer(int capacity) {
416             super(Data.class, capacity);
417         }
418 
uidStateChanged(int uid, int procState, long procStateSeq, @ProcessCapability int capability)419         public void uidStateChanged(int uid, int procState, long procStateSeq,
420                 @ProcessCapability int capability) {
421             final Data data = getNextSlot();
422             if (data == null) return;
423 
424             data.reset();
425             data.type = EVENT_UID_STATE_CHANGED;
426             data.ifield1 = uid;
427             data.ifield2 = procState;
428             data.ifield3 = capability;
429             data.lfield1 = procStateSeq;
430             data.timeStamp = System.currentTimeMillis();
431         }
432 
event(String msg)433         public void event(String msg) {
434             final Data data = getNextSlot();
435             if (data == null) return;
436 
437             data.reset();
438             data.type = EVENT_TYPE_GENERIC;
439             data.sfield1 = msg;
440             data.timeStamp = System.currentTimeMillis();
441         }
442 
networkBlocked(int uid, int blockedReasons, int allowedReasons, int effectiveBlockedReasons)443         public void networkBlocked(int uid, int blockedReasons, int allowedReasons,
444                 int effectiveBlockedReasons) {
445             final Data data = getNextSlot();
446             if (data == null) return;
447 
448             data.reset();
449             data.type = EVENT_NETWORK_BLOCKED;
450             data.ifield1 = uid;
451             data.ifield2 = blockedReasons;
452             data.ifield3 = allowedReasons;
453             data.ifield4 = effectiveBlockedReasons;
454             data.timeStamp = System.currentTimeMillis();
455         }
456 
uidPolicyChanged(int uid, int oldPolicy, int newPolicy)457         public void uidPolicyChanged(int uid, int oldPolicy, int newPolicy) {
458             final Data data = getNextSlot();
459             if (data == null) return;
460 
461             data.reset();
462             data.type = EVENT_POLICIES_CHANGED;
463             data.ifield1 = uid;
464             data.ifield2 = oldPolicy;
465             data.ifield3 = newPolicy;
466             data.timeStamp = System.currentTimeMillis();
467         }
468 
meterednessChanged(int netId, boolean newMetered)469         public void meterednessChanged(int netId, boolean newMetered) {
470             final Data data = getNextSlot();
471             if (data == null) return;
472 
473             data.reset();
474             data.type = EVENT_METEREDNESS_CHANGED;
475             data.ifield1 = netId;
476             data.bfield1 = newMetered;
477             data.timeStamp = System.currentTimeMillis();
478         }
479 
userRemoved(int userId)480         public void userRemoved(int userId) {
481             final Data data = getNextSlot();
482             if (data == null) return;
483 
484             data.reset();
485             data.type = EVENT_USER_STATE_REMOVED;
486             data.ifield1 = userId;
487             data.timeStamp = System.currentTimeMillis();
488         }
489 
restrictBackgroundChanged(boolean oldValue, boolean newValue)490         public void restrictBackgroundChanged(boolean oldValue, boolean newValue) {
491             final Data data = getNextSlot();
492             if (data == null) return;
493 
494             data.reset();
495             data.type = EVENT_RESTRICT_BG_CHANGED;
496             data.bfield1 = oldValue;
497             data.bfield2 = newValue;
498             data.timeStamp = System.currentTimeMillis();
499         }
500 
deviceIdleModeEnabled(boolean enabled)501         public void deviceIdleModeEnabled(boolean enabled) {
502             final Data data = getNextSlot();
503             if (data == null) return;
504 
505             data.reset();
506             data.type = EVENT_DEVICE_IDLE_MODE_ENABLED;
507             data.bfield1 = enabled;
508             data.timeStamp = System.currentTimeMillis();
509         }
510 
appIdleStateChanged(int uid, boolean idle)511         public void appIdleStateChanged(int uid, boolean idle) {
512             final Data data = getNextSlot();
513             if (data == null) return;
514 
515             data.reset();
516             data.type = EVENT_APP_IDLE_STATE_CHANGED;
517             data.ifield1 = uid;
518             data.bfield1 = idle;
519             data.timeStamp = System.currentTimeMillis();
520         }
521 
appIdleWlChanged(int uid, boolean isWhitelisted)522         public void appIdleWlChanged(int uid, boolean isWhitelisted) {
523             final Data data = getNextSlot();
524             if (data == null) return;
525 
526             data.reset();
527             data.type = EVENT_APP_IDLE_WL_CHANGED;
528             data.ifield1 = uid;
529             data.bfield1 = isWhitelisted;
530             data.timeStamp = System.currentTimeMillis();
531         }
532 
paroleStateChanged(boolean paroleOn)533         public void paroleStateChanged(boolean paroleOn) {
534             final Data data = getNextSlot();
535             if (data == null) return;
536 
537             data.reset();
538             data.type = EVENT_PAROLE_STATE_CHANGED;
539             data.bfield1 = paroleOn;
540             data.timeStamp = System.currentTimeMillis();
541         }
542 
tempPowerSaveWlChanged(int appId, boolean added, int reasonCode, String reason)543         public void tempPowerSaveWlChanged(int appId, boolean added,
544                 int reasonCode, String reason) {
545             final Data data = getNextSlot();
546             if (data == null) return;
547 
548             data.reset();
549             data.type = EVENT_TEMP_POWER_SAVE_WL_CHANGED;
550             data.ifield1 = appId;
551             data.ifield2 = reasonCode;
552             data.bfield1 = added;
553             data.sfield1 = reason;
554             data.timeStamp = System.currentTimeMillis();
555         }
556 
uidFirewallRuleChanged(int chain, int uid, int rule)557         public void uidFirewallRuleChanged(int chain, int uid, int rule) {
558             final Data data = getNextSlot();
559             if (data == null) return;
560 
561             data.reset();
562             data.type = EVENT_UID_FIREWALL_RULE_CHANGED;
563             data.ifield1 = chain;
564             data.ifield2 = uid;
565             data.ifield3 = rule;
566             data.timeStamp = System.currentTimeMillis();
567         }
568 
firewallChainEnabled(int chain, boolean enabled)569         public void firewallChainEnabled(int chain, boolean enabled) {
570             final Data data = getNextSlot();
571             if (data == null) return;
572 
573             data.reset();
574             data.type = EVENT_FIREWALL_CHAIN_ENABLED;
575             data.ifield1 = chain;
576             data.bfield1 = enabled;
577             data.timeStamp = System.currentTimeMillis();
578         }
579 
meteredAllowlistChanged(int uid, boolean added)580         public void meteredAllowlistChanged(int uid, boolean added) {
581             final Data data = getNextSlot();
582             if (data == null) return;
583 
584             data.reset();
585             data.type = EVENT_METERED_ALLOWLIST_CHANGED;
586             data.ifield1 = uid;
587             data.bfield1 = added;
588             data.timeStamp = System.currentTimeMillis();
589         }
590 
meteredDenylistChanged(int uid, boolean added)591         public void meteredDenylistChanged(int uid, boolean added) {
592             final Data data = getNextSlot();
593             if (data == null) return;
594 
595             data.reset();
596             data.type = EVENT_METERED_DENYLIST_CHANGED;
597             data.ifield1 = uid;
598             data.bfield1 = added;
599             data.timeStamp = System.currentTimeMillis();
600         }
601 
roamingChanged(int netId, boolean newRoaming)602         public void roamingChanged(int netId, boolean newRoaming) {
603             final Data data = getNextSlot();
604             if (data == null) return;
605 
606             data.reset();
607             data.type = EVENT_ROAMING_CHANGED;
608             data.ifield1 = netId;
609             data.bfield1 = newRoaming;
610             data.timeStamp = System.currentTimeMillis();
611         }
612 
interfacesChanged(int netId, String newIfaces)613         public void interfacesChanged(int netId, String newIfaces) {
614             final Data data = getNextSlot();
615             if (data == null) return;
616 
617             data.reset();
618             data.type = EVENT_INTERFACES_CHANGED;
619             data.ifield1 = netId;
620             data.sfield1 = newIfaces;
621             data.timeStamp = System.currentTimeMillis();
622         }
623 
reverseDump(IndentingPrintWriter pw)624         public void reverseDump(IndentingPrintWriter pw) {
625             final Data[] allData = toArray();
626             for (int i = allData.length - 1; i >= 0; --i) {
627                 if (allData[i] == null) {
628                     pw.println("NULL");
629                     continue;
630                 }
631                 pw.print(formatDate(allData[i].timeStamp));
632                 pw.print(" - ");
633                 pw.println(getContent(allData[i]));
634             }
635         }
636 
getContent(Data data)637         public String getContent(Data data) {
638             switch (data.type) {
639                 case EVENT_TYPE_GENERIC:
640                     return data.sfield1;
641                 case EVENT_NETWORK_BLOCKED:
642                     return data.ifield1 + "-" + UidBlockedState.toString(
643                             data.ifield2, data.ifield3, data.ifield4);
644                 case EVENT_UID_STATE_CHANGED:
645                     return data.ifield1 + ":" + ProcessList.makeProcStateString(data.ifield2)
646                             + ":" + ActivityManager.getCapabilitiesSummary(data.ifield3)
647                             + ":" + data.lfield1;
648                 case EVENT_POLICIES_CHANGED:
649                     return getPolicyChangedLog(data.ifield1, data.ifield2, data.ifield3);
650                 case EVENT_METEREDNESS_CHANGED:
651                     return getMeterednessChangedLog(data.ifield1, data.bfield1);
652                 case EVENT_USER_STATE_REMOVED:
653                     return getUserRemovedLog(data.ifield1);
654                 case EVENT_RESTRICT_BG_CHANGED:
655                     return getRestrictBackgroundChangedLog(data.bfield1, data.bfield2);
656                 case EVENT_DEVICE_IDLE_MODE_ENABLED:
657                     return getDeviceIdleModeEnabled(data.bfield1);
658                 case EVENT_APP_IDLE_STATE_CHANGED:
659                     return getAppIdleChangedLog(data.ifield1, data.bfield1);
660                 case EVENT_APP_IDLE_WL_CHANGED:
661                     return getAppIdleWlChangedLog(data.ifield1, data.bfield1);
662                 case EVENT_PAROLE_STATE_CHANGED:
663                     return getParoleStateChanged(data.bfield1);
664                 case EVENT_TEMP_POWER_SAVE_WL_CHANGED:
665                     return getTempPowerSaveWlChangedLog(data.ifield1, data.bfield1,
666                             data.ifield2, data.sfield1);
667                 case EVENT_UID_FIREWALL_RULE_CHANGED:
668                     return getUidFirewallRuleChangedLog(data.ifield1, data.ifield2, data.ifield3);
669                 case EVENT_FIREWALL_CHAIN_ENABLED:
670                     return getFirewallChainEnabledLog(data.ifield1, data.bfield1);
671                 case EVENT_METERED_ALLOWLIST_CHANGED:
672                     return getMeteredAllowlistChangedLog(data.ifield1, data.bfield1);
673                 case EVENT_METERED_DENYLIST_CHANGED:
674                     return getMeteredDenylistChangedLog(data.ifield1, data.bfield1);
675                 case EVENT_ROAMING_CHANGED:
676                     return getRoamingChangedLog(data.ifield1, data.bfield1);
677                 case EVENT_INTERFACES_CHANGED:
678                     return getInterfacesChangedLog(data.ifield1, data.sfield1);
679                 default:
680                     return String.valueOf(data.type);
681             }
682         }
683 
formatDate(long millis)684         private String formatDate(long millis) {
685             sDate.setTime(millis);
686             return sFormatter.format(sDate);
687         }
688     }
689 
690     /**
691      * Container class for all networkpolicy events data.
692      *
693      * Note: This class needs to be public for RingBuffer class to be able to create
694      * new instances of this.
695      */
696     public static final class Data {
697         public int type;
698         public long timeStamp;
699 
700         public int ifield1;
701         public int ifield2;
702         public int ifield3;
703         public int ifield4;
704         public long lfield1;
705         public boolean bfield1;
706         public boolean bfield2;
707         public String sfield1;
708 
reset()709         public void reset(){
710             sfield1 = null;
711         }
712     }
713 }
714