diff --git a/color-check-baseline.xml b/color-check-baseline.xml
index 75d4aba8304..15b497632f6 100644
--- a/color-check-baseline.xml
+++ b/color-check-baseline.xml
@@ -1,658 +1,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
diff --git a/res/layout/dialog_audio_sharing_loading_state.xml b/res/layout/dialog_audio_sharing_progress.xml
similarity index 100%
rename from res/layout/dialog_audio_sharing_loading_state.xml
rename to res/layout/dialog_audio_sharing_progress.xml
diff --git a/res/values/strings.xml b/res/values/strings.xml
index c586c3fb7b5..fb95aa3bd39 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -12141,8 +12141,8 @@
Satellite messaging is included with your account
Satellite messaging isn\u2019t included with your account
-
- Add satellite messaging
+
+ Learn More
How it works
diff --git a/src/com/android/settings/bluetooth/BluetoothDevicePairingDetailBase.java b/src/com/android/settings/bluetooth/BluetoothDevicePairingDetailBase.java
index 86f090e8be5..f1e12a4a6fe 100644
--- a/src/com/android/settings/bluetooth/BluetoothDevicePairingDetailBase.java
+++ b/src/com/android/settings/bluetooth/BluetoothDevicePairingDetailBase.java
@@ -72,7 +72,7 @@ public abstract class BluetoothDevicePairingDetailBase extends DeviceListPrefere
private final Handler mHandler = new Handler(Looper.getMainLooper());
private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
@Nullable
- private AlertDialog mLoadingDialog = null;
+ private AlertDialog mProgressDialog = null;
@VisibleForTesting
boolean mShouldTriggerAudioSharingShareThenPairFlow = false;
private CopyOnWriteArrayList mDevicesWithMetadataChangedListener =
@@ -89,7 +89,7 @@ public abstract class BluetoothDevicePairingDetailBase extends DeviceListPrefere
// In share then pair flow, we have to wait on this page till the device is connected.
// The BluetoothDevicePreference summary will be blank for seconds between "Pairing..." and
// "Connecting..." To help users better understand the process, we listen to metadata change
- // as well and show a loading dialog with "Connecting to ...." once BluetoothDevice.getState()
+ // as well and show a progress dialog with "Connecting to ...." once BluetoothDevice.getState()
// gets to BOND_BONDED.
final BluetoothAdapter.OnMetadataChangedListener mMetadataListener =
new BluetoothAdapter.OnMetadataChangedListener() {
@@ -97,7 +97,7 @@ public abstract class BluetoothDevicePairingDetailBase extends DeviceListPrefere
public void onMetadataChanged(@NonNull BluetoothDevice device, int key,
@Nullable byte[] value) {
Log.d(getLogTag(), "onMetadataChanged device = " + device + ", key = " + key);
- if (mShouldTriggerAudioSharingShareThenPairFlow && mLoadingDialog == null
+ if (mShouldTriggerAudioSharingShareThenPairFlow && mProgressDialog == null
&& device.getBondState() == BluetoothDevice.BOND_BONDED
&& mSelectedList.contains(device)) {
triggerAudioSharingShareThenPairFlow(device);
@@ -355,7 +355,7 @@ public abstract class BluetoothDevicePairingDetailBase extends DeviceListPrefere
return;
}
mJustBonded = device;
- // Show connecting device loading state
+ // Show connecting device progress
String aliasName = device.getAlias();
String deviceName = TextUtils.isEmpty(aliasName) ? device.getAddress()
: aliasName;
@@ -387,9 +387,9 @@ public abstract class BluetoothDevicePairingDetailBase extends DeviceListPrefere
// TODO: use DialogFragment
private void showConnectingDialog(@NonNull String message) {
postOnMainThread(() -> {
- if (mLoadingDialog != null) {
+ if (mProgressDialog != null) {
Log.d(getLogTag(), "showConnectingDialog, is already showing");
- TextView textView = mLoadingDialog.findViewById(R.id.message);
+ TextView textView = mProgressDialog.findViewById(R.id.message);
if (textView != null && !message.equals(textView.getText().toString())) {
Log.d(getLogTag(), "showConnectingDialog, update message");
// TODO: use string res once finalized
@@ -401,7 +401,7 @@ public abstract class BluetoothDevicePairingDetailBase extends DeviceListPrefere
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = LayoutInflater.from(builder.getContext());
View customView = inflater.inflate(
- R.layout.dialog_audio_sharing_loading_state, /* root= */
+ R.layout.dialog_audio_sharing_progress, /* root= */
null);
TextView textView = customView.findViewById(R.id.message);
if (textView != null) {
@@ -410,15 +410,15 @@ public abstract class BluetoothDevicePairingDetailBase extends DeviceListPrefere
}
AlertDialog dialog = builder.setView(customView).setCancelable(false).create();
dialog.setCanceledOnTouchOutside(false);
- mLoadingDialog = dialog;
+ mProgressDialog = dialog;
dialog.show();
});
}
private void dismissConnectingDialog() {
postOnMainThread(() -> {
- if (mLoadingDialog != null) {
- mLoadingDialog.dismiss();
+ if (mProgressDialog != null) {
+ mProgressDialog.dismiss();
}
});
}
diff --git a/src/com/android/settings/bluetooth/BluetoothSliceBuilder.java b/src/com/android/settings/bluetooth/BluetoothSliceBuilder.java
index fd8ef1fd82a..f4060d62dfd 100644
--- a/src/com/android/settings/bluetooth/BluetoothSliceBuilder.java
+++ b/src/com/android/settings/bluetooth/BluetoothSliceBuilder.java
@@ -26,6 +26,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.provider.SettingsSlicesContract;
+import android.util.Log;
import androidx.core.graphics.drawable.IconCompat;
import androidx.slice.Slice;
@@ -36,10 +37,16 @@ import androidx.slice.builders.SliceAction;
import com.android.settings.R;
import com.android.settings.SubSettings;
import com.android.settings.connecteddevice.BluetoothDashboardFragment;
+import com.android.settings.network.SatelliteRepository;
import com.android.settings.slices.CustomSliceRegistry;
import com.android.settings.slices.SliceBroadcastReceiver;
import com.android.settings.slices.SliceBuilderUtils;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
/**
* Utility class to build a Bluetooth Slice, and handle all associated actions.
*/
@@ -80,18 +87,34 @@ public class BluetoothSliceBuilder {
final PendingIntent primaryAction = getPrimaryAction(context);
final SliceAction primarySliceAction = SliceAction.createDeeplink(primaryAction, icon,
ListBuilder.ICON_IMAGE, title);
- final SliceAction toggleSliceAction = SliceAction.createToggle(toggleAction,
- null /* actionTitle */, isBluetoothEnabled);
+ RowBuilder rowBuilder = new RowBuilder();
+ rowBuilder.setTitle(title);
+ rowBuilder.setPrimaryAction(primarySliceAction);
+ if (!isSatelliteOn(context)) {
+ final SliceAction toggleSliceAction = SliceAction.createToggle(toggleAction,
+ null /* actionTitle */, isBluetoothEnabled);
+ rowBuilder.addEndItem(toggleSliceAction);
+ }
return new ListBuilder(context, CustomSliceRegistry.BLUETOOTH_URI, ListBuilder.INFINITY)
.setAccentColor(color)
- .addRow(new RowBuilder()
- .setTitle(title)
- .addEndItem(toggleSliceAction)
- .setPrimaryAction(primarySliceAction))
+ .addRow(rowBuilder)
.build();
}
+ private static boolean isSatelliteOn(Context context) {
+ boolean result = false;
+ SatelliteRepository satelliteRepository = new SatelliteRepository(context);
+ try {
+ result = satelliteRepository.requestIsSessionStarted(
+ Executors.newSingleThreadExecutor()).get(3000, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ Log.e(TAG, "Error to get satellite status : " + e);
+ }
+
+ return result;
+ }
+
public static Intent getIntent(Context context) {
final String screenTitle = context.getText(R.string.bluetooth_settings_title).toString();
final Uri contentUri = new Uri.Builder().appendPath(
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingRetryDialogFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingErrorDialogFragment.java
similarity index 89%
rename from src/com/android/settings/connecteddevice/audiosharing/AudioSharingRetryDialogFragment.java
rename to src/com/android/settings/connecteddevice/audiosharing/AudioSharingErrorDialogFragment.java
index 822e0537149..95b9bc36b92 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingRetryDialogFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingErrorDialogFragment.java
@@ -29,8 +29,8 @@ import androidx.fragment.app.FragmentManager;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settingslib.bluetooth.BluetoothUtils;
-public class AudioSharingRetryDialogFragment extends InstrumentedDialogFragment {
- private static final String TAG = "AudioSharingRetryDialog";
+public class AudioSharingErrorDialogFragment extends InstrumentedDialogFragment {
+ private static final String TAG = "AudioSharingErrorDialog";
@Override
public int getMetricsCategory() {
@@ -39,7 +39,7 @@ public class AudioSharingRetryDialogFragment extends InstrumentedDialogFragment
}
/**
- * Display the {@link AudioSharingRetryDialogFragment} dialog.
+ * Display the {@link AudioSharingErrorDialogFragment} dialog.
*
* @param host The Fragment this dialog will be hosted.
*/
@@ -57,8 +57,8 @@ public class AudioSharingRetryDialogFragment extends InstrumentedDialogFragment
Log.d(TAG, "Dialog is showing, return.");
return;
}
- Log.d(TAG, "Show up the retry dialog.");
- AudioSharingRetryDialogFragment dialogFrag = new AudioSharingRetryDialogFragment();
+ Log.d(TAG, "Show up the error dialog.");
+ AudioSharingErrorDialogFragment dialogFrag = new AudioSharingErrorDialogFragment();
dialogFrag.show(manager, TAG);
}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingLoadingStateDialogFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingProgressDialogFragment.java
similarity index 91%
rename from src/com/android/settings/connecteddevice/audiosharing/AudioSharingLoadingStateDialogFragment.java
rename to src/com/android/settings/connecteddevice/audiosharing/AudioSharingProgressDialogFragment.java
index 8706590c362..53bfcf8f17c 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingLoadingStateDialogFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingProgressDialogFragment.java
@@ -40,8 +40,8 @@ import com.google.common.base.Strings;
import java.util.concurrent.TimeUnit;
-public class AudioSharingLoadingStateDialogFragment extends InstrumentedDialogFragment {
- private static final String TAG = "AudioSharingLoadingDlg";
+public class AudioSharingProgressDialogFragment extends InstrumentedDialogFragment {
+ private static final String TAG = "AudioSharingProgressDlg";
private static final String BUNDLE_KEY_MESSAGE = "bundle_key_message";
private static final long AUTO_DISMISS_TIME_THRESHOLD_MS = TimeUnit.SECONDS.toMillis(15);
@@ -58,7 +58,7 @@ public class AudioSharingLoadingStateDialogFragment extends InstrumentedDialogFr
}
/**
- * Display the {@link AudioSharingLoadingStateDialogFragment} dialog.
+ * Display the {@link AudioSharingProgressDialogFragment} dialog.
*
* @param host The Fragment this dialog will be hosted by.
* @param message The content to be shown on the dialog.
@@ -85,16 +85,15 @@ public class AudioSharingLoadingStateDialogFragment extends InstrumentedDialogFr
return;
}
sMessage = message;
- Log.d(TAG, "Show up the loading dialog.");
+ Log.d(TAG, "Show up the progress dialog.");
Bundle args = new Bundle();
args.putString(BUNDLE_KEY_MESSAGE, message);
- AudioSharingLoadingStateDialogFragment dialogFrag =
- new AudioSharingLoadingStateDialogFragment();
+ AudioSharingProgressDialogFragment dialogFrag = new AudioSharingProgressDialogFragment();
dialogFrag.setArguments(args);
dialogFrag.show(manager, TAG);
}
- /** Dismiss the {@link AudioSharingLoadingStateDialogFragment} dialog. */
+ /** Dismiss the {@link AudioSharingProgressDialogFragment} dialog. */
public static void dismiss(@Nullable Fragment host) {
if (host == null || !BluetoothUtils.isAudioSharingEnabled()) return;
final FragmentManager manager;
@@ -119,7 +118,7 @@ public class AudioSharingLoadingStateDialogFragment extends InstrumentedDialogFr
String message = args.getString(BUNDLE_KEY_MESSAGE, "");
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = LayoutInflater.from(builder.getContext());
- View customView = inflater.inflate(R.layout.dialog_audio_sharing_loading_state, /* root= */
+ View customView = inflater.inflate(R.layout.dialog_audio_sharing_progress, /* root= */
null);
TextView textView = customView.findViewById(R.id.message);
if (!Strings.isNullOrEmpty(message)) textView.setText(message);
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java
index 395647ca84a..ebc8cecadbf 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java
@@ -41,7 +41,9 @@ import android.widget.CompoundButton.OnCheckedChangeListener;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.UiThread;
import androidx.annotation.VisibleForTesting;
+import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
@@ -69,7 +71,6 @@ import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
-import java.util.Locale;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executor;
@@ -113,14 +114,21 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
private final Executor mExecutor;
private final MetricsFeatureProvider mMetricsFeatureProvider;
private final OnAudioSharingStateChangedListener mListener;
+ @VisibleForTesting IntentFilter mIntentFilter;
private Map> mGroupedConnectedDevices = new HashMap<>();
@Nullable private AudioSharingDeviceItem mTargetActiveItem;
private List mDeviceItemsForSharing = new ArrayList<>();
- @VisibleForTesting IntentFilter mIntentFilter;
private final AtomicBoolean mCallbacksRegistered = new AtomicBoolean(false);
private AtomicInteger mIntentHandleStage =
new AtomicInteger(StartIntentHandleStage.TO_HANDLE.ordinal());
+ // The sinks in adding source process. We show the progress dialog based on this list.
private CopyOnWriteArrayList mSinksInAdding = new CopyOnWriteArrayList<>();
+ // The primary/active sinks in adding source process.
+ // To avoid users advance to share then pair flow before the primary/active sinks successfully
+ // join the audio sharing, we will wait for the process complete for this list of sinks and then
+ // popup audio sharing dialog with options to pair new device.
+ private CopyOnWriteArrayList mSinksToWaitFor = new CopyOnWriteArrayList<>();
+ private AtomicBoolean mStoppingSharing = new AtomicBoolean(false);
@VisibleForTesting
BroadcastReceiver mReceiver =
@@ -153,6 +161,7 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
public void onBroadcastStartFailed(int reason) {
Log.d(TAG, "onBroadcastStartFailed(), reason = " + reason);
updateSwitch();
+ showErrorDialog();
mMetricsFeatureProvider.action(
mContext,
SettingsEnums.ACTION_AUDIO_SHARING_START_FAILED,
@@ -178,7 +187,10 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
+ reason
+ ", broadcastId = "
+ broadcastId);
+ mStoppingSharing.compareAndSet(true, false);
updateSwitch();
+ AudioSharingUtils.postOnMainThread(mContext,
+ () -> dismissStaleDialogsOtherThanErrorDialog());
AudioSharingUtils.toastMessage(
mContext,
mContext.getString(R.string.audio_sharing_sharing_stopped_label));
@@ -219,7 +231,7 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
TAG,
"Skip handleOnBroadcastReady: null assistant or "
+ "sink has active local source.");
- cleanUp();
+ cleanUpStatesForStartSharing();
return;
}
handleOnBroadcastReady();
@@ -264,17 +276,14 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
+ source
+ ", reason = "
+ reason);
- mMetricsFeatureProvider.action(
- mContext,
- SettingsEnums.ACTION_AUDIO_SHARING_JOIN_FAILED,
- SettingsEnums.AUDIO_SHARING_SETTINGS);
- AudioSharingUtils.toastMessage(
- mContext,
- String.format(
- Locale.US,
- "Fail to add source to %s reason %d",
- sink.getAddress(),
- reason));
+ if (mSinksInAdding.contains(sink)) {
+ stopAudioSharing();
+ showErrorDialog();
+ mMetricsFeatureProvider.action(
+ mContext,
+ SettingsEnums.ACTION_AUDIO_SHARING_JOIN_FAILED,
+ SettingsEnums.AUDIO_SHARING_SETTINGS);
+ }
}
@Override
@@ -298,13 +307,33 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
@NonNull BluetoothDevice sink,
int sourceId,
@NonNull BluetoothLeBroadcastReceiveState state) {
+ if (mStoppingSharing.get()) {
+ Log.d(TAG, "Skip onReceiveStateChanged, stopping broadcast");
+ return;
+ }
if (BluetoothUtils.isConnected(state)) {
if (mSinksInAdding.contains(sink)) {
mSinksInAdding.remove(sink);
}
- dismissLoadingStateDialogIfNeeded();
+ dismissProgressDialogIfNeeded();
Log.d(TAG, "onReceiveStateChanged() connected, sink = " + sink
+ ", remaining sinks = " + mSinksInAdding);
+ if (mSinksToWaitFor.contains(sink)) {
+ mSinksToWaitFor.remove(sink);
+ if (mSinksToWaitFor.isEmpty()) {
+ // 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.
+ Pair[] eventData =
+ AudioSharingUtils.buildAudioSharingDialogEventData(
+ SettingsEnums.AUDIO_SHARING_SETTINGS,
+ SettingsEnums.DIALOG_AUDIO_SHARING_ADD_DEVICE,
+ /* userTriggered= */ false,
+ /* deviceCountInSharing= */ 1,
+ /* candidateDeviceCount= */ 0);
+ showAudioSharingDialog(eventData);
+ }
+ }
}
}
};
@@ -411,6 +440,8 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
return;
}
stopAudioSharing();
+ mMetricsFeatureProvider.action(
+ mContext, SettingsEnums.ACTION_AUDIO_SHARING_MAIN_SWITCH_OFF);
}
}
@@ -542,7 +573,7 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
mSinksInAdding.clear();
// TODO: use string res once finalized.
AudioSharingUtils.postOnMainThread(mContext,
- () -> AudioSharingLoadingStateDialogFragment.show(mFragment,
+ () -> AudioSharingProgressDialogFragment.show(mFragment,
"Starting audio stream..."));
mMetricsFeatureProvider.action(
mContext,
@@ -553,9 +584,14 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
private void stopAudioSharing() {
if (mBroadcast != null) {
- mBroadcast.stopBroadcast(mBroadcast.getLatestBroadcastId());
- mMetricsFeatureProvider.action(
- mContext, SettingsEnums.ACTION_AUDIO_SHARING_MAIN_SWITCH_OFF);
+ int broadcastId = mBroadcast.getLatestBroadcastId();
+ if (broadcastId != -1) {
+ mBroadcast.stopBroadcast(broadcastId);
+ mStoppingSharing.compareAndSet(false, true);
+ mSinksInAdding.clear();
+ mSinksToWaitFor.clear();
+ }
+ cleanUpStatesForStartSharing();
}
}
@@ -617,11 +653,22 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
/* userTriggered= */ false,
/* deviceCountInSharing= */ targetActiveSinks.isEmpty() ? 0 : 1,
/* candidateDeviceCount= */ mDeviceItemsForSharing.size());
+ // 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());
+ // 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.
+ if (mDeviceItemsForSharing.isEmpty()) {
+ mSinksToWaitFor.clear();
+ mSinksToWaitFor.addAll(targetActiveSinks);
+ }
mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_AUTO_JOIN_AUDIO_SHARING);
mTargetActiveItem = null;
+ // When audio sharing page is brought up by intent with EXTRA_START_LE_AUDIO_SHARING
+ // == true, plus there is one active lea headset and one connected lea headset, we
+ // should auto add these sinks without user interactions.
if (mIntentHandleStage.compareAndSet(
StartIntentHandleStage.HANDLE_AUTO_ADD.ordinal(),
StartIntentHandleStage.HANDLED.ordinal())
@@ -631,31 +678,42 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
List targetSinks = mGroupedConnectedDevices.getOrDefault(
target.getGroupId(), ImmutableList.of());
addSourceToTargetSinks(targetSinks, target.getName());
- cleanUp();
+ cleanUpStatesForStartSharing();
// TODO: Add metric for auto add by intent
return;
}
}
+ // Still mark intent as handled if early returned due to preconditions not met
mIntentHandleStage.compareAndSet(
StartIntentHandleStage.HANDLE_AUTO_ADD.ordinal(),
StartIntentHandleStage.HANDLED.ordinal());
if (mFragment == null) {
Log.d(TAG, "handleOnBroadcastReady: dialog fail to show due to null fragment.");
- dismissLoadingStateDialogIfNeeded();
- cleanUp();
+ // Clean up states before early return.
+ dismissProgressDialogIfNeeded();
+ cleanUpStatesForStartSharing();
return;
}
- showDialog(eventData);
+ // 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.
+ if (mSinksToWaitFor.isEmpty() && !mStoppingSharing.get()) {
+ showAudioSharingDialog(eventData);
+ }
}
- private void showDialog(Pair[] eventData) {
+ private void showAudioSharingDialog(Pair[] eventData) {
+ if (!BluetoothUtils.isBroadcasting(mBtManager)) {
+ Log.d(TAG, "Skip showAudioSharingDialog, broadcast is stopped");
+ return;
+ }
AudioSharingDialogFragment.DialogEventListener listener =
new AudioSharingDialogFragment.DialogEventListener() {
@Override
public void onPositiveClick() {
- // Could go to other pages, dismiss the loading dialog.
- dismissLoadingStateDialogIfNeeded();
- cleanUp();
+ // Could go to other pages, dismiss the progress dialog.
+ dismissProgressDialogIfNeeded();
+ cleanUpStatesForStartSharing();
}
@Override
@@ -663,14 +721,14 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
List targetSinks = mGroupedConnectedDevices.getOrDefault(
item.getGroupId(), ImmutableList.of());
addSourceToTargetSinks(targetSinks, item.getName());
- cleanUp();
+ cleanUpStatesForStartSharing();
}
@Override
public void onCancelClick() {
- // Could go to other pages, dismiss the loading dialog.
- dismissLoadingStateDialogIfNeeded();
- cleanUp();
+ // Could go to other pages, dismiss the progress dialog.
+ dismissProgressDialogIfNeeded();
+ cleanUpStatesForStartSharing();
}
};
AudioSharingUtils.postOnMainThread(
@@ -684,6 +742,36 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
});
}
+ private void showErrorDialog() {
+ AudioSharingUtils.postOnMainThread(mContext,
+ () -> {
+ // Remove all stale dialogs before showing error dialog
+ dismissStaleDialogsOtherThanErrorDialog();
+ AudioSharingErrorDialogFragment.show(mFragment);
+ });
+ }
+
+ @UiThread
+ private void dismissStaleDialogsOtherThanErrorDialog() {
+ List fragments = new ArrayList();
+ try {
+ if (mFragment != null) {
+ fragments =
+ mFragment.getChildFragmentManager().getFragments();
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Fail to dismiss stale dialogs: " + e.getMessage());
+ }
+ for (Fragment fragment : fragments) {
+ if (fragment != null && fragment instanceof DialogFragment
+ && !(fragment instanceof AudioSharingErrorDialogFragment)
+ && ((DialogFragment) fragment).getDialog() != null) {
+ Log.d(TAG, "Remove stale dialog = " + fragment.getTag());
+ ((DialogFragment) fragment).dismiss();
+ }
+ }
+ }
+
private static final class MainSwitchAccessibilityDelegate extends View.AccessibilityDelegate {
@Override
public boolean onRequestSendAccessibilityEvent(
@@ -742,25 +830,25 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
private void addSourceToTargetSinks(List targetActiveSinks,
@NonNull String sinkName) {
mSinksInAdding.addAll(targetActiveSinks);
- AudioSharingUtils.addSourceToTargetSinks(targetActiveSinks, mBtManager);
// TODO: move to res once finalized
- String loadingMessage = "Sharing with " + sinkName + "...";
- showLoadingStateDialog(loadingMessage);
+ String progressMessage = "Sharing with " + sinkName + "...";
+ showProgressDialog(progressMessage);
+ AudioSharingUtils.addSourceToTargetSinks(targetActiveSinks, mBtManager);
}
- private void showLoadingStateDialog(@NonNull String loadingMessage) {
+ private void showProgressDialog(@NonNull String progressMessage) {
AudioSharingUtils.postOnMainThread(mContext,
- () -> AudioSharingLoadingStateDialogFragment.show(mFragment, loadingMessage));
+ () -> AudioSharingProgressDialogFragment.show(mFragment, progressMessage));
}
- private void dismissLoadingStateDialogIfNeeded() {
+ private void dismissProgressDialogIfNeeded() {
if (mSinksInAdding.isEmpty()) {
AudioSharingUtils.postOnMainThread(mContext,
- () -> AudioSharingLoadingStateDialogFragment.dismiss(mFragment));
+ () -> AudioSharingProgressDialogFragment.dismiss(mFragment));
}
}
- private void cleanUp() {
+ private void cleanUpStatesForStartSharing() {
mGroupedConnectedDevices.clear();
mDeviceItemsForSharing.clear();
}
diff --git a/src/com/android/settings/deviceinfo/firmwareversion/BasebandVersionPreference.kt b/src/com/android/settings/deviceinfo/firmwareversion/BasebandVersionPreference.kt
new file mode 100644
index 00000000000..fb27dd814c8
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/firmwareversion/BasebandVersionPreference.kt
@@ -0,0 +1,57 @@
+/*
+ * 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.deviceinfo.firmwareversion
+
+import android.content.Context
+import android.os.SystemProperties
+import androidx.preference.Preference
+import com.android.settings.R
+import com.android.settings.Utils
+import com.android.settingslib.metadata.PreferenceAvailabilityProvider
+import com.android.settingslib.metadata.PreferenceMetadata
+import com.android.settingslib.metadata.PreferenceSummaryProvider
+import com.android.settingslib.preference.PreferenceBinding
+
+// LINT.IfChange
+class BasebandVersionPreference :
+ PreferenceMetadata,
+ PreferenceSummaryProvider,
+ PreferenceAvailabilityProvider,
+ PreferenceBinding {
+
+ override val key: String
+ get() = "base_band"
+
+ override val title: Int
+ get() = R.string.baseband_version
+
+ override fun getSummary(context: Context): CharSequence? =
+ SystemProperties.get(BASEBAND_PROPERTY, context.getString(R.string.device_info_default))
+
+ override fun isAvailable(context: Context) = !Utils.isWifiOnly(context)
+
+ override fun bind(preference: Preference, metadata: PreferenceMetadata) {
+ super.bind(preference, metadata)
+ preference.isSelectable = false
+ preference.isCopyingEnabled = true
+ }
+
+ companion object {
+ const val BASEBAND_PROPERTY: String = "gsm.version.baseband"
+ }
+}
+// LINT.ThenChange(BasebandVersionPreferenceController.java)
diff --git a/src/com/android/settings/deviceinfo/firmwareversion/BasebandVersionPreferenceController.java b/src/com/android/settings/deviceinfo/firmwareversion/BasebandVersionPreferenceController.java
index dd3d560282a..235638433be 100644
--- a/src/com/android/settings/deviceinfo/firmwareversion/BasebandVersionPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/firmwareversion/BasebandVersionPreferenceController.java
@@ -25,6 +25,7 @@ import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.core.BasePreferenceController;
+// LINT.IfChange
public class BasebandVersionPreferenceController extends BasePreferenceController {
@VisibleForTesting
@@ -45,3 +46,4 @@ public class BasebandVersionPreferenceController extends BasePreferenceControlle
mContext.getString(R.string.device_info_default));
}
}
+// LINT.ThenChange(BasebandVersionPreference.kt)
diff --git a/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionScreen.kt b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionScreen.kt
index 58fdefe6e4a..0908f9eaa85 100644
--- a/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionScreen.kt
+++ b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionScreen.kt
@@ -50,9 +50,9 @@ class FirmwareVersionScreen : PreferenceScreenCreator, PreferenceSummaryProvider
+PreferenceWidget("os_firmware_version", R.string.firmware_version)
+PreferenceWidget("security_key", R.string.security_patch)
+PreferenceWidget("module_version", R.string.module_version)
- +PreferenceWidget("base_band", R.string.baseband_version)
- +PreferenceWidget("kernel_version", R.string.kernel_version)
- +PreferenceWidget("os_build_number", R.string.build_number)
+ +BasebandVersionPreference()
+ +KernelVersionPreference()
+ +SimpleBuildNumberPreference()
}
private class PreferenceWidget(override val key: String, override val title: Int) :
diff --git a/src/com/android/settings/deviceinfo/firmwareversion/KernelVersionPreference.kt b/src/com/android/settings/deviceinfo/firmwareversion/KernelVersionPreference.kt
new file mode 100644
index 00000000000..789117852b5
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/firmwareversion/KernelVersionPreference.kt
@@ -0,0 +1,45 @@
+/*
+ * 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.deviceinfo.firmwareversion
+
+import android.content.Context
+import androidx.preference.Preference
+import com.android.settings.R
+import com.android.settingslib.DeviceInfoUtils
+import com.android.settingslib.metadata.PreferenceMetadata
+import com.android.settingslib.metadata.PreferenceSummaryProvider
+import com.android.settingslib.preference.PreferenceBinding
+
+// LINT.IfChange
+class KernelVersionPreference : PreferenceMetadata, PreferenceSummaryProvider, PreferenceBinding {
+
+ override val key: String
+ get() = "kernel_version"
+
+ override val title: Int
+ get() = R.string.kernel_version
+
+ override fun getSummary(context: Context): CharSequence? =
+ DeviceInfoUtils.getFormattedKernelVersion(context)
+
+ override fun bind(preference: Preference, metadata: PreferenceMetadata) {
+ super.bind(preference, metadata)
+ preference.isSelectable = false
+ preference.isCopyingEnabled = true
+ }
+}
+// LINT.ThenChange(KernelVersionPreferenceController.java)
diff --git a/src/com/android/settings/deviceinfo/firmwareversion/KernelVersionPreferenceController.java b/src/com/android/settings/deviceinfo/firmwareversion/KernelVersionPreferenceController.java
index 0500c89371a..7a3bdafb5e7 100644
--- a/src/com/android/settings/deviceinfo/firmwareversion/KernelVersionPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/firmwareversion/KernelVersionPreferenceController.java
@@ -21,6 +21,7 @@ import android.content.Context;
import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.DeviceInfoUtils;
+// LINT.IfChange
public class KernelVersionPreferenceController extends BasePreferenceController {
public KernelVersionPreferenceController(Context context, String preferenceKey) {
@@ -37,3 +38,4 @@ public class KernelVersionPreferenceController extends BasePreferenceController
return DeviceInfoUtils.getFormattedKernelVersion(mContext);
}
}
+// LINT.ThenChange(KernelVersionPreference.kt)
diff --git a/src/com/android/settings/deviceinfo/firmwareversion/SimpleBuildNumberPreference.kt b/src/com/android/settings/deviceinfo/firmwareversion/SimpleBuildNumberPreference.kt
new file mode 100644
index 00000000000..62cc2f985e7
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/firmwareversion/SimpleBuildNumberPreference.kt
@@ -0,0 +1,52 @@
+/*
+ * 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.deviceinfo.firmwareversion
+
+import android.content.Context
+import android.os.Build
+import android.text.BidiFormatter
+import android.view.View.LAYOUT_DIRECTION_RTL
+import androidx.preference.Preference
+import com.android.settings.R
+import com.android.settingslib.metadata.PreferenceMetadata
+import com.android.settingslib.metadata.PreferenceSummaryProvider
+import com.android.settingslib.preference.PreferenceBinding
+
+// LINT.IfChange
+class SimpleBuildNumberPreference :
+ PreferenceMetadata, PreferenceSummaryProvider, PreferenceBinding {
+
+ override val key: String
+ get() = "os_build_number"
+
+ override val title: Int
+ get() = R.string.build_number
+
+ override fun isIndexable(context: Context) = false
+
+ override fun getSummary(context: Context): CharSequence? {
+ val isRtl = context.resources.configuration.layoutDirection == LAYOUT_DIRECTION_RTL
+ return BidiFormatter.getInstance(isRtl).unicodeWrap(Build.DISPLAY)
+ }
+
+ override fun bind(preference: Preference, metadata: PreferenceMetadata) {
+ super.bind(preference, metadata)
+ preference.isSelectable = false
+ preference.isCopyingEnabled = true
+ }
+}
+// LINT.ThenChange(SimpleBuildNumberPreferenceController.java)
diff --git a/src/com/android/settings/deviceinfo/firmwareversion/SimpleBuildNumberPreferenceController.java b/src/com/android/settings/deviceinfo/firmwareversion/SimpleBuildNumberPreferenceController.java
index 53f5ff9aa9d..11988f7002e 100644
--- a/src/com/android/settings/deviceinfo/firmwareversion/SimpleBuildNumberPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/firmwareversion/SimpleBuildNumberPreferenceController.java
@@ -22,6 +22,7 @@ import android.text.BidiFormatter;
import com.android.settings.core.BasePreferenceController;
+// LINT.IfChange
public class SimpleBuildNumberPreferenceController extends BasePreferenceController {
public SimpleBuildNumberPreferenceController(Context context,
@@ -39,3 +40,4 @@ public class SimpleBuildNumberPreferenceController extends BasePreferenceControl
return BidiFormatter.getInstance().unicodeWrap(Build.DISPLAY);
}
}
+// LINT.ThenChange(SimpleBuildNumberPreference.kt)
diff --git a/src/com/android/settings/language/OnDeviceRecognitionPreferenceController.java b/src/com/android/settings/language/OnDeviceRecognitionPreferenceController.java
index cd9f266cf90..d0dec6430d7 100644
--- a/src/com/android/settings/language/OnDeviceRecognitionPreferenceController.java
+++ b/src/com/android/settings/language/OnDeviceRecognitionPreferenceController.java
@@ -20,7 +20,6 @@ import android.app.Dialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.UserInfo;
import android.os.UserHandle;
import android.os.UserManager;
import android.text.TextUtils;
@@ -80,10 +79,7 @@ public class OnDeviceRecognitionPreferenceController extends BasePreferenceContr
}
private void show(Preference preference) {
- final List userHandles = new ArrayList<>();
- for (UserInfo userInfo : UserManager.get(mContext).getUsers()) {
- userHandles.add(userInfo.getUserHandle());
- }
+ final List userHandles = UserManager.get(mContext).getEnabledProfiles();
// Only a single profile is installed. Proceed with its settings.
if (userHandles.size() == 1) {
diff --git a/src/com/android/settings/network/MobileNetworkListFragment.kt b/src/com/android/settings/network/MobileNetworkListFragment.kt
index d110779b36d..3118088c6c3 100644
--- a/src/com/android/settings/network/MobileNetworkListFragment.kt
+++ b/src/com/android/settings/network/MobileNetworkListFragment.kt
@@ -89,7 +89,7 @@ class MobileNetworkListFragment : DashboardFragment() {
private val simRepositoryFactory: (Context) -> SimRepository = ::SimRepository
) : BaseSearchIndexProvider(R.xml.network_provider_sims_list) {
public override fun isPageSearchEnabled(context: Context): Boolean =
- simRepositoryFactory(context).showMobileNetworkPage()
+ simRepositoryFactory(context).canEnterMobileNetworkPage()
}
}
}
diff --git a/src/com/android/settings/network/MobileNetworkSummaryController.kt b/src/com/android/settings/network/MobileNetworkSummaryController.kt
index 5980bbd7d05..8cf9bec283e 100644
--- a/src/com/android/settings/network/MobileNetworkSummaryController.kt
+++ b/src/com/android/settings/network/MobileNetworkSummaryController.kt
@@ -57,7 +57,7 @@ constructor(
private var isAirplaneModeOn = false
override fun getAvailabilityStatus() =
- if (SimRepository(mContext).showMobileNetworkPage()) AVAILABLE
+ if (SimRepository(mContext).showMobileNetworkPageEntrance()) AVAILABLE
else CONDITIONALLY_UNAVAILABLE
override fun displayPreference(screen: PreferenceScreen) {
diff --git a/src/com/android/settings/network/SimOnboardingActivity.kt b/src/com/android/settings/network/SimOnboardingActivity.kt
index 25afb661e8b..7fab9c9848e 100644
--- a/src/com/android/settings/network/SimOnboardingActivity.kt
+++ b/src/com/android/settings/network/SimOnboardingActivity.kt
@@ -53,8 +53,8 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.lifecycle.LifecycleRegistry
import com.android.settings.R
import com.android.settings.SidecarFragment
+import com.android.settings.network.telephony.SimRepository
import com.android.settings.network.telephony.SubscriptionActionDialogActivity
-import com.android.settings.network.telephony.SubscriptionRepository
import com.android.settings.network.telephony.ToggleSubscriptionDialogActivity
import com.android.settings.network.telephony.requireSubscriptionManager
import com.android.settings.spa.SpaActivity.Companion.startSpaActivity
@@ -578,6 +578,10 @@ class SimOnboardingActivity : SpaBaseDialogActivity() {
subId: Int,
isNewTask: Boolean = false,
) {
+ if (!SimRepository(context).canEnterMobileNetworkPage()) {
+ Log.i(TAG, "Unable to start SimOnboardingActivity due to missing permissions")
+ return
+ }
val intent = Intent(context, SimOnboardingActivity::class.java).apply {
putExtra(SUB_ID, subId)
if(isNewTask) {
diff --git a/src/com/android/settings/network/TopLevelNetworkEntryPreferenceController.kt b/src/com/android/settings/network/TopLevelNetworkEntryPreferenceController.kt
index 1722f6ae6b9..11698a6699c 100644
--- a/src/com/android/settings/network/TopLevelNetworkEntryPreferenceController.kt
+++ b/src/com/android/settings/network/TopLevelNetworkEntryPreferenceController.kt
@@ -48,7 +48,7 @@ constructor(
override fun getSummary(): CharSequence {
val summaryResId =
- if (simRepository.showMobileNetworkPage()) {
+ if (simRepository.showMobileNetworkPageEntrance()) {
R.string.network_dashboard_summary_mobile
} else {
R.string.network_dashboard_summary_no_mobile
diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettingsSearchIndex.kt b/src/com/android/settings/network/telephony/MobileNetworkSettingsSearchIndex.kt
index 83e3a31ff3f..f850e1d9b4b 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkSettingsSearchIndex.kt
+++ b/src/com/android/settings/network/telephony/MobileNetworkSettingsSearchIndex.kt
@@ -21,7 +21,6 @@ import android.provider.Settings
import android.telephony.SubscriptionInfo
import com.android.settings.R
import com.android.settings.datausage.BillingCyclePreferenceController.Companion.BillingCycleSearchItem
-import com.android.settings.network.SubscriptionUtil
import com.android.settings.network.telephony.CarrierSettingsVersionPreferenceController.Companion.CarrierSettingsVersionSearchItem
import com.android.settings.network.telephony.DataUsagePreferenceController.Companion.DataUsageSearchItem
import com.android.settings.network.telephony.MmsMessagePreferenceController.Companion.MmsMessageSearchItem
@@ -36,7 +35,6 @@ import com.android.settings.spa.search.SpaSearchRepository.Companion.createSearc
import com.android.settings.spa.search.SpaSearchRepository.Companion.searchIndexProviderOf
import com.android.settingslib.search.SearchIndexableData
import com.android.settingslib.search.SearchIndexableRaw
-import com.android.settingslib.spaprivileged.framework.common.userManager
import com.android.settingslib.spaprivileged.settingsprovider.settingsGlobalBoolean
class MobileNetworkSettingsSearchIndex(
@@ -109,12 +107,8 @@ class MobileNetworkSettingsSearchIndex(
companion object {
/** suppress full page if user is not admin */
@JvmStatic
- fun isMobileNetworkSettingsSearchable(context: Context): Boolean {
- val isAirplaneMode by context.settingsGlobalBoolean(Settings.Global.AIRPLANE_MODE_ON)
- return SubscriptionUtil.isSimHardwareVisible(context) &&
- !isAirplaneMode &&
- context.userManager.isAdminUser
- }
+ fun isMobileNetworkSettingsSearchable(context: Context): Boolean =
+ SimRepository(context).canEnterMobileNetworkPage()
fun createSearchItems(context: Context): List =
listOf(
diff --git a/src/com/android/settings/network/telephony/SimRepository.kt b/src/com/android/settings/network/telephony/SimRepository.kt
index ed3c8aa303c..baff5cbe2a3 100644
--- a/src/com/android/settings/network/telephony/SimRepository.kt
+++ b/src/com/android/settings/network/telephony/SimRepository.kt
@@ -18,13 +18,24 @@ package com.android.settings.network.telephony
import android.content.Context
import android.content.pm.PackageManager
+import android.os.UserManager
+import android.provider.Settings
import com.android.settingslib.spaprivileged.framework.common.userManager
+import com.android.settingslib.spaprivileged.settingsprovider.settingsGlobalBoolean
-class SimRepository(context: Context) {
+class SimRepository(private val context: Context) {
private val packageManager = context.packageManager
private val userManager = context.userManager
- /** Gets whether we show mobile network settings page to the current user. */
- fun showMobileNetworkPage(): Boolean =
+ /** Gets whether show mobile network settings page entrance to the current user. */
+ fun showMobileNetworkPageEntrance(): Boolean =
packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY) && userManager.isAdminUser
+
+ /** Gets whether current user can enter mobile network settings page. */
+ fun canEnterMobileNetworkPage(): Boolean {
+ val isAirplaneMode by context.settingsGlobalBoolean(Settings.Global.AIRPLANE_MODE_ON)
+ return showMobileNetworkPageEntrance() &&
+ !isAirplaneMode &&
+ !userManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)
+ }
}
diff --git a/src/com/android/settings/notification/app/NotificationSoundPreference.java b/src/com/android/settings/notification/app/NotificationSoundPreference.java
index b55f9bd7ce8..4084ffe685f 100644
--- a/src/com/android/settings/notification/app/NotificationSoundPreference.java
+++ b/src/com/android/settings/notification/app/NotificationSoundPreference.java
@@ -24,9 +24,8 @@ import android.media.RingtoneManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.util.AttributeSet;
-
import android.util.Log;
-import com.android.settings.R;
+
import com.android.settings.RingtonePreference;
public class NotificationSoundPreference extends RingtonePreference {
@@ -49,6 +48,20 @@ public class NotificationSoundPreference extends RingtonePreference {
updateRingtoneName(mRingtone);
}
+ protected String generateRingtoneTitle(Uri uri) {
+ if (uri == null) {
+ return getContext().getString(com.android.internal.R.string.ringtone_silent);
+ } else if (RingtoneManager.isDefault(uri)) {
+ return getContext().getString(com.android.settings.R.string.notification_sound_default);
+ } else if (ContentResolver.SCHEME_ANDROID_RESOURCE.equals(uri.getScheme())) {
+ return getContext().getString(
+ com.android.settings.R.string.notification_unknown_sound_title);
+ } else {
+ return Ringtone.getTitle(getContext(), uri, false /* followSettingsUri */,
+ true /* allowRemote */);
+ }
+ }
+
@Override
public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
if (data != null) {
@@ -69,16 +82,7 @@ public class NotificationSoundPreference extends RingtonePreference {
AsyncTask ringtoneNameTask = new AsyncTask