From fee853b8a1b00405d9d1d8c4b081f96f3c2ac7f5 Mon Sep 17 00:00:00 2001 From: Chiachang Wang Date: Wed, 23 Dec 2020 16:27:08 +0800 Subject: [PATCH] [IT4.3] Listen interface change in BSS Reporting interface change is planning to move from NMS to CS for incoming CS mainline. The event sent from CS to NMS will be replaced by sending to netd directly, so the change reported via NMS to BSS should be handled by BSS directly. This commit allows BSS to listen interface change itself to separate the design. Bug: 170598012 Test: m ; atest FrameworksCoreTests:BatteryStatsTests Change-Id: I4c9202be31cad09451ef47ac7b5b87f7efb2020c Merged-In: I9c1b2294905d3b59f6945c3f8acb91b2e419b492 --- .../server/NetworkManagementService.java | 6 ++ .../server/am/BatteryStatsService.java | 55 +++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java index 1ea4a89a761f0..d30a6405e95dd 100644 --- a/services/core/java/com/android/server/NetworkManagementService.java +++ b/services/core/java/com/android/server/NetworkManagementService.java @@ -405,6 +405,9 @@ public class NetworkManagementService extends INetworkManagementService.Stub { if (mLastPowerStateFromRadio != powerState) { mLastPowerStateFromRadio = powerState; try { + // TODO: The interface changes that comes from netd are handled by BSS itself. + // There are still events caused by setting or removing idle timer, so keep + // reporting from here until setting idler timer moved to CS. getBatteryStats().noteMobileRadioPowerState(powerState, tsNanos, uid); } catch (RemoteException e) { } @@ -415,6 +418,9 @@ public class NetworkManagementService extends INetworkManagementService.Stub { if (mLastPowerStateFromWifi != powerState) { mLastPowerStateFromWifi = powerState; try { + // TODO: The interface changes that comes from netd are handled by BSS itself. + // There are still events caused by setting or removing idle timer, so keep + // reporting from here until setting idler timer moved to CS. getBatteryStats().noteWifiRadioPowerState(powerState, tsNanos, uid); } catch (RemoteException e) { } diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index 1ade8e7e9311f..3c538806be015 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -21,11 +21,14 @@ import android.content.ContentResolver; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; +import android.net.INetworkManagementEventObserver; +import android.net.NetworkCapabilities; import android.os.BatteryStats; import android.os.BatteryStatsInternal; import android.os.Binder; import android.os.Handler; import android.os.IBinder; +import android.os.INetworkManagementService; import android.os.Parcel; import android.os.ParcelFileDescriptor; import android.os.ParcelFormatException; @@ -33,6 +36,7 @@ import android.os.PowerManager.ServiceType; import android.os.PowerManagerInternal; import android.os.PowerSaveState; import android.os.Process; +import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; import android.os.UserHandle; @@ -52,6 +56,7 @@ import android.telephony.SignalStrength; import android.telephony.TelephonyManager; import android.util.Slog; +import com.android.internal.annotations.GuardedBy; import com.android.internal.app.IBatteryStats; import com.android.internal.os.BatteryStatsHelper; import com.android.internal.os.BatteryStatsImpl; @@ -62,6 +67,7 @@ import com.android.internal.util.DumpUtils; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.ParseUtils; import com.android.server.LocalServices; +import com.android.server.net.BaseNetworkObserver; import java.io.File; import java.io.FileDescriptor; @@ -108,6 +114,39 @@ public final class BatteryStatsService extends IBatteryStats.Stub private CharBuffer mUtf16BufferStat = CharBuffer.allocate(MAX_LOW_POWER_STATS_SIZE); private static final int MAX_LOW_POWER_STATS_SIZE = 4096; + @GuardedBy("mStats") + private int mLastPowerStateFromRadio = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; + @GuardedBy("mStats") + private int mLastPowerStateFromWifi = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; + private final INetworkManagementEventObserver mActivityChangeObserver = + new BaseNetworkObserver() { + @Override + public void interfaceClassDataActivityChanged(int transportType, boolean active, + long tsNanos, int uid) { + final int powerState = active + ? DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH + : DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; + final long timestampNanos; + if (tsNanos <= 0) { + timestampNanos = SystemClock.elapsedRealtimeNanos(); + } else { + timestampNanos = tsNanos; + } + + switch (transportType) { + case NetworkCapabilities.TRANSPORT_CELLULAR: + noteMobileRadioPowerState(powerState, timestampNanos, uid); + break; + case NetworkCapabilities.TRANSPORT_WIFI: + noteWifiRadioPowerState(powerState, timestampNanos, uid); + break; + default: + Slog.d(TAG, "Received unexpected transport in " + + "interfaceClassDataActivityChanged unexpected type: " + + transportType); + } + } + }; /** * Replaces the information in the given rpmStats with up-to-date information. */ @@ -203,6 +242,13 @@ public final class BatteryStatsService extends IBatteryStats.Stub } public void systemServicesReady() { + final INetworkManagementService nms = INetworkManagementService.Stub.asInterface( + ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE)); + try { + nms.registerObserver(mActivityChangeObserver); + } catch (RemoteException e) { + Slog.e(TAG, "Could not register INetworkManagement event observer " + e); + } mStats.systemServicesReady(mContext); } @@ -680,8 +726,13 @@ public final class BatteryStatsService extends IBatteryStats.Stub public void noteMobileRadioPowerState(int powerState, long timestampNs, int uid) { enforceCallingPermission(); + final boolean update; synchronized (mStats) { + // Ignore if no power state change. + if (mLastPowerStateFromRadio == powerState) return; + + mLastPowerStateFromRadio = powerState; update = mStats.noteMobileRadioPowerStateLocked(powerState, timestampNs, uid); } @@ -863,6 +914,10 @@ public final class BatteryStatsService extends IBatteryStats.Stub // There was a change in WiFi power state. // Collect data now for the past activity. synchronized (mStats) { + // Ignore if no power state change. + if (mLastPowerStateFromWifi == powerState) return; + + mLastPowerStateFromWifi = powerState; if (mStats.isOnBattery()) { final String type = (powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM) ? "active"