Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 37db66cb authored by Stephanie Bak's avatar Stephanie Bak
Browse files

Add APM session metrics

Bug: 247470852
Test: statsd_testdrive 521
Change-Id: Ie9d27426578e0605965b8f35eed4a51c9a7e2196
parent 9b232a14
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ filegroup {
    name: "services.bluetooth-sources",
    srcs: [
        "java/**/*.java",
        ":statslog-bluetooth-java-gen",
    ],
    visibility: [
        "//frameworks/base/services",
@@ -60,6 +61,7 @@ java_library {
        "framework-annotations-lib",
        "framework-bluetooth-pre-jarjar",
        "app-compat-annotations",
        "framework-statsd.stubs.module_lib",
    ],

    static_libs: [
@@ -69,6 +71,9 @@ java_library {
        "bluetooth-manager-service-proto-java-gen",
        "bluetooth-proto-enums-java-gen",
        "bluetooth-nano-protos",
        "bluetooth-protos-lite",
        "libprotobuf-java-lite",
        "bluetooth-proto-enums-java-gen",
    ],

    apex_available: [
+77 −36
Original line number Diff line number Diff line
@@ -24,9 +24,11 @@ import android.database.ContentObserver;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
import android.provider.Settings;
import android.util.Log;

import com.android.bluetooth.BluetoothStatsLog;
import com.android.internal.annotations.VisibleForTesting;

/**
@@ -68,6 +70,19 @@ public class BluetoothAirplaneModeListener {

    @VisibleForTesting static final int MAX_TOAST_COUNT = 10; // 10 times

    /* Tracks the bluetooth state before entering airplane mode*/
    private boolean mIsBluetoothOnBeforeApmToggle = false;
    /* Tracks the bluetooth state after entering airplane mode*/
    private boolean mIsBluetoothOnAfterApmToggle = false;
    /* Tracks whether user toggled bluetooth in airplane mode */
    private boolean mUserToggledBluetoothDuringApm = false;
    /* Tracks whether user toggled bluetooth in airplane mode within one minute */
    private boolean mUserToggledBluetoothDuringApmWithinMinute = false;
    /* Tracks whether media profile was connected before entering airplane mode */
    private boolean mIsMediaProfileConnectedBeforeApmToggle = false;
    /* Tracks when airplane mode has been enabled */
    private long mApmEnabledTime = 0;

    private final BluetoothManagerService mBluetoothManager;
    private final BluetoothAirplaneModeHandler mHandler;
    private final Context mContext;
@@ -138,7 +153,15 @@ public class BluetoothAirplaneModeListener {
    @VisibleForTesting
    @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
    void handleAirplaneModeChange() {
        if (shouldSkipAirplaneModeChange()) {
        if (mAirplaneHelper == null) {
            return;
        }
        if (mAirplaneHelper.isAirplaneModeOn()) {
            mApmEnabledTime = SystemClock.elapsedRealtime();
            mIsBluetoothOnBeforeApmToggle = mAirplaneHelper.isBluetoothOn();
            mIsBluetoothOnAfterApmToggle = shouldSkipAirplaneModeChange();
            mIsMediaProfileConnectedBeforeApmToggle = mAirplaneHelper.isMediaProfileConnected();
            if (mIsBluetoothOnAfterApmToggle) {
                Log.i(TAG, "Ignore airplane mode change");
                // Airplane mode enabled when Bluetooth is being used for audio/headering aid.
                // Bluetooth is not disabled in such case, only state is changed to
@@ -156,9 +179,11 @@ public class BluetoothAirplaneModeListener {
                                    "bluetooth_and_wifi_stays_on_message",
                                    APM_WIFI_BT_NOTIFICATION);
                        } catch (Exception e) {
                        Log.e(TAG, "APM enhancement BT and Wi-Fi stays on notification not shown");
                            Log.e(TAG,
                                    "APM enhancement BT and Wi-Fi stays on notification not shown");
                        }
                } else if (!isWifiEnabledOnApm() && isFirstTimeNotification(APM_BT_NOTIFICATION)) {
                    } else if (!isWifiEnabledOnApm() && isFirstTimeNotification(
                            APM_BT_NOTIFICATION)) {
                        try {
                            sendApmNotification("bluetooth_stays_on_title",
                                    "bluetooth_stays_on_message",
@@ -170,29 +195,35 @@ public class BluetoothAirplaneModeListener {
                }
                return;
            }
        if (mAirplaneHelper != null) {
            mAirplaneHelper.onAirplaneModeChanged(mBluetoothManager);
        } else {
            BluetoothStatsLog.write(BluetoothStatsLog.AIRPLANE_MODE_SESSION_REPORTED,
                    BluetoothStatsLog.AIRPLANE_MODE_SESSION_REPORTED__PACKAGE_NAME__BLUETOOTH,
                    mIsBluetoothOnBeforeApmToggle,
                    mIsBluetoothOnAfterApmToggle,
                    mAirplaneHelper.isBluetoothOn(),
                    isBluetoothToggledOnApm(),
                    mUserToggledBluetoothDuringApm,
                    mUserToggledBluetoothDuringApmWithinMinute,
                    mIsMediaProfileConnectedBeforeApmToggle);
            mUserToggledBluetoothDuringApm = false;
            mUserToggledBluetoothDuringApmWithinMinute = false;
        }
        mAirplaneHelper.onAirplaneModeChanged(mBluetoothManager);
    }

    @VisibleForTesting
    boolean shouldSkipAirplaneModeChange() {
        if (mAirplaneHelper == null) {
            return false;
        }
        boolean apmEnhancementUsed = isApmEnhancementEnabled() && isBluetoothToggledOnApm();

        // APM feature disabled or user has not used the feature yet by changing BT state in APM
        // BT will only remain on in APM when media profile is connected
        if (!apmEnhancementUsed && mAirplaneHelper.isBluetoothOn()
                && mAirplaneHelper.isAirplaneModeOn()
                && mAirplaneHelper.isMediaProfileConnected()) {
            return true;
        }
        // APM feature enabled and user has used the feature by changing BT state in APM
        // BT will only remain on in APM based on user's last action in APM
        if (apmEnhancementUsed && mAirplaneHelper.isBluetoothOn()
                && mAirplaneHelper.isAirplaneModeOn()
                && mAirplaneHelper.isBluetoothOnAPM()) {
            return true;
        }
@@ -200,7 +231,6 @@ public class BluetoothAirplaneModeListener {
        // BT will only remain on in APM if the default value is set to on
        if (isApmEnhancementEnabled() && !isBluetoothToggledOnApm()
                && mAirplaneHelper.isBluetoothOn()
                && mAirplaneHelper.isAirplaneModeOn()
                && mAirplaneHelper.isBluetoothOnAPM()) {
            return true;
        }
@@ -245,4 +275,15 @@ public class BluetoothAirplaneModeListener {
        mAirplaneHelper.setSettingsSecureInt(notificationState,
                NOTIFICATION_SHOWN);
    }

    /**
     * Helper method to update whether user toggled Bluetooth in airplane mode
     */
    public void updateBluetoothToggledTime() {
        if (!mUserToggledBluetoothDuringApm) {
            mUserToggledBluetoothDuringApmWithinMinute =
                    SystemClock.elapsedRealtime() - mApmEnabledTime < 60000;
        }
        mUserToggledBluetoothDuringApm = true;
    }
}
+23 −17
Original line number Diff line number Diff line
@@ -1359,7 +1359,9 @@ public class BluetoothManagerService extends IBluetoothManager.Stub {
        synchronized (mReceiver) {
            mQuietEnableExternal = false;
            mEnableExternal = true;
            if (isAirplaneModeOn() && isApmEnhancementOn()) {
            if (isAirplaneModeOn()) {
                mBluetoothAirplaneModeListener.updateBluetoothToggledTime();
                if (isApmEnhancementOn()) {
                    setSettingsSecureInt(BLUETOOTH_APM_STATE, BLUETOOTH_ON_APM);
                    setSettingsSecureInt(APM_USER_TOGGLED_BLUETOOTH, USED);
                    if (isFirstTimeNotification(APM_BT_ENABLED_NOTIFICATION)) {
@@ -1376,6 +1378,7 @@ public class BluetoothManagerService extends IBluetoothManager.Stub {
                        }
                    }
                }
            }
            // waive WRITE_SECURE_SETTINGS permission check
            sendEnableMsg(false,
                    BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST, packageName);
@@ -1416,10 +1419,13 @@ public class BluetoothManagerService extends IBluetoothManager.Stub {
        }

        synchronized (mReceiver) {
            if (isAirplaneModeOn() && isApmEnhancementOn()) {
            if (isAirplaneModeOn()) {
                mBluetoothAirplaneModeListener.updateBluetoothToggledTime();
                if (isApmEnhancementOn()) {
                    setSettingsSecureInt(BLUETOOTH_APM_STATE, BLUETOOTH_OFF_APM);
                    setSettingsSecureInt(APM_USER_TOGGLED_BLUETOOTH, USED);
                }
            }

            if (persist) {
                persistBluetoothSetting(BLUETOOTH_OFF);
+0 −3
Original line number Diff line number Diff line
@@ -84,9 +84,6 @@ public class BluetoothAirplaneModeListenerTest {
        Assert.assertFalse(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange());

        when(mHelper.isMediaProfileConnected()).thenReturn(true);
        Assert.assertFalse(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange());

        when(mHelper.isAirplaneModeOn()).thenReturn(true);
        Assert.assertTrue(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange());
    }