[Audiosharing] Add logging 2.
Test: atest -c com.android.settings.connecteddevice.audiosharing.audiostreams Bug: 308368124 Change-Id: I50fc57427aa135a13566c4627ba193aed9d73e0d
This commit is contained in:
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.settings.connecteddevice.audiosharing.audiostreams;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
@@ -37,6 +39,17 @@ class AddSourceBadCodeState extends SyncedState {
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
void performAction(
|
||||
AudioStreamPreference preference,
|
||||
AudioStreamsProgressCategoryController controller,
|
||||
AudioStreamsHelper helper) {
|
||||
mMetricsFeatureProvider.action(
|
||||
preference.getContext(),
|
||||
SettingsEnums.ACTION_AUDIO_STREAM_JOIN_FAILED_BAD_CODE,
|
||||
preference.getSourceOriginForLogging().ordinal());
|
||||
}
|
||||
|
||||
@Override
|
||||
int getSummary() {
|
||||
return AUDIO_STREAM_ADD_SOURCE_BAD_CODE_STATE_SUMMARY;
|
||||
|
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.settings.connecteddevice.audiosharing.audiostreams;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
@@ -37,6 +39,17 @@ class AddSourceFailedState extends SyncedState {
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
void performAction(
|
||||
AudioStreamPreference preference,
|
||||
AudioStreamsProgressCategoryController controller,
|
||||
AudioStreamsHelper helper) {
|
||||
mMetricsFeatureProvider.action(
|
||||
preference.getContext(),
|
||||
SettingsEnums.ACTION_AUDIO_STREAM_JOIN_FAILED_OTHER,
|
||||
preference.getSourceOriginForLogging().ordinal());
|
||||
}
|
||||
|
||||
@Override
|
||||
int getSummary() {
|
||||
return AUDIO_STREAM_ADD_SOURCE_FAILED_STATE_SUMMARY;
|
||||
|
@@ -17,6 +17,7 @@
|
||||
package com.android.settings.connecteddevice.audiosharing.audiostreams;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -52,6 +53,10 @@ class AddSourceWaitForResponseState extends AudioStreamStateHandler {
|
||||
var metadata = preference.getAudioStreamMetadata();
|
||||
if (metadata != null) {
|
||||
helper.addSource(metadata);
|
||||
mMetricsFeatureProvider.action(
|
||||
preference.getContext(),
|
||||
SettingsEnums.ACTION_AUDIO_STREAM_JOIN,
|
||||
preference.getSourceOriginForLogging().ordinal());
|
||||
// Cache the metadata that used for add source, if source is added successfully, we
|
||||
// will save it persistently.
|
||||
mAudioStreamsRepository.cacheMetadata(metadata);
|
||||
@@ -66,6 +71,10 @@ class AddSourceWaitForResponseState extends AudioStreamStateHandler {
|
||||
&& preference.getAudioStreamState() == getStateEnum()) {
|
||||
controller.handleSourceFailedToConnect(
|
||||
preference.getAudioStreamBroadcastId());
|
||||
mMetricsFeatureProvider.action(
|
||||
preference.getContext(),
|
||||
SettingsEnums.ACTION_AUDIO_STREAM_JOIN_FAILED_TIMEOUT,
|
||||
preference.getSourceOriginForLogging().ordinal());
|
||||
ThreadUtils.postOnMainThread(
|
||||
() -> {
|
||||
if (controller.getFragment() != null) {
|
||||
|
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.settings.connecteddevice.audiosharing.audiostreams;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothLeBroadcastAssistant;
|
||||
import android.bluetooth.BluetoothLeBroadcastMetadata;
|
||||
@@ -33,7 +34,9 @@ import androidx.preference.PreferenceScreen;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.bluetooth.Utils;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
|
||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
import com.android.settingslib.widget.ActionButtonsPreference;
|
||||
|
||||
@@ -44,6 +47,7 @@ public class AudioStreamButtonController extends BasePreferenceController
|
||||
implements DefaultLifecycleObserver {
|
||||
private static final String TAG = "AudioStreamButtonController";
|
||||
private static final String KEY = "audio_stream_button";
|
||||
private static final int SOURCE_ORIGIN_REPOSITORY = SourceOriginForLogging.REPOSITORY.ordinal();
|
||||
private final BluetoothLeBroadcastAssistant.Callback mBroadcastAssistantCallback =
|
||||
new AudioStreamsBroadcastAssistantCallback() {
|
||||
@Override
|
||||
@@ -56,6 +60,8 @@ public class AudioStreamButtonController extends BasePreferenceController
|
||||
public void onSourceRemoveFailed(BluetoothDevice sink, int sourceId, int reason) {
|
||||
super.onSourceRemoveFailed(sink, sourceId, reason);
|
||||
updateButton();
|
||||
mMetricsFeatureProvider.action(
|
||||
mContext, SettingsEnums.ACTION_AUDIO_STREAM_LEAVE_FAILED);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -66,6 +72,10 @@ public class AudioStreamButtonController extends BasePreferenceController
|
||||
super.onReceiveStateChanged(sink, sourceId, state);
|
||||
if (AudioStreamsHelper.isConnected(state)) {
|
||||
updateButton();
|
||||
mMetricsFeatureProvider.action(
|
||||
mContext,
|
||||
SettingsEnums.ACTION_AUDIO_STREAM_JOIN_SUCCEED,
|
||||
SOURCE_ORIGIN_REPOSITORY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +84,10 @@ public class AudioStreamButtonController extends BasePreferenceController
|
||||
BluetoothDevice sink, BluetoothLeBroadcastMetadata source, int reason) {
|
||||
super.onSourceAddFailed(sink, source, reason);
|
||||
updateButton();
|
||||
mMetricsFeatureProvider.action(
|
||||
mContext,
|
||||
SettingsEnums.ACTION_AUDIO_STREAM_JOIN_FAILED_OTHER,
|
||||
SOURCE_ORIGIN_REPOSITORY);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -88,6 +102,7 @@ public class AudioStreamButtonController extends BasePreferenceController
|
||||
private final Executor mExecutor;
|
||||
private final AudioStreamsHelper mAudioStreamsHelper;
|
||||
private final @Nullable LocalBluetoothLeBroadcastAssistant mLeBroadcastAssistant;
|
||||
private final MetricsFeatureProvider mMetricsFeatureProvider;
|
||||
private @Nullable ActionButtonsPreference mPreference;
|
||||
private int mBroadcastId = -1;
|
||||
|
||||
@@ -96,6 +111,7 @@ public class AudioStreamButtonController extends BasePreferenceController
|
||||
mExecutor = Executors.newSingleThreadExecutor();
|
||||
mAudioStreamsHelper = new AudioStreamsHelper(Utils.getLocalBtManager(context));
|
||||
mLeBroadcastAssistant = mAudioStreamsHelper.getLeBroadcastAssistant();
|
||||
mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -124,59 +140,77 @@ public class AudioStreamButtonController extends BasePreferenceController
|
||||
}
|
||||
|
||||
private void updateButton() {
|
||||
if (mPreference != null) {
|
||||
if (mAudioStreamsHelper.getAllConnectedSources().stream()
|
||||
.map(BluetoothLeBroadcastReceiveState::getBroadcastId)
|
||||
.anyMatch(connectedBroadcastId -> connectedBroadcastId == mBroadcastId)) {
|
||||
ThreadUtils.postOnMainThread(
|
||||
() -> {
|
||||
if (mPreference != null) {
|
||||
mPreference.setButton1Enabled(true);
|
||||
mPreference
|
||||
.setButton1Text(R.string.audio_streams_disconnect)
|
||||
.setButton1Icon(
|
||||
com.android.settings.R.drawable.ic_settings_close)
|
||||
.setButton1OnClickListener(
|
||||
unused -> {
|
||||
if (mPreference == null) {
|
||||
Log.w(TAG, "updateButton(): preference is null!");
|
||||
return;
|
||||
}
|
||||
boolean isConnected =
|
||||
mAudioStreamsHelper.getAllConnectedSources().stream()
|
||||
.map(BluetoothLeBroadcastReceiveState::getBroadcastId)
|
||||
.anyMatch(connectedBroadcastId -> connectedBroadcastId == mBroadcastId);
|
||||
|
||||
View.OnClickListener onClickListener;
|
||||
|
||||
if (isConnected) {
|
||||
onClickListener =
|
||||
unused ->
|
||||
ThreadUtils.postOnBackgroundThread(
|
||||
() -> {
|
||||
mAudioStreamsHelper.removeSource(mBroadcastId);
|
||||
mMetricsFeatureProvider.action(
|
||||
mContext,
|
||||
SettingsEnums
|
||||
.ACTION_AUDIO_STREAM_LEAVE_BUTTON_CLICK);
|
||||
ThreadUtils.postOnMainThread(
|
||||
() -> {
|
||||
if (mPreference != null) {
|
||||
mPreference.setButton1Enabled(false);
|
||||
}
|
||||
mAudioStreamsHelper.removeSource(mBroadcastId);
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
View.OnClickListener clickToRejoin =
|
||||
unused ->
|
||||
ThreadUtils.postOnBackgroundThread(
|
||||
() -> {
|
||||
var metadata =
|
||||
mAudioStreamsRepository.getSavedMetadata(
|
||||
mContext, mBroadcastId);
|
||||
if (metadata != null) {
|
||||
mAudioStreamsHelper.addSource(metadata);
|
||||
ThreadUtils.postOnMainThread(
|
||||
() -> {
|
||||
if (mPreference != null) {
|
||||
mPreference.setButton1Enabled(
|
||||
false);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
ThreadUtils.postOnMainThread(
|
||||
() -> {
|
||||
if (mPreference != null) {
|
||||
mPreference.setButton1Enabled(true);
|
||||
mPreference
|
||||
.setButton1Text(R.string.audio_streams_connect)
|
||||
.setButton1Icon(com.android.settings.R.drawable.ic_add_24dp)
|
||||
.setButton1OnClickListener(clickToRejoin);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
ThreadUtils.postOnMainThread(
|
||||
() -> {
|
||||
if (mPreference != null) {
|
||||
mPreference.setButton1Enabled(true);
|
||||
mPreference
|
||||
.setButton1Text(R.string.audio_streams_disconnect)
|
||||
.setButton1Icon(
|
||||
com.android.settings.R.drawable.ic_settings_close)
|
||||
.setButton1OnClickListener(onClickListener);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Log.w(TAG, "updateButton(): preference is null!");
|
||||
onClickListener =
|
||||
unused ->
|
||||
ThreadUtils.postOnBackgroundThread(
|
||||
() -> {
|
||||
var metadata =
|
||||
mAudioStreamsRepository.getSavedMetadata(
|
||||
mContext, mBroadcastId);
|
||||
if (metadata != null) {
|
||||
mAudioStreamsHelper.addSource(metadata);
|
||||
mMetricsFeatureProvider.action(
|
||||
mContext,
|
||||
SettingsEnums.ACTION_AUDIO_STREAM_JOIN,
|
||||
SOURCE_ORIGIN_REPOSITORY);
|
||||
ThreadUtils.postOnMainThread(
|
||||
() -> {
|
||||
if (mPreference != null) {
|
||||
mPreference.setButton1Enabled(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
ThreadUtils.postOnMainThread(
|
||||
() -> {
|
||||
if (mPreference != null) {
|
||||
mPreference.setButton1Enabled(true);
|
||||
mPreference
|
||||
.setButton1Text(R.string.audio_streams_connect)
|
||||
.setButton1Icon(com.android.settings.R.drawable.ic_add_24dp)
|
||||
.setButton1OnClickListener(onClickListener);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -107,6 +107,12 @@ class AudioStreamPreference extends TwoTargetPreference {
|
||||
: AudioStreamsProgressCategoryController.AudioStreamState.UNKNOWN;
|
||||
}
|
||||
|
||||
SourceOriginForLogging getSourceOriginForLogging() {
|
||||
return mAudioStream != null
|
||||
? mAudioStream.getSourceOriginForLogging()
|
||||
: SourceOriginForLogging.UNKNOWN;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldHideSecondTarget() {
|
||||
return mIsConnected || !mIsEncrypted;
|
||||
@@ -130,11 +136,13 @@ class AudioStreamPreference extends TwoTargetPreference {
|
||||
}
|
||||
|
||||
static AudioStreamPreference fromMetadata(
|
||||
Context context, BluetoothLeBroadcastMetadata source) {
|
||||
Context context,
|
||||
BluetoothLeBroadcastMetadata source,
|
||||
SourceOriginForLogging sourceOriginForLogging) {
|
||||
AudioStreamPreference preference = new AudioStreamPreference(context, /* attrs= */ null);
|
||||
preference.setIsEncrypted(source.isEncrypted());
|
||||
preference.setTitle(AudioStreamsHelper.getBroadcastName(source));
|
||||
preference.setAudioStream(new AudioStream(source));
|
||||
preference.setAudioStream(new AudioStream(source, sourceOriginForLogging));
|
||||
return preference;
|
||||
}
|
||||
|
||||
@@ -158,11 +166,15 @@ class AudioStreamPreference extends TwoTargetPreference {
|
||||
private static final int UNAVAILABLE = -1;
|
||||
@Nullable private BluetoothLeBroadcastMetadata mMetadata;
|
||||
@Nullable private BluetoothLeBroadcastReceiveState mReceiveState;
|
||||
private SourceOriginForLogging mSourceOriginForLogging = SourceOriginForLogging.UNKNOWN;
|
||||
private AudioStreamsProgressCategoryController.AudioStreamState mState =
|
||||
AudioStreamsProgressCategoryController.AudioStreamState.UNKNOWN;
|
||||
|
||||
private AudioStream(BluetoothLeBroadcastMetadata metadata) {
|
||||
private AudioStream(
|
||||
BluetoothLeBroadcastMetadata metadata,
|
||||
SourceOriginForLogging sourceOriginForLogging) {
|
||||
mMetadata = metadata;
|
||||
mSourceOriginForLogging = sourceOriginForLogging;
|
||||
}
|
||||
|
||||
private AudioStream(BluetoothLeBroadcastReceiveState receiveState) {
|
||||
@@ -191,6 +203,10 @@ class AudioStreamPreference extends TwoTargetPreference {
|
||||
return mState;
|
||||
}
|
||||
|
||||
private SourceOriginForLogging getSourceOriginForLogging() {
|
||||
return mSourceOriginForLogging;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private BluetoothLeBroadcastMetadata getMetadata() {
|
||||
return mMetadata;
|
||||
|
@@ -25,7 +25,9 @@ import androidx.annotation.StringRes;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settingslib.bluetooth.BluetoothUtils;
|
||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
|
||||
class AudioStreamStateHandler {
|
||||
@@ -35,6 +37,8 @@ class AudioStreamStateHandler {
|
||||
|
||||
final AudioStreamsRepository mAudioStreamsRepository = AudioStreamsRepository.getInstance();
|
||||
final Handler mHandler = new Handler(Looper.getMainLooper());
|
||||
final MetricsFeatureProvider mMetricsFeatureProvider =
|
||||
FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
|
||||
|
||||
AudioStreamStateHandler() {}
|
||||
|
||||
|
@@ -19,6 +19,7 @@ package com.android.settings.connecteddevice.audiosharing.audiostreams;
|
||||
import static com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamsScanQrCodeController.REQUEST_SCAN_BT_BROADCAST_QR_CODE;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.bluetooth.BluetoothLeBroadcastMetadata;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@@ -32,8 +33,6 @@ import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settingslib.bluetooth.BluetoothLeBroadcastMetadataExt;
|
||||
import com.android.settingslib.bluetooth.BluetoothUtils;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
public class AudioStreamsDashboardFragment extends DashboardFragment {
|
||||
public static final String KEY_BROADCAST_METADATA = "key_broadcast_metadata";
|
||||
private static final String TAG = "AudioStreamsDashboardFrag";
|
||||
@@ -46,8 +45,7 @@ public class AudioStreamsDashboardFragment extends DashboardFragment {
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
// TODO: update category id.
|
||||
return 0;
|
||||
return SettingsEnums.AUDIO_STREAM_MAIN;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -78,16 +76,17 @@ public class AudioStreamsDashboardFragment extends DashboardFragment {
|
||||
mAudioStreamsProgressCategoryController.setFragment(this);
|
||||
|
||||
if (getArguments() != null) {
|
||||
String broadcastMetadataStr = getArguments().getString(KEY_BROADCAST_METADATA);
|
||||
if (!Strings.isNullOrEmpty(broadcastMetadataStr)) {
|
||||
BluetoothLeBroadcastMetadata broadcastMetadata =
|
||||
BluetoothLeBroadcastMetadataExt.INSTANCE.convertToBroadcastMetadata(
|
||||
broadcastMetadataStr);
|
||||
if (broadcastMetadata == null) {
|
||||
Log.w(TAG, "onAttach() broadcastMetadata is null!");
|
||||
} else {
|
||||
mAudioStreamsProgressCategoryController.setSourceFromQrCode(broadcastMetadata);
|
||||
}
|
||||
var broadcastMetadata =
|
||||
getArguments()
|
||||
.getParcelable(
|
||||
KEY_BROADCAST_METADATA, BluetoothLeBroadcastMetadata.class);
|
||||
if (broadcastMetadata != null) {
|
||||
mAudioStreamsProgressCategoryController.setSourceFromQrCode(
|
||||
broadcastMetadata, SourceOriginForLogging.QR_CODE_SCAN_OTHER);
|
||||
mMetricsFeatureProvider.action(
|
||||
getContext(),
|
||||
SettingsEnums.ACTION_AUDIO_STREAM_QR_CODE_SCAN_SUCCEED,
|
||||
SourceOriginForLogging.QR_CODE_SCAN_OTHER.ordinal());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -128,7 +127,12 @@ public class AudioStreamsDashboardFragment extends DashboardFragment {
|
||||
"onActivityResult() AudioStreamsProgressCategoryController is null!");
|
||||
return;
|
||||
}
|
||||
mAudioStreamsProgressCategoryController.setSourceFromQrCode(source);
|
||||
mAudioStreamsProgressCategoryController.setSourceFromQrCode(
|
||||
source, SourceOriginForLogging.QR_CODE_SCAN_SETTINGS);
|
||||
mMetricsFeatureProvider.action(
|
||||
getContext(),
|
||||
SettingsEnums.ACTION_AUDIO_STREAM_QR_CODE_SCAN_SUCCEED,
|
||||
SourceOriginForLogging.QR_CODE_SCAN_SETTINGS.ordinal());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -19,12 +19,11 @@ package com.android.settings.connecteddevice.audiosharing.audiostreams;
|
||||
import static java.util.Collections.emptyList;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.bluetooth.BluetoothLeBroadcastMetadata;
|
||||
import android.bluetooth.BluetoothLeBroadcastReceiveState;
|
||||
import android.bluetooth.BluetoothProfile;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@@ -34,8 +33,10 @@ import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.bluetooth.Utils;
|
||||
import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment;
|
||||
import com.android.settings.connecteddevice.audiosharing.AudioSharingUtils;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settingslib.bluetooth.BluetoothCallback;
|
||||
import com.android.settingslib.bluetooth.BluetoothUtils;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
@@ -100,6 +101,7 @@ public class AudioStreamsProgressCategoryController extends BasePreferenceContro
|
||||
private final ConcurrentHashMap<Integer, AudioStreamPreference> mBroadcastIdToPreferenceMap =
|
||||
new ConcurrentHashMap<>();
|
||||
private @Nullable BluetoothLeBroadcastMetadata mSourceFromQrCode;
|
||||
private SourceOriginForLogging mSourceFromQrCodeOriginForLogging;
|
||||
@Nullable private AudioStreamsProgressCategoryPreference mCategoryPreference;
|
||||
@Nullable private AudioStreamsDashboardFragment mFragment;
|
||||
|
||||
@@ -149,11 +151,13 @@ public class AudioStreamsProgressCategoryController extends BasePreferenceContro
|
||||
return mFragment;
|
||||
}
|
||||
|
||||
void setSourceFromQrCode(BluetoothLeBroadcastMetadata source) {
|
||||
void setSourceFromQrCode(
|
||||
BluetoothLeBroadcastMetadata source, SourceOriginForLogging sourceOriginForLogging) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "setSourceFromQrCode(): broadcastId " + source.getBroadcastId());
|
||||
}
|
||||
mSourceFromQrCode = source;
|
||||
mSourceFromQrCodeOriginForLogging = sourceOriginForLogging;
|
||||
}
|
||||
|
||||
void setScanning(boolean isScanning) {
|
||||
@@ -196,7 +200,10 @@ public class AudioStreamsProgressCategoryController extends BasePreferenceContro
|
||||
broadcastIdFound,
|
||||
(k, existingPreference) -> {
|
||||
if (existingPreference == null) {
|
||||
return addNewPreference(source, AudioStreamState.SYNCED);
|
||||
return addNewPreference(
|
||||
source,
|
||||
AudioStreamState.SYNCED,
|
||||
SourceOriginForLogging.BROADCAST_SEARCH);
|
||||
}
|
||||
var fromState = existingPreference.getAudioStreamState();
|
||||
if (fromState == AudioStreamState.WAIT_FOR_SYNC && mSourceFromQrCode != null) {
|
||||
@@ -268,7 +275,9 @@ public class AudioStreamsProgressCategoryController extends BasePreferenceContro
|
||||
// Check nullability to bypass NullAway check.
|
||||
if (mSourceFromQrCode != null) {
|
||||
return addNewPreference(
|
||||
mSourceFromQrCode, AudioStreamState.WAIT_FOR_SYNC);
|
||||
mSourceFromQrCode,
|
||||
AudioStreamState.WAIT_FOR_SYNC,
|
||||
mSourceFromQrCodeOriginForLogging);
|
||||
}
|
||||
}
|
||||
Log.w(
|
||||
@@ -525,23 +534,27 @@ public class AudioStreamsProgressCategoryController extends BasePreferenceContro
|
||||
}
|
||||
|
||||
private AudioStreamPreference addNewPreference(
|
||||
BluetoothLeBroadcastMetadata metadata, AudioStreamState state) {
|
||||
var preference = AudioStreamPreference.fromMetadata(mContext, metadata);
|
||||
BluetoothLeBroadcastMetadata metadata,
|
||||
AudioStreamState state,
|
||||
SourceOriginForLogging sourceOriginForLogging) {
|
||||
var preference =
|
||||
AudioStreamPreference.fromMetadata(mContext, metadata, sourceOriginForLogging);
|
||||
moveToState(preference, state);
|
||||
return preference;
|
||||
}
|
||||
|
||||
private void moveToState(AudioStreamPreference preference, AudioStreamState state) {
|
||||
AudioStreamStateHandler stateHandler = switch (state) {
|
||||
case SYNCED -> SyncedState.getInstance();
|
||||
case WAIT_FOR_SYNC -> WaitForSyncState.getInstance();
|
||||
case ADD_SOURCE_WAIT_FOR_RESPONSE ->
|
||||
AddSourceWaitForResponseState.getInstance();
|
||||
case ADD_SOURCE_BAD_CODE -> AddSourceBadCodeState.getInstance();
|
||||
case ADD_SOURCE_FAILED -> AddSourceFailedState.getInstance();
|
||||
case SOURCE_ADDED -> SourceAddedState.getInstance();
|
||||
default -> throw new IllegalArgumentException("Unsupported state: " + state);
|
||||
};
|
||||
AudioStreamStateHandler stateHandler =
|
||||
switch (state) {
|
||||
case SYNCED -> SyncedState.getInstance();
|
||||
case WAIT_FOR_SYNC -> WaitForSyncState.getInstance();
|
||||
case ADD_SOURCE_WAIT_FOR_RESPONSE ->
|
||||
AddSourceWaitForResponseState.getInstance();
|
||||
case ADD_SOURCE_BAD_CODE -> AddSourceBadCodeState.getInstance();
|
||||
case ADD_SOURCE_FAILED -> AddSourceFailedState.getInstance();
|
||||
case SOURCE_ADDED -> SourceAddedState.getInstance();
|
||||
default -> throw new IllegalArgumentException("Unsupported state: " + state);
|
||||
};
|
||||
|
||||
stateHandler.handleStateChange(preference, this, mAudioStreamsHelper);
|
||||
|
||||
@@ -566,9 +579,12 @@ public class AudioStreamsProgressCategoryController extends BasePreferenceContro
|
||||
mContext.getString(R.string.audio_streams_dialog_no_le_device_button))
|
||||
.setRightButtonOnClickListener(
|
||||
dialog -> {
|
||||
mContext.startActivity(
|
||||
new Intent(Settings.ACTION_BLUETOOTH_SETTINGS)
|
||||
.setPackage(mContext.getPackageName()));
|
||||
new SubSettingLauncher(mContext)
|
||||
.setDestination(
|
||||
ConnectedDeviceDashboardFragment.class.getName())
|
||||
.setSourceMetricsCategory(
|
||||
SettingsEnums.DIALOG_AUDIO_STREAM_MAIN_NO_LE_DEVICE)
|
||||
.launch();
|
||||
dialog.dismiss();
|
||||
});
|
||||
}
|
||||
|
@@ -57,6 +57,10 @@ class SourceAddedState extends AudioStreamStateHandler {
|
||||
context,
|
||||
preference.getAudioStreamBroadcastId(),
|
||||
String.valueOf(preference.getTitle()));
|
||||
mMetricsFeatureProvider.action(
|
||||
preference.getContext(),
|
||||
SettingsEnums.ACTION_AUDIO_STREAM_JOIN_SUCCEED,
|
||||
preference.getSourceOriginForLogging().ordinal());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -79,8 +83,10 @@ class SourceAddedState extends AudioStreamStateHandler {
|
||||
.setTitleText(
|
||||
p.getContext().getString(R.string.audio_streams_detail_page_title))
|
||||
.setDestination(AudioStreamDetailsFragment.class.getName())
|
||||
// TODO(chelseahao): Add logging enum
|
||||
.setSourceMetricsCategory(SettingsEnums.PAGE_UNKNOWN)
|
||||
.setSourceMetricsCategory(
|
||||
controller.getFragment() == null
|
||||
? SettingsEnums.PAGE_UNKNOWN
|
||||
: controller.getFragment().getMetricsCategory())
|
||||
.setArguments(broadcast)
|
||||
.launch();
|
||||
return true;
|
||||
|
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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.audiostreams;
|
||||
|
||||
enum SourceOriginForLogging {
|
||||
UNKNOWN,
|
||||
QR_CODE_SCAN_SETTINGS,
|
||||
QR_CODE_SCAN_OTHER,
|
||||
BROADCAST_SEARCH,
|
||||
REPOSITORY,
|
||||
}
|
@@ -24,6 +24,7 @@ import android.content.Context;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
@@ -59,6 +60,11 @@ class WaitForSyncState extends AudioStreamStateHandler {
|
||||
if (preference.isShown()
|
||||
&& preference.getAudioStreamState() == getStateEnum()) {
|
||||
controller.handleSourceLost(preference.getAudioStreamBroadcastId());
|
||||
mMetricsFeatureProvider.action(
|
||||
preference.getContext(),
|
||||
SettingsEnums
|
||||
.ACTION_AUDIO_STREAM_JOIN_FAILED_WAIT_FOR_SYNC_TIMEOUT,
|
||||
preference.getSourceOriginForLogging().ordinal());
|
||||
ThreadUtils.postOnMainThread(
|
||||
() -> {
|
||||
if (controller.getFragment() != null) {
|
||||
@@ -101,18 +107,19 @@ class WaitForSyncState extends AudioStreamStateHandler {
|
||||
.setRightButtonOnClickListener(
|
||||
dialog -> {
|
||||
if (controller.getFragment() != null) {
|
||||
new SubSettingLauncher(context)
|
||||
.setTitleRes(
|
||||
R.string.audio_streams_main_page_scan_qr_code_title)
|
||||
.setDestination(
|
||||
AudioStreamsQrCodeScanFragment.class.getName())
|
||||
.setResultListener(
|
||||
controller.getFragment(),
|
||||
REQUEST_SCAN_BT_BROADCAST_QR_CODE)
|
||||
.setSourceMetricsCategory(SettingsEnums.PAGE_UNKNOWN)
|
||||
.launch();
|
||||
launchQrCodeScanFragment(context, controller.getFragment());
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void launchQrCodeScanFragment(Context context, Fragment fragment) {
|
||||
new SubSettingLauncher(context)
|
||||
.setTitleRes(R.string.audio_streams_main_page_scan_qr_code_title)
|
||||
.setDestination(AudioStreamsQrCodeScanFragment.class.getName())
|
||||
.setResultListener(fragment, REQUEST_SCAN_BT_BROADCAST_QR_CODE)
|
||||
.setSourceMetricsCategory(
|
||||
SettingsEnums.DIALOG_AUDIO_STREAM_MAIN_WAIT_FOR_SYNC_TIMEOUT)
|
||||
.launch();
|
||||
}
|
||||
}
|
||||
|
@@ -92,6 +92,8 @@ public class AddSourceWaitForResponseStateTest {
|
||||
@Test
|
||||
public void testPerformAction_metadataIsNotNull_addSource() {
|
||||
when(mMockPreference.getAudioStreamMetadata()).thenReturn(mMockMetadata);
|
||||
when(mMockPreference.getSourceOriginForLogging())
|
||||
.thenReturn(SourceOriginForLogging.UNKNOWN);
|
||||
|
||||
mInstance.performAction(mMockPreference, mMockController, mMockHelper);
|
||||
|
||||
@@ -105,6 +107,8 @@ public class AddSourceWaitForResponseStateTest {
|
||||
when(mMockPreference.isShown()).thenReturn(true);
|
||||
when(mMockPreference.getAudioStreamState()).thenReturn(mInstance.getStateEnum());
|
||||
when(mMockPreference.getAudioStreamBroadcastId()).thenReturn(BROADCAST_ID);
|
||||
when(mMockPreference.getSourceOriginForLogging())
|
||||
.thenReturn(SourceOriginForLogging.UNKNOWN);
|
||||
|
||||
mInstance.performAction(mMockPreference, mMockController, mMockHelper);
|
||||
ShadowLooper.idleMainLooper(ADD_SOURCE_WAIT_FOR_RESPONSE_TIMEOUT_MILLIS, TimeUnit.SECONDS);
|
||||
|
@@ -107,7 +107,8 @@ public class AudioStreamPreferenceTest {
|
||||
@Test
|
||||
public void setAudioStreamMetadata_shouldUpdateMetadata() {
|
||||
AudioStreamPreference p =
|
||||
AudioStreamPreference.fromMetadata(mContext, mBluetoothLeBroadcastMetadata);
|
||||
AudioStreamPreference.fromMetadata(
|
||||
mContext, mBluetoothLeBroadcastMetadata, SourceOriginForLogging.UNKNOWN);
|
||||
BluetoothLeBroadcastMetadata metadata = mock(BluetoothLeBroadcastMetadata.class);
|
||||
p.setAudioStreamMetadata(metadata);
|
||||
|
||||
@@ -117,7 +118,8 @@ public class AudioStreamPreferenceTest {
|
||||
@Test
|
||||
public void setAudioStreamState_shouldUpdateState() {
|
||||
AudioStreamPreference p =
|
||||
AudioStreamPreference.fromMetadata(mContext, mBluetoothLeBroadcastMetadata);
|
||||
AudioStreamPreference.fromMetadata(
|
||||
mContext, mBluetoothLeBroadcastMetadata, SourceOriginForLogging.UNKNOWN);
|
||||
AudioStreamState state = AudioStreamState.SOURCE_ADDED;
|
||||
p.setAudioStreamState(state);
|
||||
|
||||
@@ -127,7 +129,8 @@ public class AudioStreamPreferenceTest {
|
||||
@Test
|
||||
public void fromMetadata_shouldReturnBroadcastInfo() {
|
||||
AudioStreamPreference p =
|
||||
AudioStreamPreference.fromMetadata(mContext, mBluetoothLeBroadcastMetadata);
|
||||
AudioStreamPreference.fromMetadata(
|
||||
mContext, mBluetoothLeBroadcastMetadata, SourceOriginForLogging.UNKNOWN);
|
||||
assertThat(p.getAudioStreamBroadcastId()).isEqualTo(BROADCAST_ID);
|
||||
assertThat(p.getAudioStreamBroadcastName()).isEqualTo(BROADCAST_NAME);
|
||||
assertThat(p.getAudioStreamRssi()).isEqualTo(BROADCAST_RSSI);
|
||||
@@ -152,7 +155,8 @@ public class AudioStreamPreferenceTest {
|
||||
public void shouldHideSecondTarget_notEncrypted() {
|
||||
when(mBluetoothLeBroadcastMetadata.isEncrypted()).thenReturn(false);
|
||||
AudioStreamPreference p =
|
||||
AudioStreamPreference.fromMetadata(mContext, mBluetoothLeBroadcastMetadata);
|
||||
AudioStreamPreference.fromMetadata(
|
||||
mContext, mBluetoothLeBroadcastMetadata, SourceOriginForLogging.UNKNOWN);
|
||||
assertThat(p.shouldHideSecondTarget()).isTrue();
|
||||
}
|
||||
|
||||
@@ -160,7 +164,8 @@ public class AudioStreamPreferenceTest {
|
||||
public void shouldShowSecondTarget_encrypted() {
|
||||
when(mBluetoothLeBroadcastMetadata.isEncrypted()).thenReturn(true);
|
||||
AudioStreamPreference p =
|
||||
AudioStreamPreference.fromMetadata(mContext, mBluetoothLeBroadcastMetadata);
|
||||
AudioStreamPreference.fromMetadata(
|
||||
mContext, mBluetoothLeBroadcastMetadata, SourceOriginForLogging.UNKNOWN);
|
||||
assertThat(p.shouldHideSecondTarget()).isFalse();
|
||||
}
|
||||
|
||||
|
@@ -93,6 +93,8 @@ public class WaitForSyncStateTest {
|
||||
.thenReturn(AudioStreamsProgressCategoryController.AudioStreamState.WAIT_FOR_SYNC);
|
||||
when(mMockPreference.getAudioStreamBroadcastId()).thenReturn(1);
|
||||
when(mMockPreference.getAudioStreamMetadata()).thenReturn(mMockMetadata);
|
||||
when(mMockPreference.getSourceOriginForLogging())
|
||||
.thenReturn(SourceOriginForLogging.UNKNOWN);
|
||||
|
||||
mInstance.performAction(mMockPreference, mMockController, mMockHelper);
|
||||
ShadowLooper.idleMainLooper(WAIT_FOR_SYNC_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
|
||||
|
Reference in New Issue
Block a user