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