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

Commit 93278a6b authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 13235988 from 4bc471f6 to 25Q2-release

Change-Id: Ifc3e397531aca70c7a40287ada0a08b0eb54bb60
parents 06baa0c1 4bc471f6
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -14360,6 +14360,16 @@ Data usage charges may apply.</string>
    <string name="supervision_web_content_filters_browser_block_explicit_sites_summary">No filter is perfect, but this should help hide sexually explicit sites</string>
    <!-- Title for web content filters browser category allow all sites option [CHAR LIMIT=60] -->
    <string name="supervision_web_content_filters_browser_allow_all_sites_title">Allow all sites</string>
    <!-- Title for web content filters search category [CHAR LIMIT=60] -->
    <string name="supervision_web_content_filters_search_title">Google Search</string>
    <!-- Title for web content filters search category filter on option [CHAR LIMIT=60] -->
    <string name="supervision_web_content_filters_search_filter_on_title">SafeSearch filtering ON</string>
    <!-- Summary for web content filters search category filter on option [CHAR LIMIT=None] -->
    <string name="supervision_web_content_filters_search_filter_on_summary">Helps filter out explicit images, text, and links from search results on this device</string>
    <!-- Title for web content filters search category filter off option [CHAR LIMIT=60] -->
    <string name="supervision_web_content_filters_search_filter_off_title">SafeSearch filtering OFF</string>
    <!-- Summary for web content filters search category filter off option [CHAR LIMIT=None] -->
    <string name="supervision_web_content_filters_search_filter_off_summary">Account settings may still filter or blur explicit results</string>
    <!-- Generic content description that is attached to the preview illustration at the top of an Accessibility feature toggle page. [CHAR LIMIT=NONE] -->
    <!-- Title for supervision PIN verification screen [CHAR LIMIT=60] -->
    <string name="supervision_full_screen_pin_verification_title">Enter supervision PIN</string>
+2 −95
Original line number Diff line number Diff line
@@ -419,32 +419,7 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll
                mContext,
                SettingsEnums.ACTION_BLUETOOTH_PROFILE_LE_AUDIO_OFF,
                isCurrentDeviceInOrByPassAllowList());

        LocalBluetoothProfile asha = mProfileManager.getHearingAidProfile();
        LocalBluetoothProfile broadcastAssistant =
                mProfileManager.getLeAudioBroadcastAssistantProfile();

        for (CachedBluetoothDevice leAudioDevice : mProfileDeviceMap.get(profile.toString())) {
            Log.d(TAG,
                    "device:" + leAudioDevice.getDevice().getAnonymizedAddress()
                            + " disable LE profile");
            profile.setEnabled(leAudioDevice.getDevice(), false);
            if (asha != null) {
                asha.setEnabled(leAudioDevice.getDevice(), true);
            }
            if (broadcastAssistant != null) {
                Log.d(TAG,
                        "device:" + leAudioDevice.getDevice().getAnonymizedAddress()
                                + " disable LE broadcast assistant profile");
                broadcastAssistant.setEnabled(leAudioDevice.getDevice(), false);
            }
        }

        if (!SystemProperties.getBoolean(ENABLE_DUAL_MODE_AUDIO, false)) {
            Log.i(TAG, "Enabling classic audio profiles because dual mode is disabled");
            enableProfileAfterUserDisablesLeAudio(mProfileManager.getA2dpProfile());
            enableProfileAfterUserDisablesLeAudio(mProfileManager.getHeadsetProfile());
        }
        Utils.setLeAudioEnabled(mManager, List.copyOf(mCachedDeviceGroup), false);
    }

    /**
@@ -462,75 +437,7 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll
                mContext,
                SettingsEnums.ACTION_BLUETOOTH_PROFILE_LE_AUDIO_ON,
                isCurrentDeviceInOrByPassAllowList());

        if (!SystemProperties.getBoolean(ENABLE_DUAL_MODE_AUDIO, false)) {
            Log.i(TAG, "Disabling classic audio profiles because dual mode is disabled");
            disableProfileBeforeUserEnablesLeAudio(mProfileManager.getA2dpProfile());
            disableProfileBeforeUserEnablesLeAudio(mProfileManager.getHeadsetProfile());
        }
        LocalBluetoothProfile asha = mProfileManager.getHearingAidProfile();
        LocalBluetoothProfile broadcastAssistant =
                mProfileManager.getLeAudioBroadcastAssistantProfile();

        for (CachedBluetoothDevice leAudioDevice : mProfileDeviceMap.get(profile.toString())) {
            Log.d(TAG,
                    "device:" + leAudioDevice.getDevice().getAnonymizedAddress()
                            + " enable LE profile");
            profile.setEnabled(leAudioDevice.getDevice(), true);
            if (asha != null) {
                asha.setEnabled(leAudioDevice.getDevice(), false);
            }
            if (broadcastAssistant != null) {
                Log.d(TAG,
                        "device:" + leAudioDevice.getDevice().getAnonymizedAddress()
                                + " enable LE broadcast assistant profile");
                broadcastAssistant.setEnabled(leAudioDevice.getDevice(), true);
            }
        }
    }

    private void disableProfileBeforeUserEnablesLeAudio(LocalBluetoothProfile profile) {
        if (profile != null && mProfileDeviceMap.get(profile.toString()) != null) {
            Log.d(TAG, "Disable " + profile.toString() + " before user enables LE");
            for (CachedBluetoothDevice profileDevice : mProfileDeviceMap.get(profile.toString())) {
                if (profile.isEnabled(profileDevice.getDevice())) {
                    Log.d(TAG, "The " + profileDevice.getDevice().getAnonymizedAddress() + ":"
                            + profile.toString() + " set disable");
                    profile.setEnabled(profileDevice.getDevice(), false);
                } else {
                    Log.d(TAG, "The " + profileDevice.getDevice().getAnonymizedAddress() + ":"
                            + profile.toString() + " profile is disabled. Do nothing.");
                }
            }
        } else {
            if (profile == null) {
                Log.w(TAG, "profile is null");
            } else {
                Log.w(TAG, profile.toString() + " is not in " + mProfileDeviceMap);
            }
        }
    }

    private void enableProfileAfterUserDisablesLeAudio(LocalBluetoothProfile profile) {
        if (profile != null && mProfileDeviceMap.get(profile.toString()) != null) {
            Log.d(TAG, "enable " + profile.toString() + "after user disables LE");
            for (CachedBluetoothDevice profileDevice : mProfileDeviceMap.get(profile.toString())) {
                if (!profile.isEnabled(profileDevice.getDevice())) {
                    Log.d(TAG, "The " + profileDevice.getDevice().getAnonymizedAddress() + ":"
                            + profile.toString() + " set enable");
                    profile.setEnabled(profileDevice.getDevice(), true);
                } else {
                    Log.d(TAG, "The " + profileDevice.getDevice().getAnonymizedAddress() + ":"
                            + profile.toString() + " profile is enabled. Do nothing.");
                }
            }
        } else {
            if (profile == null) {
                Log.w(TAG, "profile is null");
            } else {
                Log.w(TAG, profile.toString() + " is not in " + mProfileDeviceMap);
            }
        }
        Utils.setLeAudioEnabled(mManager, List.copyOf(mCachedDeviceGroup), true);
    }

    /**
+9 −0
Original line number Diff line number Diff line
@@ -55,9 +55,18 @@ public final class BluetoothKeyMissingReceiver extends BroadcastReceiver {
        }

        BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
        if (device == null) {
            return;
        }
        PowerManager powerManager = context.getSystemService(PowerManager.class);
        if (TextUtils.equals(action, BluetoothDevice.ACTION_KEY_MISSING)) {
            Log.d(TAG, "Receive ACTION_KEY_MISSING");
            if (device.getBondState() == BluetoothDevice.BOND_NONE) {
                Log.d(
                        TAG,
                        "Device " + device.getAnonymizedAddress() + " is already unbonded, skip.");
                return;
            }
            Integer keyMissingCount = BluetoothUtils.getKeyMissingCount(device);
            if (keyMissingCount != null && keyMissingCount != 1) {
                Log.d(TAG, "Key missing count is " + keyMissingCount  + ", skip.");
+122 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.content.pm.ActivityInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log;
@@ -45,15 +46,20 @@ import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.BluetoothUtils.ErrorListener;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
import com.android.settingslib.bluetooth.HearingAidProfile;
import com.android.settingslib.bluetooth.LeAudioProfile;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothManager.BluetoothManagerCallback;
import com.android.settingslib.bluetooth.LocalBluetoothProfile;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import com.android.settingslib.utils.ThreadUtils;

import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
@@ -70,6 +76,7 @@ import java.util.stream.Collectors;
public final class Utils {

    private static final String TAG = "BluetoothUtils";
    private static final String ENABLE_DUAL_MODE_AUDIO = "persist.bluetooth.enable_dual_mode_audio";

    static final boolean V = BluetoothUtils.V; // verbose logging
    static final boolean D = BluetoothUtils.D;  // regular logging
@@ -360,4 +367,119 @@ public final class Utils {
        dialog.show();
        return dialog;
    }

    /** Enables/disables LE Audio profile for the device. */
    public static void setLeAudioEnabled(
            @NonNull LocalBluetoothManager manager,
            @NonNull CachedBluetoothDevice cachedDevice,
            boolean enable) {
        List<CachedBluetoothDevice> devices =
                List.copyOf(findAllCachedBluetoothDevicesByGroupId(manager, cachedDevice));
        setLeAudioEnabled(manager, devices, enable);
    }

    /** Enables/disables LE Audio profile for the devices in the same csip group. */
    public static void setLeAudioEnabled(
            @NonNull LocalBluetoothManager manager,
            @NonNull List<CachedBluetoothDevice> devicesWithSameGroupId,
            boolean enable) {
        LocalBluetoothProfileManager profileManager = manager.getProfileManager();
        LeAudioProfile leAudioProfile = profileManager.getLeAudioProfile();
        List<CachedBluetoothDevice> leAudioDevices =
                getDevicesWithProfile(devicesWithSameGroupId, leAudioProfile);
        if (leAudioDevices.isEmpty()) {
            Log.i(TAG, "Fail to setLeAudioEnabled, no LE Audio profile found.");
        }
        boolean dualModeEnabled = SystemProperties.getBoolean(ENABLE_DUAL_MODE_AUDIO, false);

        if (enable && !dualModeEnabled) {
            Log.i(TAG, "Disabling classic audio profiles because dual mode is disabled");
            setProfileEnabledWhenChangingLeAudio(
                    devicesWithSameGroupId, profileManager.getA2dpProfile(), false);
            setProfileEnabledWhenChangingLeAudio(
                    devicesWithSameGroupId, profileManager.getHeadsetProfile(), false);
        }

        HearingAidProfile asha = profileManager.getHearingAidProfile();
        LocalBluetoothLeBroadcastAssistant broadcastAssistant =
                profileManager.getLeAudioBroadcastAssistantProfile();

        for (CachedBluetoothDevice leAudioDevice : leAudioDevices) {
            Log.d(
                    TAG,
                    "device:"
                            + leAudioDevice.getDevice().getAnonymizedAddress()
                            + " set LE profile enabled: "
                            + enable);
            leAudioProfile.setEnabled(leAudioDevice.getDevice(), enable);
            if (asha != null) {
                asha.setEnabled(leAudioDevice.getDevice(), !enable);
            }
            if (broadcastAssistant != null) {
                Log.d(
                        TAG,
                        "device:"
                                + leAudioDevice.getDevice().getAnonymizedAddress()
                                + " enable LE broadcast assistant profile: "
                                + enable);
                broadcastAssistant.setEnabled(leAudioDevice.getDevice(), enable);
            }
        }

        if (!enable && !dualModeEnabled) {
            Log.i(TAG, "Enabling classic audio profiles because dual mode is disabled");
            setProfileEnabledWhenChangingLeAudio(
                    devicesWithSameGroupId, profileManager.getA2dpProfile(), true);
            setProfileEnabledWhenChangingLeAudio(
                    devicesWithSameGroupId, profileManager.getHeadsetProfile(), true);
        }
    }

    private static List<CachedBluetoothDevice> getDevicesWithProfile(
            List<CachedBluetoothDevice> devices, LocalBluetoothProfile profile) {
        List<CachedBluetoothDevice> devicesWithProfile = new ArrayList<>();
        for (CachedBluetoothDevice device : devices) {
            for (LocalBluetoothProfile currentProfile : device.getProfiles()) {
                if (currentProfile.toString().equals(profile.toString())) {
                    devicesWithProfile.add(device);
                }
            }
        }
        return devicesWithProfile;
    }

    private static void setProfileEnabledWhenChangingLeAudio(
            List<CachedBluetoothDevice> devices,
            @Nullable LocalBluetoothProfile profile,
            boolean enable) {
        if (profile == null) {
            Log.i(TAG, "profile is null");
            return;
        }
        List<CachedBluetoothDevice> deviceWithProfile = getDevicesWithProfile(devices, profile);
        Log.d(TAG, "Set " + profile + " enabled:" + enable + " when switching LE Audio");
        for (CachedBluetoothDevice profileDevice : deviceWithProfile) {
            if (profile.isEnabled(profileDevice.getDevice()) != enable) {
                Log.d(
                        TAG,
                        "The "
                                + profileDevice.getDevice().getAnonymizedAddress()
                                + ":"
                                + profile
                                + " set to "
                                + enable);
                profile.setEnabled(profileDevice.getDevice(), enable);
            } else {
                Log.d(
                        TAG,
                        "The "
                                + profileDevice.getDevice().getAnonymizedAddress()
                                + ":"
                                + profile
                                + " profile is already "
                                + enable
                                + ". Do nothing.");
            }
        }
    }
}
+36 −21
Original line number Diff line number Diff line
@@ -192,7 +192,7 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
                        Log.d(TAG, "Skip handleOnBroadcastReady, not in starting process");
                        return;
                    }
                    handleOnBroadcastReady();
                    handleOnBroadcastReady(metadata);
                }

                @Override
@@ -273,7 +273,7 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
                            + mSinksInAdding);
                    if (mSinksToWaitFor.contains(sink)) {
                        mSinksToWaitFor.remove(sink);
                        if (mSinksToWaitFor.isEmpty()) {
                        if (mSinksToWaitFor.isEmpty() && mBroadcast != null) {
                            // To avoid users advance to share then pair flow before the
                            // primary/active sinks successfully join the audio sharing,
                            // popup dialog till adding source complete for mSinksToWaitFor.
@@ -284,7 +284,8 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
                                            /* userTriggered= */ false,
                                            /* deviceCountInSharing= */ 1,
                                            /* candidateDeviceCount= */ 0);
                            showAudioSharingDialog(eventData);
                            showJoinAudioSharingDialog(eventData,
                                    mBroadcast.getLatestBluetoothLeBroadcastMetadata());
                        }
                    }
                }
@@ -501,9 +502,10 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
                mBtManager == null ? null : mBtManager.getCachedDeviceManager();
        CachedBluetoothDevice cachedDevice =
                deviceManager == null ? null : deviceManager.findDevice(device);
        if (cachedDevice != null) {
        if (cachedDevice != null && mBroadcast != null) {
            Log.d(TAG, "handleAutoAddSourceAfterPair, device = " + device.getAnonymizedAddress());
            addSourceToTargetSinks(ImmutableList.of(device), cachedDevice.getName());
            addSourceToTargetSinks(ImmutableList.of(device), cachedDevice.getName(),
                    mBroadcast.getLatestBluetoothLeBroadcastMetadata());
        }
    }

@@ -642,7 +644,7 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
        return mAssistant != null && mAssistant.getAllConnectedDevices().isEmpty();
    }

    private void handleOnBroadcastReady() {
    private void handleOnBroadcastReady(@NonNull BluetoothLeBroadcastMetadata metadata) {
        List<BluetoothDevice> targetActiveSinks = mTargetActiveItem == null ? ImmutableList.of()
                : mGroupedConnectedDevices.getOrDefault(
                        mTargetActiveItem.getGroupId(), ImmutableList.of());
@@ -656,7 +658,7 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
        // Auto add primary/active sinks w/o user interactions.
        if (!targetActiveSinks.isEmpty() && mTargetActiveItem != null) {
            Log.d(TAG, "handleOnBroadcastReady: automatically add source to active sinks.");
            addSourceToTargetSinks(targetActiveSinks, mTargetActiveItem.getName());
            addSourceToTargetSinks(targetActiveSinks, mTargetActiveItem.getName(), metadata);
            // To avoid users advance to share then pair flow before the primary/active sinks
            // successfully join the audio sharing, save the primary/active sinks in mSinksToWaitFor
            // and popup dialog till adding source complete for these sinks.
@@ -677,7 +679,7 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
                AudioSharingDeviceItem target = mDeviceItemsForSharing.get(0);
                List<BluetoothDevice> targetSinks = mGroupedConnectedDevices.getOrDefault(
                        target.getGroupId(), ImmutableList.of());
                addSourceToTargetSinks(targetSinks, target.getName());
                addSourceToTargetSinks(targetSinks, target.getName(), metadata);
                cleanUpStatesForStartSharing();
                // TODO: Add metric for auto add by intent
                return;
@@ -698,20 +700,21 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
        // successfully join the audio sharing, popup dialog till adding source complete for
        // mSinksToWaitFor.
        if (mSinksToWaitFor.isEmpty() && !mStoppingSharing.get()) {
            showAudioSharingDialog(eventData);
            showJoinAudioSharingDialog(eventData, metadata);
        }
    }

    private void showAudioSharingDialog(Pair<Integer, Object>[] eventData) {
    private void showJoinAudioSharingDialog(Pair<Integer, Object>[] eventData,
            @Nullable BluetoothLeBroadcastMetadata metadata) {
        if (!BluetoothUtils.isBroadcasting(mBtManager)) {
            Log.d(TAG, "Skip showAudioSharingDialog, broadcast is stopped");
            Log.d(TAG, "Skip showJoinAudioSharingDialog, broadcast is stopped");
            return;
        }
        AudioSharingDialogFragment.DialogEventListener listener =
                new AudioSharingDialogFragment.DialogEventListener() {
                    @Override
                    public void onPositiveClick() {
                        // Could go to other pages, dismiss the progress dialog.
                        // Could go to other pages (pair new device), dismiss the progress dialog.
                        dismissProgressDialogIfNeeded();
                        cleanUpStatesForStartSharing();
                    }
@@ -720,19 +723,17 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
                    public void onItemClick(@NonNull AudioSharingDeviceItem item) {
                        List<BluetoothDevice> targetSinks = mGroupedConnectedDevices.getOrDefault(
                                item.getGroupId(), ImmutableList.of());
                        addSourceToTargetSinks(targetSinks, item.getName());
                        addSourceToTargetSinks(targetSinks, item.getName(), metadata);
                        cleanUpStatesForStartSharing();
                    }

                    @Override
                    public void onCancelClick() {
                        // Could go to other pages, dismiss the progress dialog.
                        // Could go to other pages (show qr code), dismiss the progress dialog.
                        dismissProgressDialogIfNeeded();
                        cleanUpStatesForStartSharing();
                    }
                };
        BluetoothLeBroadcastMetadata metadata = mBroadcast == null ? null
                : mBroadcast.getLatestBluetoothLeBroadcastMetadata();
        AudioSharingUtils.postOnMainThread(
                mContext,
                () -> AudioSharingDialogFragment.show(
@@ -828,13 +829,27 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
                        });
    }

    private void addSourceToTargetSinks(List<BluetoothDevice> targetActiveSinks,
            @NonNull String sinkName) {
        mSinksInAdding.addAll(targetActiveSinks);
    private void addSourceToTargetSinks(List<BluetoothDevice> targetGroupedSinks,
            @NonNull String targetSinkName, @Nullable BluetoothLeBroadcastMetadata metadata) {
        if (targetGroupedSinks.isEmpty()) {
            Log.d(TAG, "Skip addSourceToTargetSinks, no sinks.");
            return;
        }
        if (metadata == null) {
            Log.d(TAG, "Skip addSourceToTargetSinks, metadata is null");
            return;
        }
        if (mAssistant == null) {
            Log.d(TAG, "skip addSourceToTargetDevices, assistant profile is null.");
            return;
        }
        mSinksInAdding.addAll(targetGroupedSinks);
        String progressMessage = mContext.getString(
                R.string.audio_sharing_progress_dialog_add_source_content, sinkName);
                R.string.audio_sharing_progress_dialog_add_source_content, targetSinkName);
        showProgressDialog(progressMessage);
        AudioSharingUtils.addSourceToTargetSinks(targetActiveSinks, mBtManager);
        for (BluetoothDevice sink : targetGroupedSinks) {
            mAssistant.addSource(sink, metadata, /* isGroupOp= */ false);
        }
    }

    private void showProgressDialog(@NonNull String progressMessage) {
Loading