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

Commit 71cf2232 authored by Yiyi Shen's avatar Yiyi Shen Committed by Android (Google) Code Review
Browse files

Merge "[Audiosharing] Format files" into main

parents cce6ef49 bf6d4e4e
Loading
Loading
Loading
Loading
+54 −40
Original line number Diff line number Diff line
@@ -164,7 +164,8 @@ public class AudioSharingDialogHandler {
                        : null;
        mAudioManager = context.getSystemService(AudioManager.class);
        mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
        mHostMetricsCategory = mHostFragment instanceof DashboardFragment
        mHostMetricsCategory =
                mHostFragment instanceof DashboardFragment
                        ? ((DashboardFragment) mHostFragment).getMetricsCategory()
                        : SettingsEnums.PAGE_UNKNOWN;
    }
@@ -185,6 +186,7 @@ public class AudioSharingDialogHandler {

    /**
     * Handle dialog pop-up logic when device is connected.
     *
     * @param cachedDevice The target {@link CachedBluetoothDevice} to handle for
     * @param userTriggered If the device is connected by user
     * @return If a dialog is popped up
@@ -236,8 +238,10 @@ public class AudioSharingDialogHandler {
                            mLocalBtManager, groupedDevices, /* filterByInSharing= */ true);
            AudioSharingStopDialogFragment.DialogEventListener listener =
                    () -> {
                        if (mLocalBtManager != null && (Flags.adoptPrimaryGroupManagementApi() || (
                                mContext != null && Flags.audioSharingDeveloperOption()
                        if (mLocalBtManager != null
                                && (Flags.adoptPrimaryGroupManagementApi()
                                        || (mContext != null
                                                && Flags.audioSharingDeveloperOption()
                                                && BluetoothUtils.getAudioSharingPreviewValue(
                                                        mContext.getContentResolver())))) {
                            LeAudioProfile profile =
@@ -260,11 +264,7 @@ public class AudioSharingDialogHandler {
                            /* candidateDeviceCount= */ 0);
            closeOpeningDialogsOtherThan(AudioSharingStopDialogFragment.tag());
            return AudioSharingStopDialogFragment.show(
                    mHostFragment,
                    deviceItemsInSharingSession,
                    cachedDevice,
                    listener,
                    eventData);
                    mHostFragment, deviceItemsInSharingSession, cachedDevice, listener, eventData);
        } else {
            if (userTriggered) {
                cachedDevice.setActive();
@@ -298,7 +298,8 @@ public class AudioSharingDialogHandler {
                                                    device, mLocalBtManager))) {
                Log.d(TAG, "Auto add sink with the same group to the sharing: " + deviceAddress);
                if (mAssistant != null && mBroadcast != null) {
                    mMetricsFeatureProvider.action(mContext,
                    mMetricsFeatureProvider.action(
                            mContext,
                            SettingsEnums.ACTION_AUDIO_SHARING_ADD_SOURCE,
                            AudioSharingUtils.buildAddSourceEventData(
                                    mHostMetricsCategory, /* userTriggered= */ false));
@@ -323,7 +324,9 @@ public class AudioSharingDialogHandler {
                            // Remove all sources from the device user clicked
                            removeSourceForGroup(item.getGroupId(), groupedDevices);
                            // Add current broadcast to the latest connected device
                            addSourceForGroup(groupId, groupedDevices,
                            addSourceForGroup(
                                    groupId,
                                    groupedDevices,
                                    AudioSharingUtils.buildAddSourceEventData(
                                            SettingsEnums.DIALOG_AUDIO_SHARING_SWITCH_DEVICE,
                                            userTriggered));
@@ -335,8 +338,7 @@ public class AudioSharingDialogHandler {
                                userTriggered,
                                deviceItemsInSharingSession.size(),
                                /* candidateDeviceCount= */ 1);
                closeOpeningDialogsOtherThan(
                        AudioSharingDisconnectDialogFragment.tag());
                closeOpeningDialogsOtherThan(AudioSharingDisconnectDialogFragment.tag());
                Log.d(TAG, "Show disconnect dialog, device = " + deviceAddress);
                return AudioSharingDisconnectDialogFragment.show(
                        mHostFragment,
@@ -351,7 +353,9 @@ public class AudioSharingDialogHandler {
                        new AudioSharingJoinDialogFragment.DialogEventListener() {
                            @Override
                            public void onShareClick() {
                                addSourceForGroup(groupId, groupedDevices,
                                addSourceForGroup(
                                        groupId,
                                        groupedDevices,
                                        AudioSharingUtils.buildAddSourceEventData(
                                                SettingsEnums.DIALOG_AUDIO_SHARING_ADD_DEVICE,
                                                userTriggered));
@@ -448,7 +452,11 @@ public class AudioSharingDialogHandler {
                    try {
                        fragments = mHostFragment.getChildFragmentManager().getFragments();
                    } catch (IllegalStateException e) {
                        Log.d(TAG, "Fail to closeOpeningDialogsOtherThan " + tag + ": "
                        Log.d(
                                TAG,
                                "Fail to closeOpeningDialogsOtherThan "
                                        + tag
                                        + ": "
                                        + e.getMessage());
                        return;
                    }
@@ -507,8 +515,9 @@ public class AudioSharingDialogHandler {
                    }
                    for (Fragment fragment : fragments) {
                        CachedBluetoothDevice device = getCachedBluetoothDeviceFromDialog(fragment);
                        if (device != null && address != null && address.equals(
                                device.getAddress())) {
                        if (device != null
                                && address != null
                                && address.equals(device.getAddress())) {
                            Log.d(
                                    TAG,
                                    "Remove staled opening dialog for device "
@@ -544,26 +553,31 @@ public class AudioSharingDialogHandler {
            return;
        }
        List<BluetoothDevice> devices = groupedDevices.get(groupId);
        devices.stream().forEach(
        devices.stream()
                .forEach(
                        device -> {
                            for (BluetoothLeBroadcastReceiveState source :
                                    mAssistant.getAllSources(device)) {
                                mAssistant.removeSource(device, source.getSourceId());
                            }
                        });
        boolean isPrimary = groupId == BluetoothUtils.getPrimaryGroupIdForBroadcast(
        boolean isPrimary =
                groupId
                        == BluetoothUtils.getPrimaryGroupIdForBroadcast(
                                mContext.getContentResolver(), mLocalBtManager);
        boolean isTempBond = devices.stream().anyMatch(BluetoothUtils::isTemporaryBondDevice);
        Pair<Integer, Object>[] eventData = new Pair[]{
        Pair<Integer, Object>[] eventData =
                new Pair[] {
                    Pair.create(METRIC_KEY_DEVICE_IS_PRIMARY.getId(), isPrimary ? 1 : 0),
                    Pair.create(METRIC_KEY_DEVICE_IS_TEMP_BOND.getId(), isTempBond ? 1 : 0)
                };
        mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_AUDIO_SHARING_REMOVE_SOURCE,
                eventData);
        mMetricsFeatureProvider.action(
                mContext, SettingsEnums.ACTION_AUDIO_SHARING_REMOVE_SOURCE, eventData);
    }

    private void addSourceForGroup(
            int groupId, Map<Integer, List<BluetoothDevice>> groupedDevices,
            int groupId,
            Map<Integer, List<BluetoothDevice>> groupedDevices,
            Pair<Integer, Object>[] eventData) {
        if (mBroadcast == null || mAssistant == null) {
            Log.d(TAG, "Fail to add source due to null profiles, group = " + groupId);
@@ -580,8 +594,8 @@ public class AudioSharingDialogHandler {
                                        device,
                                        mBroadcast.getLatestBluetoothLeBroadcastMetadata(),
                                        /* isGroupOp= */ false));
        mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_AUDIO_SHARING_ADD_SOURCE,
                eventData);
        mMetricsFeatureProvider.action(
                mContext, SettingsEnums.ACTION_AUDIO_SHARING_ADD_SOURCE, eventData);
    }

    private boolean isBroadcasting() {
+60 −48
Original line number Diff line number Diff line
@@ -102,7 +102,8 @@ public class AudioSharingReceiver extends BroadcastReceiver {
                    cancelSharingNotification(context, AUDIO_SHARING_NOTIFICATION_ID);
                    cancelSharingNotification(context, ADD_SOURCE_NOTIFICATION_ID);
                    metricsFeatureProvider.action(
                            context, SettingsEnums.ACTION_CANCEL_AUDIO_SHARING_NOTIFICATION,
                            context,
                            SettingsEnums.ACTION_CANCEL_AUDIO_SHARING_NOTIFICATION,
                            LocalBluetoothLeBroadcast.ACTION_LE_AUDIO_SHARING_STATE_CHANGE);
                } else {
                    Log.w(
@@ -127,7 +128,8 @@ public class AudioSharingReceiver extends BroadcastReceiver {
                //       or FEATURE_NOT_SUPPORTED when BT and BLE off
                cancelSharingNotification(context, AUDIO_SHARING_NOTIFICATION_ID);
                metricsFeatureProvider.action(
                        context, SettingsEnums.ACTION_CANCEL_AUDIO_SHARING_NOTIFICATION,
                        context,
                        SettingsEnums.ACTION_CANCEL_AUDIO_SHARING_NOTIFICATION,
                        ACTION_LE_AUDIO_SHARING_STOP);
                cancelSharingNotification(context, ADD_SOURCE_NOTIFICATION_ID);
                break;
@@ -137,8 +139,8 @@ public class AudioSharingReceiver extends BroadcastReceiver {
                    Log.d(TAG, "Skip ACTION_LE_AUDIO_SHARING_DEVICE_CONNECTED, flag/feature off");
                    return;
                }
                BluetoothDevice device = intent.getParcelableExtra(EXTRA_BLUETOOTH_DEVICE,
                        BluetoothDevice.class);
                BluetoothDevice device =
                        intent.getParcelableExtra(EXTRA_BLUETOOTH_DEVICE, BluetoothDevice.class);
                if (device == null) {
                    Log.d(TAG, "Skip ACTION_LE_AUDIO_SHARING_DEVICE_CONNECTED, null device");
                    return;
@@ -167,14 +169,15 @@ public class AudioSharingReceiver extends BroadcastReceiver {
                    cancelSharingNotification(context, ADD_SOURCE_NOTIFICATION_ID);
                    return;
                }
                BluetoothDevice sink = intent.getParcelableExtra(EXTRA_BLUETOOTH_DEVICE,
                        BluetoothDevice.class);
                BluetoothDevice sink =
                        intent.getParcelableExtra(EXTRA_BLUETOOTH_DEVICE, BluetoothDevice.class);
                LocalBluetoothManager manager = Utils.getLocalBtManager(context);
                ImmutableList<BluetoothDevice> sinksToAdd = validToAddSource(sink, action, manager);
                AudioSharingUtils.addSourceToTargetSinks(sinksToAdd, manager);
                cancelSharingNotification(context, ADD_SOURCE_NOTIFICATION_ID);
                if (!sinksToAdd.isEmpty()) {
                    metricsFeatureProvider.action(context,
                    metricsFeatureProvider.action(
                            context,
                            SettingsEnums.ACTION_AUDIO_SHARING_ADD_SOURCE,
                            AudioSharingUtils.buildAddSourceEventData(
                                    SettingsEnums.ACTION_SHOW_ADD_SOURCE_NOTIFICATION,
@@ -196,8 +199,10 @@ public class AudioSharingReceiver extends BroadcastReceiver {
        }
    }

    private ImmutableList<BluetoothDevice> validToAddSource(@Nullable BluetoothDevice sink,
            @NonNull String action, @Nullable LocalBluetoothManager btManager) {
    private ImmutableList<BluetoothDevice> validToAddSource(
            @Nullable BluetoothDevice sink,
            @NonNull String action,
            @Nullable LocalBluetoothManager btManager) {
        if (sink == null) {
            Log.d(TAG, "Skip " + action + ", null device");
            return ImmutableList.of();
@@ -209,17 +214,23 @@ public class AudioSharingReceiver extends BroadcastReceiver {
        }
        Map<Integer, List<BluetoothDevice>> groupedDevices =
                AudioSharingUtils.fetchConnectedDevicesByGroupId(btManager);
        int groupId = groupedDevices.entrySet().stream().filter(
                entry -> entry.getValue().contains(sink)).findFirst().map(
                Map.Entry::getKey).orElse(BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
        int groupId =
                groupedDevices.entrySet().stream()
                        .filter(entry -> entry.getValue().contains(sink))
                        .findFirst()
                        .map(Map.Entry::getKey)
                        .orElse(BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
        if (groupId == BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
            Log.d(TAG, "Skip " + action + ", no valid group id");
            return ImmutableList.of();
        }
        List<BluetoothDevice> sinksToAdd = groupedDevices.getOrDefault(groupId,
                ImmutableList.of()).stream().filter(
                    d -> !BluetoothUtils.hasConnectedBroadcastSourceForBtDevice(d,
                        btManager)).toList();
        List<BluetoothDevice> sinksToAdd =
                groupedDevices.getOrDefault(groupId, ImmutableList.of()).stream()
                        .filter(
                                d ->
                                        !BluetoothUtils.hasConnectedBroadcastSourceForBtDevice(
                                                d, btManager))
                        .toList();
        if (sinksToAdd.isEmpty()) {
            Log.d(TAG, "Skip " + action + ", already has source");
            return ImmutableList.of();
@@ -294,13 +305,14 @@ public class AudioSharingReceiver extends BroadcastReceiver {
        nm.notify(AUDIO_SHARING_NOTIFICATION_ID, builder.build());
    }

    private void showAddSourceNotification(@NonNull Context context,
            @NonNull BluetoothDevice device) {
    private void showAddSourceNotification(
            @NonNull Context context, @NonNull BluetoothDevice device) {
        NotificationManager nm = context.getSystemService(NotificationManager.class);
        if (nm == null) return;
        createNotificationChannelIfNeeded(nm, context);
        Intent addSourceIntent =
                new Intent(ACTION_LE_AUDIO_SHARING_ADD_SOURCE).setPackage(context.getPackageName())
                new Intent(ACTION_LE_AUDIO_SHARING_ADD_SOURCE)
                        .setPackage(context.getPackageName())
                        .putExtra(EXTRA_BLUETOOTH_DEVICE, device);
        // Use PendingIntent.FLAG_UPDATE_CURRENT here because intent extra (device) could be updated
        PendingIntent addSourcePendingIntent =
@@ -308,7 +320,8 @@ public class AudioSharingReceiver extends BroadcastReceiver {
                        context,
                        R.string.audio_sharing_share_button_label,
                        addSourceIntent,
                        PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT
                        PendingIntent.FLAG_ONE_SHOT
                                | PendingIntent.FLAG_UPDATE_CURRENT
                                | PendingIntent.FLAG_IMMUTABLE);
        NotificationCompat.Action addSourceAction =
                new NotificationCompat.Action.Builder(
@@ -316,20 +329,16 @@ public class AudioSharingReceiver extends BroadcastReceiver {
                                context.getString(R.string.audio_sharing_share_button_label),
                                addSourcePendingIntent)
                        .build();
        Intent cancelIntent = new Intent(ACTION_LE_AUDIO_SHARING_CANCEL_NOTIF).setPackage(
                        context.getPackageName())
        Intent cancelIntent =
                new Intent(ACTION_LE_AUDIO_SHARING_CANCEL_NOTIF)
                        .setPackage(context.getPackageName())
                        .putExtra(EXTRA_NOTIF_ID, ADD_SOURCE_NOTIFICATION_ID);
        PendingIntent cancelPendingIntent =
                PendingIntent.getBroadcast(
                        context,
                        R.string.cancel,
                        cancelIntent,
                        PendingIntent.FLAG_IMMUTABLE);
                        context, R.string.cancel, cancelIntent, PendingIntent.FLAG_IMMUTABLE);
        NotificationCompat.Action cancelAction =
                new NotificationCompat.Action.Builder(
                        0,
                        context.getString(R.string.cancel),
                        cancelPendingIntent)
                                0, context.getString(R.string.cancel), cancelPendingIntent)
                        .build();
        final Bundle extras = new Bundle();
        extras.putString(
@@ -343,8 +352,9 @@ public class AudioSharingReceiver extends BroadcastReceiver {
                new NotificationCompat.Builder(context, CHANNEL_ID)
                        .setSmallIcon(com.android.settingslib.R.drawable.ic_bt_le_audio_sharing)
                        .setLocalOnly(true)
                        .setContentTitle(context.getString(R.string.share_audio_notification_title,
                                deviceName))
                        .setContentTitle(
                                context.getString(
                                        R.string.share_audio_notification_title, deviceName))
                        .setContentText(
                                context.getString(R.string.audio_sharing_notification_content))
                        .setOngoing(true)
@@ -367,8 +377,8 @@ public class AudioSharingReceiver extends BroadcastReceiver {
        }
    }

    private void createNotificationChannelIfNeeded(@NonNull NotificationManager nm,
            @NonNull Context context) {
    private void createNotificationChannelIfNeeded(
            @NonNull NotificationManager nm, @NonNull Context context) {
        if (nm.getNotificationChannel(CHANNEL_ID) == null) {
            Log.d(TAG, "Create bluetooth notification channel");
            NotificationChannel notificationChannel =
@@ -384,12 +394,14 @@ public class AudioSharingReceiver extends BroadcastReceiver {
        try {
            ActivityManager activityManager = context.getSystemService(ActivityManager.class);
            String packageName = context.getPackageName();
            if (context.getPackageManager().checkPermission(Manifest.permission.PACKAGE_USAGE_STATS,
                    packageName) != PackageManager.PERMISSION_GRANTED) {
            if (context.getPackageManager()
                            .checkPermission(Manifest.permission.PACKAGE_USAGE_STATS, packageName)
                    != PackageManager.PERMISSION_GRANTED) {
                Log.d(TAG, "check isAppInForeground, returns false due to no permission");
                return false;
            }
            if (packageName != null && activityManager.getPackageImportance(packageName)
            if (packageName != null
                    && activityManager.getPackageImportance(packageName)
                            == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
                Log.d(TAG, "check isAppInForeground, returns true");
                return true;