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

Commit f870974b authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge changes Ib793b8af,If7a8060b into main

* changes:
  Move airplaneMode code into its listener
  Move notification in its own function
parents 4f820dbf c5b0cb95
Loading
Loading
Loading
Loading
+90 −35
Original line number Diff line number Diff line
@@ -17,13 +17,16 @@
package com.android.server.bluetooth;

import android.annotation.RequiresPermission;
import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.os.Binder;
import android.os.Handler;
import android.os.Looper;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log;

@@ -44,7 +47,8 @@ import com.android.internal.annotations.VisibleForTesting;
 * </ul>
 */
class BluetoothAirplaneModeListener extends Handler {
    private static final String TAG = "BluetoothAirplaneModeListener";
    private static final String TAG = BluetoothAirplaneModeListener.class.getSimpleName();

    @VisibleForTesting static final String TOAST_COUNT = "bluetooth_airplane_toast_count";

    // keeps track of whether wifi should remain on in airplane mode
@@ -68,6 +72,9 @@ class BluetoothAirplaneModeListener extends Handler {
    public static final int UNUSED = 0;
    public static final int USED = 1;

    private static final int BLUETOOTH_OFF_APM = 0;
    private static final int BLUETOOTH_ON_APM = 1;

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

    /* Tracks the bluetooth state before entering airplane mode*/
@@ -187,10 +194,32 @@ class BluetoothAirplaneModeListener extends Handler {
                mAirplaneHelper.setSettingsInt(
                        Settings.Global.BLUETOOTH_ON,
                        BluetoothManagerService.BLUETOOTH_ON_AIRPLANE);
                displayUserNotificationIfNeeded();
                return;
            }
        } 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;
        }
        mBluetoothManager.onAirplaneModeChanged(isAirplaneModeOn);
    }

    private void displayUserNotificationIfNeeded() {
        if (!isApmEnhancementEnabled() || !isBluetoothToggledOnApm()) {
            if (shouldPopToast()) {
                mAirplaneHelper.showToastMessage();
            }
            return;
        } else {
            if (isWifiEnabledOnApm() && isFirstTimeNotification(APM_WIFI_BT_NOTIFICATION)) {
                try {
@@ -199,12 +228,9 @@ class BluetoothAirplaneModeListener extends Handler {
                            "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",
@@ -215,23 +241,6 @@ class BluetoothAirplaneModeListener extends Handler {
                }
            }
        }
                return;
            }
        } 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;
        }
        mBluetoothManager.onAirplaneModeChanged(isAirplaneModeOn);
    }

    @VisibleForTesting
@@ -276,11 +285,6 @@ class BluetoothAirplaneModeListener extends Handler {
                && mAirplaneHelper.getSettingsSecureInt(WIFI_APM_STATE, 0) == 1;
    }

    private boolean isFirstTimeNotification(String name) {
        return mAirplaneHelper.getSettingsSecureInt(name, NOTIFICATION_NOT_SHOWN)
                == NOTIFICATION_NOT_SHOWN;
    }

    /** Helper method to send APM notification */
    public void sendApmNotification(String titleId, String messageId, String notificationState)
            throws PackageManager.NameNotFoundException {
@@ -301,11 +305,62 @@ class BluetoothAirplaneModeListener extends Handler {
    }

    /** Helper method to update whether user toggled Bluetooth in airplane mode */
    public void updateBluetoothToggledTime() {
    public void notifyUserToggledBluetooth(boolean isOn) {
        if (!mIsAirplaneModeOn) {
            // User not in Airplane mode, discard event
            return;
        }
        if (!mUserToggledBluetoothDuringApm) {
            mUserToggledBluetoothDuringApmWithinMinute =
                    SystemClock.elapsedRealtime() - mApmEnabledTime < 60000;
        }
        mUserToggledBluetoothDuringApm = true;
        if (isApmEnhancementEnabled()) {
            setSettingsSecureInt(BLUETOOTH_APM_STATE, isOn ? BLUETOOTH_ON_APM : BLUETOOTH_OFF_APM);
            setSettingsSecureInt(APM_USER_TOGGLED_BLUETOOTH, USED);
            if (isOn && isFirstTimeNotification(APM_BT_ENABLED_NOTIFICATION)) {
                // waive WRITE_SECURE_SETTINGS permission check
                final long callingIdentity = Binder.clearCallingIdentity();
                try {
                    sendApmNotification(
                            "bluetooth_enabled_apm_title",
                            "bluetooth_enabled_apm_message",
                            APM_BT_ENABLED_NOTIFICATION);
                } catch (Exception e) {
                    Log.e(TAG, "APM enhancement BT enabled notification not shown");
                } finally {
                    Binder.restoreCallingIdentity(callingIdentity);
                }
            }
        }
    }

    /** Return whether APM notification has been shown */
    private boolean isFirstTimeNotification(String name) {
        // waive WRITE_SECURE_SETTINGS permission check
        final long callingIdentity = Binder.clearCallingIdentity();
        try {
            Context userContext =
                    mContext.createContextAsUser(
                            UserHandle.of(ActivityManager.getCurrentUser()), 0);
            return mAirplaneHelper.getSettingsSecureInt(name, NOTIFICATION_NOT_SHOWN)
                    == NOTIFICATION_NOT_SHOWN;
        } finally {
            Binder.restoreCallingIdentity(callingIdentity);
        }
    }

    /** Set the Settings Secure Int value for foreground user */
    private void setSettingsSecureInt(String name, int value) {
        // waive WRITE_SECURE_SETTINGS permission check
        final long callingIdentity = Binder.clearCallingIdentity();
        try {
            Context userContext =
                    mContext.createContextAsUser(
                            UserHandle.of(ActivityManager.getCurrentUser()), 0);
            Settings.Secure.putInt(userContext.getContentResolver(), name, value);
        } finally {
            Binder.restoreCallingIdentity(callingIdentity);
        }
    }
}
+2 −78
Original line number Diff line number Diff line
@@ -25,12 +25,7 @@ import static android.bluetooth.BluetoothAdapter.STATE_TURNING_OFF;
import static android.bluetooth.BluetoothAdapter.STATE_TURNING_ON;
import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED;

import static com.android.server.bluetooth.BluetoothAirplaneModeListener.APM_BT_ENABLED_NOTIFICATION;
import static com.android.server.bluetooth.BluetoothAirplaneModeListener.APM_ENHANCEMENT;
import static com.android.server.bluetooth.BluetoothAirplaneModeListener.APM_USER_TOGGLED_BLUETOOTH;
import static com.android.server.bluetooth.BluetoothAirplaneModeListener.BLUETOOTH_APM_STATE;
import static com.android.server.bluetooth.BluetoothAirplaneModeListener.NOTIFICATION_NOT_SHOWN;
import static com.android.server.bluetooth.BluetoothAirplaneModeListener.USED;

import static java.util.Objects.requireNonNull;

@@ -176,9 +171,6 @@ class BluetoothManagerService {
    // and Airplane mode will have higher priority.
    @VisibleForTesting static final int BLUETOOTH_ON_AIRPLANE = 2;

    private static final int BLUETOOTH_OFF_APM = 0;
    private static final int BLUETOOTH_ON_APM = 1;

    private static final int FLAGS_SYSTEM_APP =
            ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;

@@ -759,11 +751,6 @@ class BluetoothManagerService {
        return mBluetoothSatelliteModeListener.isSatelliteModeOn();
    }

    /** Returns true if airplane mode enhancement feature is enabled */
    private boolean isApmEnhancementOn() {
        return Settings.Global.getInt(mContext.getContentResolver(), APM_ENHANCEMENT, 0) == 1;
    }

    /** Returns true if the Bluetooth saved state is "on" */
    private boolean isBluetoothPersistedStateOn() {
        final int state =
@@ -811,43 +798,6 @@ class BluetoothManagerService {
        }
    }

    /** Set the Settings Secure Int value for foreground user */
    private void setSettingsSecureInt(String name, int value) {
        if (DBG) {
            Log.d(TAG, "Persisting Settings Secure Int: " + name + "=" + value);
        }

        // waive WRITE_SECURE_SETTINGS permission check
        final long callingIdentity = Binder.clearCallingIdentity();
        try {
            Context userContext =
                    mContext.createContextAsUser(
                            UserHandle.of(ActivityManager.getCurrentUser()), 0);
            Settings.Secure.putInt(userContext.getContentResolver(), name, value);
        } finally {
            Binder.restoreCallingIdentity(callingIdentity);
        }
    }

    /** Return whether APM notification has been shown */
    private boolean isFirstTimeNotification(String name) {
        boolean firstTime = false;
        // waive WRITE_SECURE_SETTINGS permission check
        final long callingIdentity = Binder.clearCallingIdentity();
        try {
            Context userContext =
                    mContext.createContextAsUser(
                            UserHandle.of(ActivityManager.getCurrentUser()), 0);
            firstTime =
                    Settings.Secure.getInt(
                                    userContext.getContentResolver(), name, NOTIFICATION_NOT_SHOWN)
                            == NOTIFICATION_NOT_SHOWN;
        } finally {
            Binder.restoreCallingIdentity(callingIdentity);
        }
        return firstTime;
    }

    /**
     * Returns true if the Bluetooth Adapter's name and address is locally cached
     *
@@ -1307,27 +1257,7 @@ class BluetoothManagerService {
        synchronized (mReceiver) {
            mQuietEnableExternal = false;
            mEnableExternal = true;
            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)) {
                        final long callingIdentity = Binder.clearCallingIdentity();
                        try {
                            mBluetoothAirplaneModeListener.sendApmNotification(
                                    "bluetooth_enabled_apm_title",
                                    "bluetooth_enabled_apm_message",
                                    APM_BT_ENABLED_NOTIFICATION);
                        } catch (Exception e) {
                            Log.e(TAG, "APM enhancement BT enabled notification not shown");
                        } finally {
                            Binder.restoreCallingIdentity(callingIdentity);
                        }
                    }
                }
            }
            // waive WRITE_SECURE_SETTINGS permission check
            mBluetoothAirplaneModeListener.notifyUserToggledBluetooth(true);
            sendEnableMsg(
                    false,
                    BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST,
@@ -1357,13 +1287,7 @@ class BluetoothManagerService {
        }

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

            if (persist) {
                persistBluetoothSetting(BLUETOOTH_OFF);