[Audiosharing] Add audio sharing dialog.
Open the dialog when audio sharing main switch on.
Flagged with enable_le_audio_sharing
Bug: 305620450
Test: Manual
Change-Id: I5b7cf655782a1da8b4fbd42eca11b473bac339b0
diff --git a/res/layout/audio_sharing_device_item.xml b/res/layout/audio_sharing_device_item.xml
new file mode 100644
index 0000000..f8e7454
--- /dev/null
+++ b/res/layout/audio_sharing_device_item.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <Button
+ android:id="@+id/device_button"
+ android:overScrollMode="never"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAlignment="center"
+ android:text=""/>
+
+</FrameLayout>
\ No newline at end of file
diff --git a/res/layout/dialog_audio_sharing.xml b/res/layout/dialog_audio_sharing.xml
new file mode 100644
index 0000000..9624c90
--- /dev/null
+++ b/res/layout/dialog_audio_sharing.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:padding="24dp"
+ android:orientation="vertical">
+
+ <TextView
+ style="@style/device_info_dialog_value"
+ android:id="@+id/share_audio_subtitle1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAlignment="center"
+ android:layout_gravity="center"/>
+
+ <TextView
+ style="@style/device_info_dialog_value"
+ android:id="@+id/share_audio_subtitle2"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAlignment="center"
+ android:layout_gravity="center"/>
+
+ <com.android.internal.widget.RecyclerView
+ android:visibility="visible"
+ android:id="@+id/btn_list"
+ android:nestedScrollingEnabled="false"
+ android:overScrollMode="never"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDashboardFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDashboardFragment.java
index b9ef8f4..b3b7a2c 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDashboardFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDashboardFragment.java
@@ -75,6 +75,8 @@
mMainSwitchBar = activity.getSwitchBar();
mMainSwitchBar.setTitle(getText(R.string.audio_sharing_switch_title));
mSwitchBarController = new AudioSharingSwitchBarController(activity, mMainSwitchBar);
+ mSwitchBarController.init(this);
+ getSettingsLifecycle().addObserver(mSwitchBarController);
mMainSwitchBar.show();
}
}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceAdapter.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceAdapter.java
new file mode 100644
index 0000000..6d5b693
--- /dev/null
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceAdapter.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.connecteddevice.audiosharing;
+
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+
+import com.android.internal.widget.RecyclerView;
+import com.android.settings.R;
+
+import java.util.ArrayList;
+
+public class AudioSharingDeviceAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
+
+ private static final String TAG = "AudioSharingDeviceAdapter";
+ private final ArrayList<String> mDevices;
+ private final OnClickListener mOnClickListener;
+
+ public AudioSharingDeviceAdapter(ArrayList<String> devices, OnClickListener listener) {
+ mDevices = devices;
+ mOnClickListener = listener;
+ }
+
+ private class AudioSharingDeviceViewHolder extends RecyclerView.ViewHolder {
+ private final Button mButtonView;
+
+ AudioSharingDeviceViewHolder(View view) {
+ super(view);
+ mButtonView = view.findViewById(R.id.device_button);
+ }
+
+ public void bindView(int position) {
+ if (mButtonView != null) {
+ mButtonView.setText(mDevices.get(position));
+ mButtonView.setOnClickListener(v -> mOnClickListener.onClick(position));
+ } else {
+ Log.w(TAG, "bind view skipped due to button view is null");
+ }
+ }
+ }
+
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ View view =
+ LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.audio_sharing_device_item, parent, false);
+ return new AudioSharingDeviceViewHolder(view);
+ }
+
+ @Override
+ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
+ ((AudioSharingDeviceViewHolder) holder).bindView(position);
+ }
+
+ @Override
+ public int getItemCount() {
+ return mDevices.size();
+ }
+
+ public interface OnClickListener {
+ /** Called when an item has been clicked. */
+ void onClick(int position);
+ }
+}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragment.java
new file mode 100644
index 0000000..5b99907
--- /dev/null
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragment.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.connecteddevice.audiosharing;
+
+import android.app.Dialog;
+import android.app.settings.SettingsEnums;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+
+import com.android.internal.widget.LinearLayoutManager;
+import com.android.internal.widget.RecyclerView;
+import com.android.settings.R;
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+import com.android.settings.flags.Flags;
+
+import java.util.ArrayList;
+
+public class AudioSharingDialogFragment extends InstrumentedDialogFragment {
+ private static final String TAG = "AudioSharingDialog";
+
+ private View mRootView;
+
+ @Override
+ public int getMetricsCategory() {
+ return SettingsEnums.DIALOG_START_AUDIO_SHARING;
+ }
+
+ /**
+ * Display the {@link AudioSharingDialogFragment} dialog.
+ *
+ * @param host The Fragment this dialog will be hosted.
+ */
+ public static void show(Fragment host) {
+ if (!Flags.enableLeAudioSharing()) return;
+ final FragmentManager manager = host.getChildFragmentManager();
+ if (manager.findFragmentByTag(TAG) == null) {
+ final AudioSharingDialogFragment dialog = new AudioSharingDialogFragment();
+ dialog.show(manager, TAG);
+ }
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ final AlertDialog.Builder builder =
+ new AlertDialog.Builder(getActivity()).setTitle("Share audio");
+ mRootView =
+ LayoutInflater.from(builder.getContext())
+ .inflate(R.layout.dialog_audio_sharing, /* parent= */ null);
+ // TODO: use real subtitle according to device count.
+ TextView subTitle1 = mRootView.findViewById(R.id.share_audio_subtitle1);
+ TextView subTitle2 = mRootView.findViewById(R.id.share_audio_subtitle2);
+ subTitle1.setText("2 devices connected");
+ subTitle2.setText("placeholder");
+ RecyclerView recyclerView = mRootView.findViewById(R.id.btn_list);
+ // TODO: use real audio sharing device list.
+ ArrayList<String> devices = new ArrayList<>();
+ devices.add("Buds 1");
+ devices.add("Buds 2");
+ recyclerView.setAdapter(
+ new AudioSharingDeviceAdapter(
+ devices,
+ (int position) -> {
+ // TODO: add on click callback.
+ }));
+ recyclerView.setLayoutManager(
+ new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
+ return builder.setView(mRootView).create();
+ }
+}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java
index 1400720..a375a3c 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java
@@ -17,24 +17,30 @@
package com.android.settings.connecteddevice.audiosharing;
import android.content.Context;
+import android.util.Log;
import android.widget.Switch;
import androidx.annotation.NonNull;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.flags.Flags;
import com.android.settings.widget.SettingsMainSwitchBar;
import com.android.settingslib.widget.OnMainSwitchChangeListener;
-public class AudioSharingSwitchBarController
+public class AudioSharingSwitchBarController extends BasePreferenceController
implements DefaultLifecycleObserver, OnMainSwitchChangeListener {
-
private static final String TAG = "AudioSharingSwitchBarCtl";
+ private static final String PREF_KEY = "audio_sharing_main_switch";
private final Context mContext;
private final SettingsMainSwitchBar mSwitchBar;
+ private DashboardFragment mFragment;
AudioSharingSwitchBarController(Context context, SettingsMainSwitchBar switchBar) {
+ super(context, PREF_KEY);
mContext = context;
mSwitchBar = switchBar;
mSwitchBar.setChecked(false);
@@ -54,11 +60,32 @@
public void onSwitchChanged(Switch switchView, boolean isChecked) {
// Filter out unnecessary callbacks when switch is disabled.
if (!switchView.isEnabled()) return;
-
if (isChecked) {
- // TODO: start sharing
+ startAudioSharing();
} else {
// TODO: stop sharing
}
}
+
+ @Override
+ public int getAvailabilityStatus() {
+ return Flags.enableLeAudioSharing() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+ }
+
+ /**
+ * Initialize the controller.
+ *
+ * @param fragment The fragment to host the {@link AudioSharingSwitchBarController} dialog.
+ */
+ public void init(DashboardFragment fragment) {
+ this.mFragment = fragment;
+ }
+
+ private void startAudioSharing() {
+ if (mFragment != null) {
+ AudioSharingDialogFragment.show(mFragment);
+ } else {
+ Log.w(TAG, "Dialog fail to show due to null fragment.");
+ }
+ }
}