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