diff options
Diffstat (limited to 'service')
-rw-r--r-- | service/java/com/android/server/wifi/WifiMetrics.java | 111 | ||||
-rw-r--r-- | service/java/com/android/server/wifi/WifiServiceImpl.java | 13 | ||||
-rw-r--r-- | service/proto/src/metrics.proto | 52 |
3 files changed, 173 insertions, 3 deletions
diff --git a/service/java/com/android/server/wifi/WifiMetrics.java b/service/java/com/android/server/wifi/WifiMetrics.java index 7578b8e71..031c495cc 100644 --- a/service/java/com/android/server/wifi/WifiMetrics.java +++ b/service/java/com/android/server/wifi/WifiMetrics.java @@ -77,6 +77,7 @@ import com.android.server.wifi.proto.nano.WifiMetricsProto.PnoScanMetrics; import com.android.server.wifi.proto.nano.WifiMetricsProto.SoftApConnectedClientsEvent; import com.android.server.wifi.proto.nano.WifiMetricsProto.StaEvent; import com.android.server.wifi.proto.nano.WifiMetricsProto.StaEvent.ConfigInfo; +import com.android.server.wifi.proto.nano.WifiMetricsProto.UserActionEvent; import com.android.server.wifi.proto.nano.WifiMetricsProto.WifiIsUnusableEvent; import com.android.server.wifi.proto.nano.WifiMetricsProto.WifiLinkLayerUsageStats; import com.android.server.wifi.proto.nano.WifiMetricsProto.WifiLockStats; @@ -221,7 +222,9 @@ public class WifiMetrics { private long mScoreBreachLowTimeMillis = -1; public static final int MAX_STA_EVENTS = 768; + @VisibleForTesting static final int MAX_USER_ACTION_EVENTS = 200; private LinkedList<StaEventWithTime> mStaEventList = new LinkedList<>(); + private LinkedList<UserActionEventWithTime> mUserActionEventList = new LinkedList<>(); private int mLastPollRssi = -127; private int mLastPollLinkSpeed = -1; private int mLastPollRxLinkSpeed = -1; @@ -725,6 +728,83 @@ public class WifiMetrics { } } + class UserActionEventWithTime { + private UserActionEvent mUserActionEvent; + private long mWallClockTimeMs = 0; // wall clock time for debugging only + + UserActionEventWithTime(int eventType, int targetNetId) { + mUserActionEvent = new UserActionEvent(); + mUserActionEvent.eventType = eventType; + mUserActionEvent.startTimeMillis = mClock.getElapsedSinceBootMillis(); + mWallClockTimeMs = mClock.getWallClockMillis(); + if (targetNetId >= 0) { + WifiConfiguration config = mWifiConfigManager.getConfiguredNetwork(targetNetId); + if (config != null) { + WifiMetricsProto.TargetNetworkInfo networkInfo = + new WifiMetricsProto.TargetNetworkInfo(); + networkInfo.isEphemeral = config.isEphemeral(); + networkInfo.isPasspoint = config.isPasspoint(); + mUserActionEvent.targetNetworkInfo = networkInfo; + } + } + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + Calendar c = Calendar.getInstance(); + c.setTimeInMillis(mWallClockTimeMs); + sb.append(String.format("%tm-%td %tH:%tM:%tS.%tL", c, c, c, c, c, c)); + String eventType = "UNKNOWN"; + switch (mUserActionEvent.eventType) { + case UserActionEvent.EVENT_FORGET_WIFI: + eventType = "EVENT_FORGET_WIFI"; + break; + case UserActionEvent.EVENT_DISCONNECT_WIFI: + eventType = "EVENT_DISCONNECT_WIFI"; + break; + case UserActionEvent.EVENT_CONFIGURE_METERED_STATUS_METERED: + eventType = "EVENT_CONFIGURE_METERED_STATUS_METERED"; + break; + case UserActionEvent.EVENT_CONFIGURE_METERED_STATUS_UNMETERED: + eventType = "EVENT_CONFIGURE_METERED_STATUS_UNMETERED"; + break; + case UserActionEvent.EVENT_CONFIGURE_MAC_RANDOMIZATION_ON: + eventType = "EVENT_CONFIGURE_MAC_RANDOMIZATION_ON"; + break; + case UserActionEvent.EVENT_CONFIGURE_MAC_RANDOMIZATION_OFF: + eventType = "EVENT_CONFIGURE_MAC_RANDOMIZATION_OFF"; + break; + case UserActionEvent.EVENT_CONFIGURE_AUTO_CONNECT_ON: + eventType = "EVENT_CONFIGURE_AUTO_CONNECT_ON"; + break; + case UserActionEvent.EVENT_CONFIGURE_AUTO_CONNECT_OFF: + eventType = "EVENT_CONFIGURE_AUTO_CONNECT_OFF"; + break; + case UserActionEvent.EVENT_TOGGLE_WIFI_ON: + eventType = "EVENT_TOGGLE_WIFI_ON"; + break; + case UserActionEvent.EVENT_TOGGLE_WIFI_OFF: + eventType = "EVENT_TOGGLE_WIFI_OFF"; + break; + case UserActionEvent.EVENT_MANUAL_CONNECT: + eventType = "EVENT_MANUAL_CONNECT"; + break; + } + sb.append(" eventType=").append(eventType); + sb.append(" startTimeMillis=").append(mUserActionEvent.startTimeMillis); + WifiMetricsProto.TargetNetworkInfo networkInfo = mUserActionEvent.targetNetworkInfo; + if (networkInfo != null) { + sb.append(" isEphemeral=").append(networkInfo.isEphemeral); + sb.append(" isPasspoint=").append(networkInfo.isPasspoint); + } + return sb.toString(); + } + + public UserActionEvent toProto() { + return mUserActionEvent; + } + } + /** * Log event, tracking the start time, end time and result of a wireless connection attempt. */ @@ -3254,6 +3334,10 @@ public class WifiMetrics { for (StaEventWithTime event : mStaEventList) { pw.println(event); } + pw.println("UserActionEvents:"); + for (UserActionEventWithTime event : mUserActionEventList) { + pw.println(event); + } pw.println("mWifiLogProto.numPasspointProviders=" + mWifiLogProto.numPasspointProviders); @@ -3937,6 +4021,10 @@ public class WifiMetrics { for (int i = 0; i < mStaEventList.size(); i++) { mWifiLogProto.staEventList[i] = mStaEventList.get(i).staEvent; } + mWifiLogProto.userActionEvents = new UserActionEvent[mUserActionEventList.size()]; + for (int i = 0; i < mUserActionEventList.size(); i++) { + mWifiLogProto.userActionEvents[i] = mUserActionEventList.get(i).toProto(); + } mWifiLogProto.totalSsidsInScanHistogram = makeNumConnectableNetworksBucketArray(mTotalSsidsInScanHistogram); mWifiLogProto.totalBssidsInScanHistogram = @@ -4339,6 +4427,7 @@ public class WifiMetrics { mScanResultRssiTimestampMillis = -1; mSoftApManagerReturnCodeCounts.clear(); mStaEventList.clear(); + mUserActionEventList.clear(); mWifiAwareMetrics.clear(); mRttMetrics.clear(); mTotalSsidsInScanHistogram.clear(); @@ -5009,6 +5098,28 @@ public class WifiMetrics { } /** + * Logs a UserActionEvent without a target network. + * @param eventType the type of user action (one of WifiMetricsProto.UserActionEvent.EventType) + */ + public void logUserActionEvent(int eventType) { + logUserActionEvent(eventType, -1); + } + + /** + * Logs a UserActionEvent which has a target network. + * @param eventType the type of user action (one of WifiMetricsProto.UserActionEvent.EventType) + * @param networkId networkId of the target network. + */ + public void logUserActionEvent(int eventType, int networkId) { + synchronized (mLock) { + mUserActionEventList.add(new UserActionEventWithTime(eventType, networkId)); + if (mUserActionEventList.size() > MAX_USER_ACTION_EVENTS) { + mUserActionEventList.remove(); + } + } + } + + /** * Update the difference between the last two WifiLinkLayerStats for WifiIsUnusableEvent */ public void updateWifiIsUnusableLinkLayerStats(long txSuccessDelta, long txRetriesDelta, diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java index a373c3fae..4a9902484 100644 --- a/service/java/com/android/server/wifi/WifiServiceImpl.java +++ b/service/java/com/android/server/wifi/WifiServiceImpl.java @@ -112,6 +112,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.AsyncChannel; import com.android.server.wifi.hotspot2.PasspointManager; import com.android.server.wifi.hotspot2.PasspointProvider; +import com.android.server.wifi.proto.nano.WifiMetricsProto; import com.android.server.wifi.util.ApConfigUtil; import com.android.server.wifi.util.ExternalCallbackTracker; import com.android.server.wifi.util.RssiUtil; @@ -4090,12 +4091,18 @@ public class WifiServiceImpl extends BaseWifiService { @Override public void forget(int netId, IBinder binder, @Nullable IActionListener callback, int callbackIdentifier) { - if (!isPrivileged(Binder.getCallingPid(), Binder.getCallingUid())) { + int uid = Binder.getCallingUid(); + if (!isPrivileged(Binder.getCallingPid(), uid)) { throw new SecurityException(TAG + ": Permission denied"); } mLog.info("forget uid=%").c(Binder.getCallingUid()).flush(); - mClientModeImpl.forget( - netId, binder, callback, callbackIdentifier, Binder.getCallingUid()); + if (mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)) { + // It's important to log this metric before the actual forget executes because + // the netId becomes invalid after the forget operation. + mWifiMetrics.logUserActionEvent(WifiMetricsProto.UserActionEvent.EVENT_FORGET_WIFI, + netId); + } + mClientModeImpl.forget(netId, binder, callback, callbackIdentifier, uid); } /** diff --git a/service/proto/src/metrics.proto b/service/proto/src/metrics.proto index 6fddc69ce..d1dd39e49 100644 --- a/service/proto/src/metrics.proto +++ b/service/proto/src/metrics.proto @@ -684,6 +684,9 @@ message WifiLog { // Total number of Passpoint providers with subscription expiration date in their profile. optional int32 num_passpoint_provider_with_subscription_expiration = 191; + + // List of user initiated actions + repeated UserActionEvent user_action_events = 192; } // Information that gets logged for every WiFi connection. @@ -3052,6 +3055,55 @@ message PasspointProvisionStats { } } +// An event capturing user action on wifi +message UserActionEvent { + enum EventType { + // The default and unused event + EVENT_UNKNOWN = 0; + // User forgets the network + EVENT_FORGET_WIFI = 1; + // User manually triggers disconnect + EVENT_DISCONNECT_WIFI = 2; + // User changes the metered setting to "metered" + EVENT_CONFIGURE_METERED_STATUS_METERED = 3; + // User changes the metered setting to "unmetered" + EVENT_CONFIGURE_METERED_STATUS_UNMETERED = 4; + // User changes the mac randomization setting to use random MAC + EVENT_CONFIGURE_MAC_RANDOMIZATION_ON = 5; + // User changes the mac randomization setting to use factory MAC + EVENT_CONFIGURE_MAC_RANDOMIZATION_OFF = 6; + // User sets auto-connect to on + EVENT_CONFIGURE_AUTO_CONNECT_ON = 7; + // User sets auto-connect to off + EVENT_CONFIGURE_AUTO_CONNECT_OFF = 8; + // User toggles wifi on + EVENT_TOGGLE_WIFI_ON = 9; + // User toggles wifi off + EVENT_TOGGLE_WIFI_OFF = 10; + // User manually connects to a network + EVENT_MANUAL_CONNECT = 11; + } + + // The type of user action + optional EventType event_type = 1; + + // The start time of the event in milliseconds since boot. + optional int64 start_time_millis = 2; + + // Additional information on the target network for the action. This is not applicable and will + // be null for some actions such as EVENT_TOGGLE_WIFI_ON. + optional TargetNetworkInfo target_network_info = 3; +} + +// Additional information on a network +message TargetNetworkInfo { + // Whether the network is an ephemeral network. + optional bool is_ephemeral = 1; + + // Whether the target is a passpoint network. + optional bool is_passpoint = 2; +} + // Number of networks with a large change of connection/disconnection // failure rate or high failure rate at high RSSI message HealthMonitorFailureStats { |