Loading android/app/src/com/android/bluetooth/BluetoothMethodProxy.java +2 −2 Original line number Diff line number Diff line Loading @@ -266,8 +266,8 @@ public class BluetoothMethodProxy { /** Proxies {@link AppAdvertiseStats}. */ public AppAdvertiseStats createAppAdvertiseStats( int id, String name, ContextMap map, GattService service) { return new AppAdvertiseStats(id, name, map, service); int appUid, int id, String name, ContextMap map, GattService service) { return new AppAdvertiseStats(appUid, id, name, map, service); } /** Proxies {@link Thread#start()}. */ Loading android/app/src/com/android/bluetooth/btservice/MetricsLogger.java +82 −0 Original line number Diff line number Diff line Loading @@ -389,6 +389,88 @@ public class MetricsLogger { return matchedString; } /** Logs the app scan stats with app attribution when the app scan state changed. */ public void logAppScanStateChanged( int[] uids, String[] tags, boolean enabled, boolean isFilterScan, boolean isCallbackScan, int scanCallBackType, int scanType, int scanMode, long reportDelayMillis, long scanDurationMillis, int numOngoingScan, boolean isScreenOn, boolean isAppDead) { BluetoothStatsLog.write( BluetoothStatsLog.LE_APP_SCAN_STATE_CHANGED, uids, tags, enabled, isFilterScan, isCallbackScan, scanCallBackType, scanType, scanMode, reportDelayMillis, scanDurationMillis, numOngoingScan, isScreenOn, isAppDead); } /** Logs the radio scan stats with app attribution when the radio scan stopped. */ public void logRadioScanStopped( int[] uids, String[] tags, int scanType, int scanMode, long scanIntervalMillis, long scanWindowMillis, boolean isScreenOn, long scanDurationMillis) { BluetoothStatsLog.write( BluetoothStatsLog.LE_RADIO_SCAN_STOPPED, uids, tags, scanType, scanMode, scanIntervalMillis, scanWindowMillis, isScreenOn, scanDurationMillis); } /** Logs the advertise stats with app attribution when the advertise state changed. */ public void logAdvStateChanged( int[] uids, String[] tags, boolean enabled, int interval, int txPowerLevel, boolean isConnectable, boolean isPeriodicAdvertisingEnabled, boolean hasScanResponse, boolean isExtendedAdv, int instanceCount, long advDurationMs) { BluetoothStatsLog.write( BluetoothStatsLog.LE_ADV_STATE_CHANGED, uids, tags, enabled, interval, txPowerLevel, isConnectable, isPeriodicAdvertisingEnabled, hasScanResponse, isExtendedAdv, instanceCount, advDurationMs); } protected String getAllowlistedDeviceNameHash(String deviceName) { List<String> wordBreakdownList = getWordBreakdownList(deviceName); String matchedString = getMatchedString(wordBreakdownList); Loading android/app/src/com/android/bluetooth/gatt/AdvertiseManager.java +3 −4 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package com.android.bluetooth.gatt; import static android.bluetooth.BluetoothProtoEnums.LE_ADV_ERROR_ON_START_COUNT; import android.bluetooth.le.AdvertiseCallback; import android.bluetooth.le.AdvertiseData; Loading Loading @@ -169,10 +168,10 @@ public class AdvertiseManager { AppAdvertiseStats stats = mAdvertiserMap.getAppAdvertiseStatsById(regId); if (stats != null) { stats.recordAdvertiseStop(); stats.recordAdvertiseStop(mAdvertisers.size()); stats.recordAdvertiseErrorCount(status); } mAdvertiserMap.removeAppAdvertiseStats(regId); AppAdvertiseStats.recordAdvertiseErrorCount(LE_ADV_ERROR_ON_START_COUNT); } IBinder gattBinder = mService.getBinder(); Loading Loading @@ -204,7 +203,7 @@ public class AdvertiseManager { if (!enable && status != 0) { AppAdvertiseStats stats = mAdvertiserMap.getAppAdvertiseStatsById(advertiserId); if (stats != null) { stats.recordAdvertiseStop(); stats.recordAdvertiseStop(mAdvertisers.size()); } } } Loading android/app/src/com/android/bluetooth/gatt/AppAdvertiseStats.java +103 −21 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.bluetooth.gatt; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProtoEnums; import android.bluetooth.le.AdvertiseData; import android.bluetooth.le.AdvertisingSetCallback; import android.bluetooth.le.AdvertisingSetParameters; import android.bluetooth.le.PeriodicAdvertisingParameters; import android.os.ParcelUuid; Loading @@ -25,7 +26,9 @@ import android.util.SparseArray; import androidx.annotation.VisibleForTesting; import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.btservice.MetricsLogger; import com.android.bluetooth.flags.Flags; import java.time.Duration; import java.time.Instant; Loading @@ -35,7 +38,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; /** ScanStats class helps keep track of information about scans on a per application basis. */ /** AdvStats class helps keep track of information about advertising on a per application basis. */ @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) public class AppAdvertiseStats { private static final String TAG = AppAdvertiseStats.class.getSimpleName(); Loading Loading @@ -84,6 +87,7 @@ public class AppAdvertiseStats { } } private int mAppUid; private String mAppName; private int mId; private boolean mAdvertisingEnabled = false; Loading @@ -104,7 +108,8 @@ public class AppAdvertiseStats { public ArrayList<AppAdvertiserRecord> mAdvertiserRecords = new ArrayList<AppAdvertiserRecord>(); @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) public AppAdvertiseStats(int id, String name, ContextMap map, GattService service) { public AppAdvertiseStats(int appUid, int id, String name, ContextMap map, GattService service) { this.mAppUid = appUid; this.mId = id; this.mAppName = name; this.mContextMap = map; Loading @@ -118,7 +123,8 @@ public class AppAdvertiseStats { PeriodicAdvertisingParameters periodicParameters, AdvertiseData periodicData, int duration, int maxExtAdvEvents) { int maxExtAdvEvents, int instanceCount) { mAdvertisingEnabled = true; AppAdvertiserRecord record = new AppAdvertiserRecord(Instant.now()); record.duration = duration; Loading Loading @@ -174,20 +180,24 @@ public class AppAdvertiseStats { mPeriodicIncludeTxPower = periodicParameters.getIncludeTxPower(); mPeriodicInterval = periodicParameters.getInterval(); } recordAdvertiseEnableCount(true, mConnectable, mPeriodicAdvertisingEnabled); recordAdvertiseEnableCount(true, instanceCount, 0 /* durationMs */); } void recordAdvertiseStart(int duration, int maxExtAdvEvents) { recordAdvertiseStart(null, null, null, null, null, duration, maxExtAdvEvents); void recordAdvertiseStart(int duration, int maxExtAdvEvents, int instanceCount) { recordAdvertiseStart( null, null, null, null, null, duration, maxExtAdvEvents, instanceCount); } void recordAdvertiseStop() { recordAdvertiseEnableCount(false, mConnectable, mPeriodicAdvertisingEnabled); void recordAdvertiseStop(int instanceCount) { if (!mAdvertiserRecords.isEmpty()) { AppAdvertiserRecord record = mAdvertiserRecords.get(mAdvertiserRecords.size() - 1); record.stopTime = Instant.now(); Duration duration = Duration.between(record.startTime, record.stopTime); recordAdvertiseDurationCount(duration, mConnectable, mPeriodicAdvertisingEnabled); recordAdvertiseEnableCount( false, instanceCount, record.stopTime.toEpochMilli() - record.startTime.toEpochMilli()); } mAdvertisingEnabled = false; mPeriodicAdvertisingEnabled = false; Loading @@ -206,23 +216,53 @@ public class AppAdvertiseStats { } } static void recordAdvertiseErrorCount(int key) { if (key != BluetoothProtoEnums.LE_ADV_ERROR_ON_START_COUNT) { return; } MetricsLogger.getInstance().cacheCount(key, 1); } void enableAdvertisingSet(boolean enable, int duration, int maxExtAdvEvents) { void recordAdvertiseErrorCount(int status) { if (Flags.bleScanAdvMetricsRedesign()) { BluetoothStatsLog.write( BluetoothStatsLog.LE_ADV_ERROR_REPORTED, new int[] {mAppUid}, new String[] {mAppName}, BluetoothStatsLog.LE_ADV_ERROR_REPORTED__LE_ADV_OP_CODE__ERROR_CODE_ON_START, convertStatusCode(status)); } MetricsLogger.getInstance().cacheCount(BluetoothProtoEnums.LE_ADV_ERROR_ON_START_COUNT, 1); } private int convertStatusCode(int status) { switch (status) { case AdvertisingSetCallback.ADVERTISE_SUCCESS: return BluetoothStatsLog.LE_ADV_ERROR_REPORTED__STATUS_CODE__ADV_STATUS_SUCCESS; case AdvertisingSetCallback.ADVERTISE_FAILED_DATA_TOO_LARGE: return BluetoothStatsLog .LE_ADV_ERROR_REPORTED__STATUS_CODE__ADV_STATUS_FAILED_DATA_TOO_LARGE; case AdvertisingSetCallback.ADVERTISE_FAILED_TOO_MANY_ADVERTISERS: return BluetoothStatsLog .LE_ADV_ERROR_REPORTED__STATUS_CODE__ADV_STATUS_FAILED_TOO_MANY_ADVERTISERS; case AdvertisingSetCallback.ADVERTISE_FAILED_ALREADY_STARTED: return BluetoothStatsLog .LE_ADV_ERROR_REPORTED__STATUS_CODE__ADV_STATUS_FAILED_ALREADY_STARTED; case AdvertisingSetCallback.ADVERTISE_FAILED_INTERNAL_ERROR: return BluetoothStatsLog .LE_ADV_ERROR_REPORTED__STATUS_CODE__ADV_STATUS_FAILED_INTERNAL_ERROR; case AdvertisingSetCallback.ADVERTISE_FAILED_FEATURE_UNSUPPORTED: return BluetoothStatsLog .LE_ADV_ERROR_REPORTED__STATUS_CODE__ADV_STATUS_FAILED_FEATURE_UNSUPPORTED; default: return BluetoothStatsLog.LE_ADV_ERROR_REPORTED__STATUS_CODE__ADV_STATUS_UNKNOWN; } } void enableAdvertisingSet( boolean enable, int duration, int maxExtAdvEvents, int instanceCount) { if (enable) { // if the advertisingSet have not been disabled, skip enabling. if (!mAdvertisingEnabled) { recordAdvertiseStart(duration, maxExtAdvEvents); recordAdvertiseStart(duration, maxExtAdvEvents, instanceCount); } } else { // if the advertisingSet have not been enabled, skip disabling. if (mAdvertisingEnabled) { recordAdvertiseStop(); recordAdvertiseStop(instanceCount); } } } Loading Loading @@ -369,31 +409,73 @@ public class AppAdvertiseStats { } } private static void recordAdvertiseEnableCount( boolean enable, boolean isConnectable, boolean inPeriodic) { private void recordAdvertiseEnableCount(boolean enable, int instanceCount, long durationMs) { if (Flags.bleScanAdvMetricsRedesign()) { MetricsLogger.getInstance() .logAdvStateChanged( new int[] {mAppUid}, new String[] {mAppName}, enable /* enabled */, convertAdvInterval(mInterval), convertTxPowerLevel(mTxPowerLevel), mConnectable, mPeriodicAdvertisingEnabled, mScanResponseData != null && mScannable /* hasScanResponse */, !mLegacy /* isExtendedAdv */, instanceCount, durationMs); } if (enable) { MetricsLogger.getInstance().cacheCount(BluetoothProtoEnums.LE_ADV_COUNT_ENABLE, 1); if (isConnectable) { if (mConnectable) { MetricsLogger.getInstance() .cacheCount(BluetoothProtoEnums.LE_ADV_COUNT_CONNECTABLE_ENABLE, 1); } if (inPeriodic) { if (mPeriodicAdvertisingEnabled) { MetricsLogger.getInstance() .cacheCount(BluetoothProtoEnums.LE_ADV_COUNT_PERIODIC_ENABLE, 1); } } else { MetricsLogger.getInstance().cacheCount(BluetoothProtoEnums.LE_ADV_COUNT_DISABLE, 1); if (isConnectable) { if (mConnectable) { MetricsLogger.getInstance() .cacheCount(BluetoothProtoEnums.LE_ADV_COUNT_CONNECTABLE_DISABLE, 1); } if (inPeriodic) { if (mPeriodicAdvertisingEnabled) { MetricsLogger.getInstance() .cacheCount(BluetoothProtoEnums.LE_ADV_COUNT_PERIODIC_DISABLE, 1); } } } private int convertAdvInterval(int interval) { switch (interval) { case AdvertisingSetParameters.INTERVAL_HIGH: return BluetoothStatsLog.LE_ADV_STATE_CHANGED__ADV_INTERVAL__INTERVAL_HIGH; case AdvertisingSetParameters.INTERVAL_MEDIUM: return BluetoothStatsLog.LE_ADV_STATE_CHANGED__ADV_INTERVAL__INTERVAL_MEDIUM; case AdvertisingSetParameters.INTERVAL_LOW: return BluetoothStatsLog.LE_ADV_STATE_CHANGED__ADV_INTERVAL__INTERVAL_LOW; default: return BluetoothStatsLog.LE_ADV_STATE_CHANGED__ADV_INTERVAL__INTERVAL_UNKNOWN; } } private int convertTxPowerLevel(int level) { switch (level) { case AdvertisingSetParameters.TX_POWER_ULTRA_LOW: return BluetoothStatsLog.LE_ADV_STATE_CHANGED__ADV_TX_POWER__TX_POWER_ULTRA_LOW; case AdvertisingSetParameters.TX_POWER_LOW: return BluetoothStatsLog.LE_ADV_STATE_CHANGED__ADV_TX_POWER__TX_POWER_LOW; case AdvertisingSetParameters.TX_POWER_MEDIUM: return BluetoothStatsLog.LE_ADV_STATE_CHANGED__ADV_TX_POWER__TX_POWER_MEDIUM; case AdvertisingSetParameters.TX_POWER_HIGH: return BluetoothStatsLog.LE_ADV_STATE_CHANGED__ADV_TX_POWER__TX_POWER_HIGH; default: return BluetoothStatsLog.LE_ADV_STATE_CHANGED__ADV_TX_POWER__TX_POWER_UNKNOWN; } } private static void dumpAppAdvertiserData(StringBuilder sb, AppAdvertiserData advData) { sb.append( "\n └Include Device Name : " Loading android/app/src/com/android/bluetooth/gatt/ContextMap.java +9 −7 Original line number Diff line number Diff line Loading @@ -252,7 +252,7 @@ public class ContextMap<C, T> { if (!mAppAdvertiseStats.containsKey(id)) { AppAdvertiseStats appAdvertiseStats = BluetoothMethodProxy.getInstance() .createAppAdvertiseStats(id, appName, this, service); .createAppAdvertiseStats(appUid, id, appName, this, service); mAppAdvertiseStats.put(id, appAdvertiseStats); } } Loading Loading @@ -450,6 +450,9 @@ public class ContextMap<C, T> { if (stats == null) { return; } int advertiseInstanceCount = mAppAdvertiseStats.size(); Log.d(TAG, "advertiseInstanceCount is " + advertiseInstanceCount); AppAdvertiseStats.recordAdvertiseInstanceCount(advertiseInstanceCount); stats.recordAdvertiseStart( parameters, advertiseData, Loading @@ -457,10 +460,8 @@ public class ContextMap<C, T> { periodicParameters, periodicData, duration, maxExtAdvEvents); int advertiseInstanceCount = mAppAdvertiseStats.size(); Log.d(TAG, "advertiseInstanceCount is " + advertiseInstanceCount); AppAdvertiseStats.recordAdvertiseInstanceCount(advertiseInstanceCount); maxExtAdvEvents, advertiseInstanceCount); } } Loading @@ -470,7 +471,7 @@ public class ContextMap<C, T> { if (stats == null) { return; } stats.recordAdvertiseStop(); stats.recordAdvertiseStop(mAppAdvertiseStats.size()); mAppAdvertiseStats.remove(id); mLastAdvertises.add(stats); } Loading @@ -482,7 +483,8 @@ public class ContextMap<C, T> { if (stats == null) { return; } stats.enableAdvertisingSet(enable, duration, maxExtAdvEvents); stats.enableAdvertisingSet( enable, duration, maxExtAdvEvents, mAppAdvertiseStats.size()); } } Loading Loading
android/app/src/com/android/bluetooth/BluetoothMethodProxy.java +2 −2 Original line number Diff line number Diff line Loading @@ -266,8 +266,8 @@ public class BluetoothMethodProxy { /** Proxies {@link AppAdvertiseStats}. */ public AppAdvertiseStats createAppAdvertiseStats( int id, String name, ContextMap map, GattService service) { return new AppAdvertiseStats(id, name, map, service); int appUid, int id, String name, ContextMap map, GattService service) { return new AppAdvertiseStats(appUid, id, name, map, service); } /** Proxies {@link Thread#start()}. */ Loading
android/app/src/com/android/bluetooth/btservice/MetricsLogger.java +82 −0 Original line number Diff line number Diff line Loading @@ -389,6 +389,88 @@ public class MetricsLogger { return matchedString; } /** Logs the app scan stats with app attribution when the app scan state changed. */ public void logAppScanStateChanged( int[] uids, String[] tags, boolean enabled, boolean isFilterScan, boolean isCallbackScan, int scanCallBackType, int scanType, int scanMode, long reportDelayMillis, long scanDurationMillis, int numOngoingScan, boolean isScreenOn, boolean isAppDead) { BluetoothStatsLog.write( BluetoothStatsLog.LE_APP_SCAN_STATE_CHANGED, uids, tags, enabled, isFilterScan, isCallbackScan, scanCallBackType, scanType, scanMode, reportDelayMillis, scanDurationMillis, numOngoingScan, isScreenOn, isAppDead); } /** Logs the radio scan stats with app attribution when the radio scan stopped. */ public void logRadioScanStopped( int[] uids, String[] tags, int scanType, int scanMode, long scanIntervalMillis, long scanWindowMillis, boolean isScreenOn, long scanDurationMillis) { BluetoothStatsLog.write( BluetoothStatsLog.LE_RADIO_SCAN_STOPPED, uids, tags, scanType, scanMode, scanIntervalMillis, scanWindowMillis, isScreenOn, scanDurationMillis); } /** Logs the advertise stats with app attribution when the advertise state changed. */ public void logAdvStateChanged( int[] uids, String[] tags, boolean enabled, int interval, int txPowerLevel, boolean isConnectable, boolean isPeriodicAdvertisingEnabled, boolean hasScanResponse, boolean isExtendedAdv, int instanceCount, long advDurationMs) { BluetoothStatsLog.write( BluetoothStatsLog.LE_ADV_STATE_CHANGED, uids, tags, enabled, interval, txPowerLevel, isConnectable, isPeriodicAdvertisingEnabled, hasScanResponse, isExtendedAdv, instanceCount, advDurationMs); } protected String getAllowlistedDeviceNameHash(String deviceName) { List<String> wordBreakdownList = getWordBreakdownList(deviceName); String matchedString = getMatchedString(wordBreakdownList); Loading
android/app/src/com/android/bluetooth/gatt/AdvertiseManager.java +3 −4 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package com.android.bluetooth.gatt; import static android.bluetooth.BluetoothProtoEnums.LE_ADV_ERROR_ON_START_COUNT; import android.bluetooth.le.AdvertiseCallback; import android.bluetooth.le.AdvertiseData; Loading Loading @@ -169,10 +168,10 @@ public class AdvertiseManager { AppAdvertiseStats stats = mAdvertiserMap.getAppAdvertiseStatsById(regId); if (stats != null) { stats.recordAdvertiseStop(); stats.recordAdvertiseStop(mAdvertisers.size()); stats.recordAdvertiseErrorCount(status); } mAdvertiserMap.removeAppAdvertiseStats(regId); AppAdvertiseStats.recordAdvertiseErrorCount(LE_ADV_ERROR_ON_START_COUNT); } IBinder gattBinder = mService.getBinder(); Loading Loading @@ -204,7 +203,7 @@ public class AdvertiseManager { if (!enable && status != 0) { AppAdvertiseStats stats = mAdvertiserMap.getAppAdvertiseStatsById(advertiserId); if (stats != null) { stats.recordAdvertiseStop(); stats.recordAdvertiseStop(mAdvertisers.size()); } } } Loading
android/app/src/com/android/bluetooth/gatt/AppAdvertiseStats.java +103 −21 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.bluetooth.gatt; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProtoEnums; import android.bluetooth.le.AdvertiseData; import android.bluetooth.le.AdvertisingSetCallback; import android.bluetooth.le.AdvertisingSetParameters; import android.bluetooth.le.PeriodicAdvertisingParameters; import android.os.ParcelUuid; Loading @@ -25,7 +26,9 @@ import android.util.SparseArray; import androidx.annotation.VisibleForTesting; import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.btservice.MetricsLogger; import com.android.bluetooth.flags.Flags; import java.time.Duration; import java.time.Instant; Loading @@ -35,7 +38,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; /** ScanStats class helps keep track of information about scans on a per application basis. */ /** AdvStats class helps keep track of information about advertising on a per application basis. */ @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) public class AppAdvertiseStats { private static final String TAG = AppAdvertiseStats.class.getSimpleName(); Loading Loading @@ -84,6 +87,7 @@ public class AppAdvertiseStats { } } private int mAppUid; private String mAppName; private int mId; private boolean mAdvertisingEnabled = false; Loading @@ -104,7 +108,8 @@ public class AppAdvertiseStats { public ArrayList<AppAdvertiserRecord> mAdvertiserRecords = new ArrayList<AppAdvertiserRecord>(); @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) public AppAdvertiseStats(int id, String name, ContextMap map, GattService service) { public AppAdvertiseStats(int appUid, int id, String name, ContextMap map, GattService service) { this.mAppUid = appUid; this.mId = id; this.mAppName = name; this.mContextMap = map; Loading @@ -118,7 +123,8 @@ public class AppAdvertiseStats { PeriodicAdvertisingParameters periodicParameters, AdvertiseData periodicData, int duration, int maxExtAdvEvents) { int maxExtAdvEvents, int instanceCount) { mAdvertisingEnabled = true; AppAdvertiserRecord record = new AppAdvertiserRecord(Instant.now()); record.duration = duration; Loading Loading @@ -174,20 +180,24 @@ public class AppAdvertiseStats { mPeriodicIncludeTxPower = periodicParameters.getIncludeTxPower(); mPeriodicInterval = periodicParameters.getInterval(); } recordAdvertiseEnableCount(true, mConnectable, mPeriodicAdvertisingEnabled); recordAdvertiseEnableCount(true, instanceCount, 0 /* durationMs */); } void recordAdvertiseStart(int duration, int maxExtAdvEvents) { recordAdvertiseStart(null, null, null, null, null, duration, maxExtAdvEvents); void recordAdvertiseStart(int duration, int maxExtAdvEvents, int instanceCount) { recordAdvertiseStart( null, null, null, null, null, duration, maxExtAdvEvents, instanceCount); } void recordAdvertiseStop() { recordAdvertiseEnableCount(false, mConnectable, mPeriodicAdvertisingEnabled); void recordAdvertiseStop(int instanceCount) { if (!mAdvertiserRecords.isEmpty()) { AppAdvertiserRecord record = mAdvertiserRecords.get(mAdvertiserRecords.size() - 1); record.stopTime = Instant.now(); Duration duration = Duration.between(record.startTime, record.stopTime); recordAdvertiseDurationCount(duration, mConnectable, mPeriodicAdvertisingEnabled); recordAdvertiseEnableCount( false, instanceCount, record.stopTime.toEpochMilli() - record.startTime.toEpochMilli()); } mAdvertisingEnabled = false; mPeriodicAdvertisingEnabled = false; Loading @@ -206,23 +216,53 @@ public class AppAdvertiseStats { } } static void recordAdvertiseErrorCount(int key) { if (key != BluetoothProtoEnums.LE_ADV_ERROR_ON_START_COUNT) { return; } MetricsLogger.getInstance().cacheCount(key, 1); } void enableAdvertisingSet(boolean enable, int duration, int maxExtAdvEvents) { void recordAdvertiseErrorCount(int status) { if (Flags.bleScanAdvMetricsRedesign()) { BluetoothStatsLog.write( BluetoothStatsLog.LE_ADV_ERROR_REPORTED, new int[] {mAppUid}, new String[] {mAppName}, BluetoothStatsLog.LE_ADV_ERROR_REPORTED__LE_ADV_OP_CODE__ERROR_CODE_ON_START, convertStatusCode(status)); } MetricsLogger.getInstance().cacheCount(BluetoothProtoEnums.LE_ADV_ERROR_ON_START_COUNT, 1); } private int convertStatusCode(int status) { switch (status) { case AdvertisingSetCallback.ADVERTISE_SUCCESS: return BluetoothStatsLog.LE_ADV_ERROR_REPORTED__STATUS_CODE__ADV_STATUS_SUCCESS; case AdvertisingSetCallback.ADVERTISE_FAILED_DATA_TOO_LARGE: return BluetoothStatsLog .LE_ADV_ERROR_REPORTED__STATUS_CODE__ADV_STATUS_FAILED_DATA_TOO_LARGE; case AdvertisingSetCallback.ADVERTISE_FAILED_TOO_MANY_ADVERTISERS: return BluetoothStatsLog .LE_ADV_ERROR_REPORTED__STATUS_CODE__ADV_STATUS_FAILED_TOO_MANY_ADVERTISERS; case AdvertisingSetCallback.ADVERTISE_FAILED_ALREADY_STARTED: return BluetoothStatsLog .LE_ADV_ERROR_REPORTED__STATUS_CODE__ADV_STATUS_FAILED_ALREADY_STARTED; case AdvertisingSetCallback.ADVERTISE_FAILED_INTERNAL_ERROR: return BluetoothStatsLog .LE_ADV_ERROR_REPORTED__STATUS_CODE__ADV_STATUS_FAILED_INTERNAL_ERROR; case AdvertisingSetCallback.ADVERTISE_FAILED_FEATURE_UNSUPPORTED: return BluetoothStatsLog .LE_ADV_ERROR_REPORTED__STATUS_CODE__ADV_STATUS_FAILED_FEATURE_UNSUPPORTED; default: return BluetoothStatsLog.LE_ADV_ERROR_REPORTED__STATUS_CODE__ADV_STATUS_UNKNOWN; } } void enableAdvertisingSet( boolean enable, int duration, int maxExtAdvEvents, int instanceCount) { if (enable) { // if the advertisingSet have not been disabled, skip enabling. if (!mAdvertisingEnabled) { recordAdvertiseStart(duration, maxExtAdvEvents); recordAdvertiseStart(duration, maxExtAdvEvents, instanceCount); } } else { // if the advertisingSet have not been enabled, skip disabling. if (mAdvertisingEnabled) { recordAdvertiseStop(); recordAdvertiseStop(instanceCount); } } } Loading Loading @@ -369,31 +409,73 @@ public class AppAdvertiseStats { } } private static void recordAdvertiseEnableCount( boolean enable, boolean isConnectable, boolean inPeriodic) { private void recordAdvertiseEnableCount(boolean enable, int instanceCount, long durationMs) { if (Flags.bleScanAdvMetricsRedesign()) { MetricsLogger.getInstance() .logAdvStateChanged( new int[] {mAppUid}, new String[] {mAppName}, enable /* enabled */, convertAdvInterval(mInterval), convertTxPowerLevel(mTxPowerLevel), mConnectable, mPeriodicAdvertisingEnabled, mScanResponseData != null && mScannable /* hasScanResponse */, !mLegacy /* isExtendedAdv */, instanceCount, durationMs); } if (enable) { MetricsLogger.getInstance().cacheCount(BluetoothProtoEnums.LE_ADV_COUNT_ENABLE, 1); if (isConnectable) { if (mConnectable) { MetricsLogger.getInstance() .cacheCount(BluetoothProtoEnums.LE_ADV_COUNT_CONNECTABLE_ENABLE, 1); } if (inPeriodic) { if (mPeriodicAdvertisingEnabled) { MetricsLogger.getInstance() .cacheCount(BluetoothProtoEnums.LE_ADV_COUNT_PERIODIC_ENABLE, 1); } } else { MetricsLogger.getInstance().cacheCount(BluetoothProtoEnums.LE_ADV_COUNT_DISABLE, 1); if (isConnectable) { if (mConnectable) { MetricsLogger.getInstance() .cacheCount(BluetoothProtoEnums.LE_ADV_COUNT_CONNECTABLE_DISABLE, 1); } if (inPeriodic) { if (mPeriodicAdvertisingEnabled) { MetricsLogger.getInstance() .cacheCount(BluetoothProtoEnums.LE_ADV_COUNT_PERIODIC_DISABLE, 1); } } } private int convertAdvInterval(int interval) { switch (interval) { case AdvertisingSetParameters.INTERVAL_HIGH: return BluetoothStatsLog.LE_ADV_STATE_CHANGED__ADV_INTERVAL__INTERVAL_HIGH; case AdvertisingSetParameters.INTERVAL_MEDIUM: return BluetoothStatsLog.LE_ADV_STATE_CHANGED__ADV_INTERVAL__INTERVAL_MEDIUM; case AdvertisingSetParameters.INTERVAL_LOW: return BluetoothStatsLog.LE_ADV_STATE_CHANGED__ADV_INTERVAL__INTERVAL_LOW; default: return BluetoothStatsLog.LE_ADV_STATE_CHANGED__ADV_INTERVAL__INTERVAL_UNKNOWN; } } private int convertTxPowerLevel(int level) { switch (level) { case AdvertisingSetParameters.TX_POWER_ULTRA_LOW: return BluetoothStatsLog.LE_ADV_STATE_CHANGED__ADV_TX_POWER__TX_POWER_ULTRA_LOW; case AdvertisingSetParameters.TX_POWER_LOW: return BluetoothStatsLog.LE_ADV_STATE_CHANGED__ADV_TX_POWER__TX_POWER_LOW; case AdvertisingSetParameters.TX_POWER_MEDIUM: return BluetoothStatsLog.LE_ADV_STATE_CHANGED__ADV_TX_POWER__TX_POWER_MEDIUM; case AdvertisingSetParameters.TX_POWER_HIGH: return BluetoothStatsLog.LE_ADV_STATE_CHANGED__ADV_TX_POWER__TX_POWER_HIGH; default: return BluetoothStatsLog.LE_ADV_STATE_CHANGED__ADV_TX_POWER__TX_POWER_UNKNOWN; } } private static void dumpAppAdvertiserData(StringBuilder sb, AppAdvertiserData advData) { sb.append( "\n └Include Device Name : " Loading
android/app/src/com/android/bluetooth/gatt/ContextMap.java +9 −7 Original line number Diff line number Diff line Loading @@ -252,7 +252,7 @@ public class ContextMap<C, T> { if (!mAppAdvertiseStats.containsKey(id)) { AppAdvertiseStats appAdvertiseStats = BluetoothMethodProxy.getInstance() .createAppAdvertiseStats(id, appName, this, service); .createAppAdvertiseStats(appUid, id, appName, this, service); mAppAdvertiseStats.put(id, appAdvertiseStats); } } Loading Loading @@ -450,6 +450,9 @@ public class ContextMap<C, T> { if (stats == null) { return; } int advertiseInstanceCount = mAppAdvertiseStats.size(); Log.d(TAG, "advertiseInstanceCount is " + advertiseInstanceCount); AppAdvertiseStats.recordAdvertiseInstanceCount(advertiseInstanceCount); stats.recordAdvertiseStart( parameters, advertiseData, Loading @@ -457,10 +460,8 @@ public class ContextMap<C, T> { periodicParameters, periodicData, duration, maxExtAdvEvents); int advertiseInstanceCount = mAppAdvertiseStats.size(); Log.d(TAG, "advertiseInstanceCount is " + advertiseInstanceCount); AppAdvertiseStats.recordAdvertiseInstanceCount(advertiseInstanceCount); maxExtAdvEvents, advertiseInstanceCount); } } Loading @@ -470,7 +471,7 @@ public class ContextMap<C, T> { if (stats == null) { return; } stats.recordAdvertiseStop(); stats.recordAdvertiseStop(mAppAdvertiseStats.size()); mAppAdvertiseStats.remove(id); mLastAdvertises.add(stats); } Loading @@ -482,7 +483,8 @@ public class ContextMap<C, T> { if (stats == null) { return; } stats.enableAdvertisingSet(enable, duration, maxExtAdvEvents); stats.enableAdvertisingSet( enable, duration, maxExtAdvEvents, mAppAdvertiseStats.size()); } } Loading