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

Commit 2b941e91 authored by William Escande's avatar William Escande Committed by Gerrit Code Review
Browse files

Merge changes from topics "bluetooth_auto_on_basic_implementation",...

Merge changes from topics "bluetooth_auto_on_basic_implementation", "bluetooth_auto_on_hidden_listener", "bluetooth_auto_on_system_api" into main

* changes:
  Toggle Notification
  SystemServer: AutoOn: Hidden api listener
  SystemServer: AutoOn: Airplane override
  SystemServer: AutoOn: Handle time change
  SystemServer: AutoOn: Handle reboot
  SystemServer: AutoOn: Respect user restriction
  SystemServer: AutoOn: Handle user switch
  SystemServer: AutoOn: Satellite override
  SystemServer: AutoOn: Timer can pause and resume
  SystemServer: AutoOn: Add system API
  SystemServer: AutoOn: Set default feature value
  SystemServer: AutoOn: Add notification support
  SystemServer: AutoOn: Add basic feature
parents 8fabbedf 4be5db46
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -110,6 +110,7 @@
             android:permission="android.permission.BLUETOOTH_PRIVILEGED">
            <intent-filter>
                <action android:name="android.bluetooth.notification.action.SEND_TOGGLE_NOTIFICATION"/>
                <action android:name="android.bluetooth.notification.action.AUTO_ON_USER_ACTION"/>
            </intent-filter>
        </service>

+10 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="960"
    android:viewportHeight="960">
    <path
        android:fillColor="@android:color/white"
        android:pathData="M450,472.15L277.08,645.08Q268.77,653.38 256.19,653.58Q243.62,653.77 234.92,645.08Q226.23,636.38 226.23,624Q226.23,611.62 234.92,602.92L437.85,400L234.92,197.08Q226.62,188.77 226.42,176.19Q226.23,163.62 234.92,154.92Q243.62,146.23 256,146.23Q268.38,146.23 277.08,154.92L450,327.85L450,71.23Q450,54.77 461.04,44.62Q472.08,34.46 486.15,34.46Q493,34.46 499.42,37.08Q505.85,39.69 511.46,45.31L668.84,202.69Q674.46,208.31 676.77,214.54Q679.08,220.77 679.08,228Q679.08,235.23 676.77,241.46Q674.46,247.69 668.84,253.31L522.15,400L668.84,546.69Q674.46,552.31 676.77,558.54Q679.08,564.77 679.08,572Q679.08,579.23 676.77,585.46Q674.46,591.69 668.84,597.31L511.46,754.69Q505.85,760.31 499.42,762.92Q493,765.54 486.15,765.54Q472.08,765.54 461.04,755.38Q450,745.23 450,728.77L450,472.15ZM510,670.62L609.85,572L510,472.15L510,670.62ZM510,327.85L609.85,228L510,129.38L510,327.85ZM320,955.38Q305.31,955.38 294.96,945.04Q284.62,934.69 284.62,920Q284.62,905.31 294.96,894.96Q305.31,884.62 320,884.62Q334.69,884.62 345.04,894.96Q355.38,905.31 355.38,920Q355.38,934.69 345.04,945.04Q334.69,955.38 320,955.38ZM480,955.38Q465.31,955.38 454.96,945.04Q444.62,934.69 444.62,920Q444.62,905.31 454.96,894.96Q465.31,884.62 480,884.62Q494.69,884.62 505.04,894.96Q515.38,905.31 515.38,920Q515.38,934.69 505.04,945.04Q494.69,955.38 480,955.38ZM640,955.38Q625.31,955.38 614.96,945.04Q604.62,934.69 604.62,920Q604.62,905.31 614.96,894.96Q625.31,884.62 640,884.62Q654.69,884.62 665.04,894.96Q675.38,905.31 675.38,920Q675.38,934.69 665.04,945.04Q654.69,955.38 640,955.38Z" />
</vector>
+4 −0
Original line number Diff line number Diff line
@@ -256,4 +256,8 @@
    <string name="bluetooth_stays_on_message">Your device remembers to keep Bluetooth on in airplane mode. Turn off Bluetooth if you don\'t want it to stay on.</string>
    <string name="bluetooth_and_wifi_stays_on_title">Wi-Fi and Bluetooth stay on</string>
    <string name="bluetooth_and_wifi_stays_on_message">Your device remembers to keep Wi-Fi and Bluetooth on in airplane mode. Turn off Wi-Fi and Bluetooth if you don\'t want them to stay on.</string>
    <string name="bluetooth_enabled_auto_on_title">Bluetooth has been automatically enabled</string>
    <string name="bluetooth_enabled_auto_on_message">Automatic restart can be toggled in Bluetooth Settings.</string>
    <string name="bluetooth_disable_auto_on">Turn off</string>
    <string name="bluetooth_notification_group">Bluetooth automatic state change</string>
</resources>
+73 −21
Original line number Diff line number Diff line
@@ -23,7 +23,9 @@ import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.bluetooth.BluetoothManager;
import android.content.Intent;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.IBinder;
import android.provider.Settings;
@@ -45,10 +47,22 @@ public class NotificationHelperService extends Service {
    private static final String APM_BT_NOTIFICATION = "apm_bt_notification";
    // Keeps track of whether user enabling bt notification was shown
    private static final String APM_BT_ENABLED_NOTIFICATION = "apm_bt_enabled_notification";
    // Keeps track of whether auto on enabling bt notification was shown
    private static final String AUTO_ON_BT_ENABLED_NOTIFICATION = "auto_on_bt_enabled_notification";

    private static final String NOTIFICATION_TAG = "com.android.bluetooth";
    private static final String NOTIFICATION_CHANNEL = "notification_toggle_channel";
    private static final String NOTIFICATION_GROUP = "notification_toggle_group";
    private static final int NOTIFICATION_GROUP = R.string.bluetooth_notification_group;

    private static final String NOTIFICATION_ACTION =
            "android.bluetooth.notification.action.SEND_TOGGLE_NOTIFICATION";
    private static final String NOTIFICATION_EXTRA =
            "android.bluetooth.notification.extra.NOTIFICATION_REASON";

    private static final String AUTO_ON_USER_ACTION =
            "android.bluetooth.notification.action.AUTO_ON_USER_ACTION";
    private static final String AUTO_ON_USER_EXTRA =
            "android.bluetooth.notification.extra.AUTO_ON_DISABLE";

    private static final Map<String, Pair<Integer /* titleId */, Integer /* messageId */>>
            NOTIFICATION_MAP =
@@ -64,7 +78,11 @@ public class NotificationHelperService extends Service {
                            APM_BT_ENABLED_NOTIFICATION,
                            Pair.create(
                                    R.string.bluetooth_enabled_apm_title,
                                    R.string.bluetooth_enabled_apm_message));
                                    R.string.bluetooth_enabled_apm_message),
                            AUTO_ON_BT_ENABLED_NOTIFICATION,
                            Pair.create(
                                    R.string.bluetooth_enabled_auto_on_title,
                                    R.string.bluetooth_enabled_auto_on_message));

    @Override
    public IBinder onBind(Intent intent) {
@@ -73,8 +91,14 @@ public class NotificationHelperService extends Service {

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        sendToggleNotification(
                intent.getStringExtra("android.bluetooth.notification.extra.NOTIFICATION_REASON"));
        switch (intent.getAction()) {
            case NOTIFICATION_ACTION -> {
                sendToggleNotification(intent.getStringExtra(NOTIFICATION_EXTRA));
            }
            case AUTO_ON_USER_ACTION -> {
                autoOnUserAction(intent.getBooleanExtra(AUTO_ON_USER_EXTRA, false));
            }
        }
        return Service.START_NOT_STICKY;
    }

@@ -96,46 +120,74 @@ public class NotificationHelperService extends Service {

        NotificationManager notificationManager =
                requireNonNull(getSystemService(NotificationManager.class));
        String tag = NOTIFICATION_TAG + "/" + notificationReason;
        for (StatusBarNotification notification : notificationManager.getActiveNotifications()) {
            if (NOTIFICATION_TAG.equals(notification.getTag())) {
                notificationManager.cancel(NOTIFICATION_TAG, notification.getId());
            if (tag.equals(notification.getTag())) {
                notificationManager.cancel(tag, notification.getId());
            }
        }

        notificationManager.createNotificationChannel(
                new NotificationChannel(
                        NOTIFICATION_CHANNEL,
                        NOTIFICATION_GROUP,
                        getString(NOTIFICATION_GROUP),
                        NotificationManager.IMPORTANCE_HIGH));

        String title = getString(notificationContent.first);
        String message = getString(notificationContent.second);
        String helpLinkUrl = getString(R.string.config_apmLearnMoreLink);

        notificationManager.notify(
                NOTIFICATION_TAG,
                SystemMessage.ID.NOTE_BT_APM_NOTIFICATION_VALUE,
        Notification.Builder builder =
                new Notification.Builder(this, NOTIFICATION_CHANNEL)
                        .setAutoCancel(true)
                        .setLocalOnly(true)
                        .setContentTitle(title)
                        .setContentText(message)
                        .setContentIntent(
                        .setVisibility(Notification.VISIBILITY_PUBLIC)
                        .setStyle(new Notification.BigTextStyle().bigText(message))
                        .setSmallIcon(android.R.drawable.stat_sys_data_bluetooth);

        if (!notificationReason.equals(AUTO_ON_BT_ENABLED_NOTIFICATION)) {
            // Do not display airplane link when the notification is due to auto_on feature
            String helpLinkUrl = getString(R.string.config_apmLearnMoreLink);
            builder.setContentIntent(
                    PendingIntent.getActivity(
                            this,
                            PendingIntent.FLAG_UPDATE_CURRENT,
                            new Intent(Intent.ACTION_VIEW)
                                    .setData(Uri.parse(helpLinkUrl))
                                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
                                        PendingIntent.FLAG_IMMUTABLE))
                        .setVisibility(Notification.VISIBILITY_PUBLIC)
                        .setStyle(new Notification.BigTextStyle().bigText(message))
                        .setSmallIcon(android.R.drawable.stat_sys_data_bluetooth)
                            PendingIntent.FLAG_IMMUTABLE));
        } else {
            Intent baseIntent =
                    new Intent()
                            .setAction(AUTO_ON_USER_ACTION)
                            .setClass(this, NotificationHelperService.class);
            PendingIntent disablePendingIntent =
                    PendingIntent.getService(
                            this,
                            0,
                            new Intent(baseIntent).putExtra(AUTO_ON_USER_EXTRA, true),
                            PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_ONE_SHOT);
            builder.addAction(
                    new Notification.Action.Builder(
                                    Icon.createWithResource(this, R.drawable.ic_bluetooth_settings),
                                    getString(R.string.bluetooth_disable_auto_on),
                                    disablePendingIntent)
                            .build());
        }

        notificationManager.notify(
                tag, SystemMessage.ID.NOTE_BT_APM_NOTIFICATION_VALUE, builder.build());
    }

    /** Return whether the notification has been shown */
    private boolean isFirstTimeNotification(String name) {
        return Settings.Secure.getInt(getContentResolver(), name, 0) == 0;
    }

    private void autoOnUserAction(boolean disableAutoOn) {
        if (disableAutoOn) {
            getSystemService(BluetoothManager.class).getAdapter().setAutoOnEnabled(false);
        }
    }
}
+3 −0
Original line number Diff line number Diff line
@@ -75,6 +75,8 @@ package android.bluetooth {
    method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public android.os.Bundle getPreferredAudioProfiles(@NonNull android.bluetooth.BluetoothDevice);
    method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public java.util.List<java.lang.Integer> getSupportedProfiles();
    method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.os.ParcelUuid> getUuidsList();
    method @FlaggedApi("com.android.bluetooth.flags.auto_on_feature") @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean isAutoOnEnabled();
    method @FlaggedApi("com.android.bluetooth.flags.auto_on_feature") @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean isAutoOnSupported();
    method public boolean isBleScanAlwaysAvailable();
    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int isDistanceMeasurementSupported();
    method public boolean isLeEnabled();
@@ -88,6 +90,7 @@ package android.bluetooth {
    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public void requestControllerActivityEnergyInfo(@NonNull java.util.concurrent.Executor, @NonNull android.bluetooth.BluetoothAdapter.OnBluetoothActivityEnergyInfoCallback);
    method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public android.bluetooth.BluetoothSocket retrieveConnectedRfcommSocket(@NonNull java.util.UUID);
    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean setActiveDevice(@NonNull android.bluetooth.BluetoothDevice, int);
    method @FlaggedApi("com.android.bluetooth.flags.auto_on_feature") @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void setAutoOnEnabled(boolean);
    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int setBluetoothHciSnoopLoggingMode(int);
    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_SCAN, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int setDiscoverableTimeout(@NonNull java.time.Duration);
    method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int setPreferredAudioProfiles(@NonNull android.bluetooth.BluetoothDevice, @NonNull android.os.Bundle);
Loading