Snap for 11270238 from 0612c9b103 to 24Q2-release
Change-Id: I53ef600f3d77b347fac82749c8b95d1f7af54381
This commit is contained in:
@@ -20,3 +20,10 @@ flag {
|
||||
description: "Gates whether to enable LE audio private broadcast sharing via QR code"
|
||||
bug: "308368124"
|
||||
}
|
||||
|
||||
flag {
|
||||
name: "enable_auth_challenge_for_usb_preferences"
|
||||
namespace: "safety_center"
|
||||
description: "Gates whether to require an auth challenge for changing USB preferences"
|
||||
bug: "317367746"
|
||||
}
|
||||
|
||||
@@ -88,6 +88,11 @@
|
||||
<string name="selective_stay_awake_title">Only games, videos, and more</string>
|
||||
<!-- Summary for selective stay awake radio button. [CHAR_LIMIT=NONE] -->
|
||||
<string name="selective_stay_awake_summary">Front display turns on for apps that stop your screen going idle</string>
|
||||
<!-- Title for fold grace period radio button that, on fold, goes to the lockscreen. [CHAR_LIMIT=NONE] -->
|
||||
<string name="stay_awake_on_lockscreen_title">Swipe up to continue</string>
|
||||
<!-- Summary for folding grace period radio button that, on fold, goes to the lockscreen. [CHAR_LIMIT=NONE] -->
|
||||
<string name="stay_awake_on_lockscreen_summary">Fold your phone and swipe up on the front display to continue using the app, or wait a few seconds for the screen to lock</string>
|
||||
|
||||
<!-- Title for sleep on fold radio button. [CHAR_LIMIT=NONE] -->
|
||||
<string name="sleep_on_fold_title">Never</string>
|
||||
<!-- Summary for sleep on fold radio button. [CHAR_LIMIT=NONE] -->
|
||||
@@ -2659,7 +2664,7 @@
|
||||
<string name="display_white_balance_summary"></string>
|
||||
<!-- Display settings screen, setting option name to change Fold setting -->
|
||||
<string name="fold_lock_behavior_title">Continue using apps on fold</string>
|
||||
<!-- Display settings screen, game default frame rate settings title [CHAR LIMIT=30] -->
|
||||
<!-- Display settings screen, game default frame rate settings title [CHAR LIMIT=65] -->
|
||||
<string name="disable_game_default_frame_rate_title">Disable default frame rate for games</string>
|
||||
<!-- Display settings screen, game default frame rate settings summary [CHAR LIMIT=NONE] -->
|
||||
<string name="disable_game_default_frame_rate_summary">Disable limiting the maximum frame rate for games at <xliff:g id="frame_rate" example="60">%1$d</xliff:g> Hz.</string>
|
||||
@@ -8207,6 +8212,9 @@
|
||||
<!-- a11y string -->
|
||||
<string name="clear">Clear</string>
|
||||
|
||||
<!-- a11y string -->
|
||||
<string name="clear_conversation">Clear <xliff:g id="conversation_name" example="Mom">%1$s</xliff:g></string>
|
||||
|
||||
<!-- title for conversation onboarding -->
|
||||
<string name="conversation_onboarding_title">Priority and modified conversations will appear here</string>
|
||||
|
||||
@@ -9494,7 +9502,7 @@
|
||||
other {# apps used memory in the last {time}}
|
||||
}</string>
|
||||
|
||||
<!-- Label for toggle that enables the profiling/aggregating of memory usage [CHAR LIMIT=40]-->
|
||||
<!-- Label for toggle that enables the profiling/aggregating of memory usage [CHAR LIMIT=80]-->
|
||||
<string name="force_enable_pss_profiling_title">Enable memory usage profiling</string>
|
||||
<!-- Description with an explanation of the extra resources used if profiling of memory usage is enabled [CHAR LIMIT=NONE]-->
|
||||
<string name="force_enable_pss_profiling_summary">Memory usage profiling requires additional system resources.</string>
|
||||
|
||||
@@ -23,6 +23,8 @@ import androidx.annotation.UiThread;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settings.flags.Flags;
|
||||
import com.android.settings.wifi.dpp.WifiDppUtils;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
|
||||
/**
|
||||
@@ -61,4 +63,16 @@ public abstract class UsbDetailsController extends AbstractPreferenceController
|
||||
*/
|
||||
@UiThread
|
||||
protected abstract void refresh(boolean connected, long functions, int powerRole, int dataRole);
|
||||
|
||||
/** Protects given action with an auth challenge. */
|
||||
protected final void requireAuthAndExecute(Runnable action) {
|
||||
if (Flags.enableAuthChallengeForUsbPreferences() && !mFragment.isUserAuthenticated()) {
|
||||
WifiDppUtils.showLockScreen(mContext, () -> {
|
||||
mFragment.setUserAuthenticated(true);
|
||||
action.run();
|
||||
});
|
||||
} else {
|
||||
action.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,17 +98,19 @@ public class UsbDetailsDataRoleController extends UsbDetailsController
|
||||
|
||||
@Override
|
||||
public void onRadioButtonClicked(SelectorWithWidgetPreference preference) {
|
||||
int role = UsbBackend.dataRoleFromString(preference.getKey());
|
||||
if (role != mUsbBackend.getDataRole() && mNextRolePref == null
|
||||
&& !Utils.isMonkeyRunning()) {
|
||||
mUsbBackend.setDataRole(role);
|
||||
mNextRolePref = preference;
|
||||
preference.setSummary(R.string.usb_switching);
|
||||
requireAuthAndExecute(() -> {
|
||||
int role = UsbBackend.dataRoleFromString(preference.getKey());
|
||||
if (role != mUsbBackend.getDataRole() && mNextRolePref == null
|
||||
&& !Utils.isMonkeyRunning()) {
|
||||
mUsbBackend.setDataRole(role);
|
||||
mNextRolePref = preference;
|
||||
preference.setSummary(R.string.usb_switching);
|
||||
|
||||
mHandler.postDelayed(mFailureCallback,
|
||||
mUsbBackend.areAllRolesSupported() ? UsbBackend.PD_ROLE_SWAP_TIMEOUT_MS
|
||||
: UsbBackend.NONPD_ROLE_SWAP_TIMEOUT_MS);
|
||||
}
|
||||
mHandler.postDelayed(mFailureCallback,
|
||||
mUsbBackend.areAllRolesSupported() ? UsbBackend.PD_ROLE_SWAP_TIMEOUT_MS
|
||||
: UsbBackend.NONPD_ROLE_SWAP_TIMEOUT_MS);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -45,6 +45,7 @@ public class UsbDetailsFragment extends DashboardFragment {
|
||||
|
||||
private List<UsbDetailsController> mControllers;
|
||||
private UsbBackend mUsbBackend;
|
||||
private boolean mUserAuthenticated = false;
|
||||
|
||||
@VisibleForTesting
|
||||
UsbConnectionBroadcastReceiver mUsbReceiver;
|
||||
@@ -56,6 +57,20 @@ public class UsbDetailsFragment extends DashboardFragment {
|
||||
}
|
||||
};
|
||||
|
||||
boolean isUserAuthenticated() {
|
||||
return mUserAuthenticated;
|
||||
}
|
||||
|
||||
void setUserAuthenticated(boolean userAuthenticated) {
|
||||
mUserAuthenticated = userAuthenticated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
mUserAuthenticated = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
@@ -130,37 +130,39 @@ public class UsbDetailsFunctionsController extends UsbDetailsController
|
||||
|
||||
@Override
|
||||
public void onRadioButtonClicked(SelectorWithWidgetPreference preference) {
|
||||
final long function = UsbBackend.usbFunctionsFromString(preference.getKey());
|
||||
final long previousFunction = mUsbBackend.getCurrentFunctions();
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onRadioButtonClicked() function : " + function + ", toString() : "
|
||||
+ UsbManager.usbFunctionsToString(function) + ", previousFunction : "
|
||||
+ previousFunction + ", toString() : "
|
||||
+ UsbManager.usbFunctionsToString(previousFunction));
|
||||
}
|
||||
if (function != previousFunction && !Utils.isMonkeyRunning()
|
||||
&& !isClickEventIgnored(function, previousFunction)) {
|
||||
mPreviousFunction = previousFunction;
|
||||
|
||||
//Update the UI in advance to make it looks smooth
|
||||
final SelectorWithWidgetPreference prevPref =
|
||||
(SelectorWithWidgetPreference) mProfilesContainer.findPreference(
|
||||
UsbBackend.usbFunctionsToString(mPreviousFunction));
|
||||
if (prevPref != null) {
|
||||
prevPref.setChecked(false);
|
||||
preference.setChecked(true);
|
||||
requireAuthAndExecute(() -> {
|
||||
final long function = UsbBackend.usbFunctionsFromString(preference.getKey());
|
||||
final long previousFunction = mUsbBackend.getCurrentFunctions();
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onRadioButtonClicked() function : " + function + ", toString() : "
|
||||
+ UsbManager.usbFunctionsToString(function) + ", previousFunction : "
|
||||
+ previousFunction + ", toString() : "
|
||||
+ UsbManager.usbFunctionsToString(previousFunction));
|
||||
}
|
||||
if (function != previousFunction && !Utils.isMonkeyRunning()
|
||||
&& !isClickEventIgnored(function, previousFunction)) {
|
||||
mPreviousFunction = previousFunction;
|
||||
|
||||
if (function == UsbManager.FUNCTION_RNDIS || function == UsbManager.FUNCTION_NCM) {
|
||||
// We need to have entitlement check for usb tethering, so use API in
|
||||
// TetheringManager.
|
||||
mTetheringManager.startTethering(
|
||||
TetheringManager.TETHERING_USB, new HandlerExecutor(mHandler),
|
||||
mOnStartTetheringCallback);
|
||||
} else {
|
||||
mUsbBackend.setCurrentFunctions(function);
|
||||
//Update the UI in advance to make it looks smooth
|
||||
final SelectorWithWidgetPreference prevPref =
|
||||
(SelectorWithWidgetPreference) mProfilesContainer.findPreference(
|
||||
UsbBackend.usbFunctionsToString(mPreviousFunction));
|
||||
if (prevPref != null) {
|
||||
prevPref.setChecked(false);
|
||||
preference.setChecked(true);
|
||||
}
|
||||
|
||||
if (function == UsbManager.FUNCTION_RNDIS || function == UsbManager.FUNCTION_NCM) {
|
||||
// We need to have entitlement check for usb tethering, so use API in
|
||||
// TetheringManager.
|
||||
mTetheringManager.startTethering(
|
||||
TetheringManager.TETHERING_USB, new HandlerExecutor(mHandler),
|
||||
mOnStartTetheringCallback);
|
||||
} else {
|
||||
mUsbBackend.setCurrentFunctions(function);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean isClickEventIgnored(long function, long previousFunction) {
|
||||
|
||||
@@ -78,13 +78,15 @@ public class UsbDetailsTranscodeMtpController extends UsbDetailsController
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
SystemProperties.set(TRANSCODE_MTP_SYS_PROP_KEY,
|
||||
Boolean.toString(mSwitchPreference.isChecked()));
|
||||
requireAuthAndExecute(() -> {
|
||||
SystemProperties.set(TRANSCODE_MTP_SYS_PROP_KEY,
|
||||
Boolean.toString(mSwitchPreference.isChecked()));
|
||||
|
||||
final long previousFunctions = mUsbBackend.getCurrentFunctions();
|
||||
// Toggle the MTP connection to reload file sizes for files shared via MTP clients
|
||||
mUsbBackend.setCurrentFunctions(previousFunctions & ~UsbManager.FUNCTION_MTP);
|
||||
mUsbBackend.setCurrentFunctions(previousFunctions);
|
||||
final long previousFunctions = mUsbBackend.getCurrentFunctions();
|
||||
// Toggle the MTP connection to reload file sizes for files shared via MTP clients
|
||||
mUsbBackend.setCurrentFunctions(previousFunctions & ~UsbManager.FUNCTION_MTP);
|
||||
mUsbBackend.setCurrentFunctions(previousFunctions);
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import android.provider.Settings;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.internal.foldables.FoldGracePeriodProvider;
|
||||
import com.android.internal.foldables.FoldLockSettingAvailabilityProvider;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
@@ -58,8 +59,13 @@ public class FoldLockBehaviorPreferenceController extends BasePreferenceControll
|
||||
mFoldLockSettingAvailabilityProvider = foldLockSettingAvailabilityProvider;
|
||||
KEY_TO_TEXT.put(SETTING_VALUE_STAY_AWAKE_ON_FOLD,
|
||||
resourceToString(R.string.stay_awake_on_fold_title));
|
||||
KEY_TO_TEXT.put(SETTING_VALUE_SELECTIVE_STAY_AWAKE,
|
||||
resourceToString(R.string.selective_stay_awake_title));
|
||||
if (new FoldGracePeriodProvider().isEnabled()) {
|
||||
KEY_TO_TEXT.put(SETTING_VALUE_SELECTIVE_STAY_AWAKE,
|
||||
resourceToString(R.string.stay_awake_on_lockscreen_title));
|
||||
} else {
|
||||
KEY_TO_TEXT.put(SETTING_VALUE_SELECTIVE_STAY_AWAKE,
|
||||
resourceToString(R.string.selective_stay_awake_title));
|
||||
}
|
||||
KEY_TO_TEXT.put(SETTING_VALUE_SLEEP_ON_FOLD,
|
||||
resourceToString(R.string.sleep_on_fold_title));
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.foldables.FoldGracePeriodProvider;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.support.actionbar.HelpResourceProvider;
|
||||
import com.android.settings.utils.CandidateInfoExtra;
|
||||
@@ -54,6 +55,7 @@ public class FoldLockBehaviorSettings extends RadioButtonPickerFragment implemen
|
||||
SETTING_VALUE_SLEEP_ON_FOLD));
|
||||
private static final String SETTING_VALUE_DEFAULT = SETTING_VALUE_SELECTIVE_STAY_AWAKE;
|
||||
private Context mContext;
|
||||
private final FoldGracePeriodProvider mFoldGracePeriodProvider = new FoldGracePeriodProvider();
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
@@ -69,10 +71,17 @@ public class FoldLockBehaviorSettings extends RadioButtonPickerFragment implemen
|
||||
resourceToString(R.string.stay_awake_on_fold_title),
|
||||
resourceToString(R.string.stay_awake_on_fold_summary),
|
||||
SETTING_VALUE_STAY_AWAKE_ON_FOLD, /* enabled */ true));
|
||||
candidates.add(new CandidateInfoExtra(
|
||||
resourceToString(R.string.selective_stay_awake_title),
|
||||
resourceToString(R.string.selective_stay_awake_summary),
|
||||
SETTING_VALUE_SELECTIVE_STAY_AWAKE, /* enabled */ true));
|
||||
if (mFoldGracePeriodProvider.isEnabled()) {
|
||||
candidates.add(new CandidateInfoExtra(
|
||||
resourceToString(R.string.stay_awake_on_lockscreen_title),
|
||||
resourceToString(R.string.stay_awake_on_lockscreen_summary),
|
||||
SETTING_VALUE_SELECTIVE_STAY_AWAKE, /* enabled */ true));
|
||||
} else {
|
||||
candidates.add(new CandidateInfoExtra(
|
||||
resourceToString(R.string.selective_stay_awake_title),
|
||||
resourceToString(R.string.selective_stay_awake_summary),
|
||||
SETTING_VALUE_SELECTIVE_STAY_AWAKE, /* enabled */ true));
|
||||
}
|
||||
candidates.add(new CandidateInfoExtra(
|
||||
resourceToString(R.string.sleep_on_fold_title),
|
||||
resourceToString(R.string.sleep_on_fold_summary),
|
||||
|
||||
@@ -83,17 +83,8 @@ public class BatteryDefenderTip extends BatteryTip {
|
||||
}
|
||||
|
||||
cardPreference.setSelectable(false);
|
||||
cardPreference.setPrimaryButtonText(
|
||||
context.getString(R.string.battery_tip_charge_to_full_button));
|
||||
cardPreference.setPrimaryButtonText(context.getString(R.string.learn_more));
|
||||
cardPreference.setPrimaryButtonClickListener(
|
||||
unused -> {
|
||||
resumeCharging(context);
|
||||
preference.setVisible(false);
|
||||
});
|
||||
cardPreference.setPrimaryButtonVisible(mIsPluggedIn);
|
||||
|
||||
cardPreference.setSecondaryButtonText(context.getString(R.string.learn_more));
|
||||
cardPreference.setSecondaryButtonClickListener(
|
||||
button ->
|
||||
button.startActivityForResult(
|
||||
HelpUtils.getHelpIntent(
|
||||
@@ -101,10 +92,19 @@ public class BatteryDefenderTip extends BatteryTip {
|
||||
context.getString(R.string.help_url_battery_defender),
|
||||
/* backupContext */ ""), /* requestCode */
|
||||
0));
|
||||
cardPreference.setSecondaryButtonVisible(true);
|
||||
cardPreference.setSecondaryButtonContentDescription(
|
||||
cardPreference.setPrimaryButtonVisible(true);
|
||||
cardPreference.setPrimaryButtonContentDescription(
|
||||
context.getString(
|
||||
R.string.battery_tip_limited_temporarily_sec_button_content_description));
|
||||
|
||||
cardPreference.setSecondaryButtonText(
|
||||
context.getString(R.string.battery_tip_charge_to_full_button));
|
||||
cardPreference.setSecondaryButtonClickListener(
|
||||
unused -> {
|
||||
resumeCharging(context);
|
||||
preference.setVisible(false);
|
||||
});
|
||||
cardPreference.setSecondaryButtonVisible(mIsPluggedIn);
|
||||
}
|
||||
|
||||
private void resumeCharging(Context context) {
|
||||
|
||||
@@ -26,7 +26,6 @@ import android.util.Log;
|
||||
import com.android.settings.core.instrumentation.ElapsedTimeUtils;
|
||||
import com.android.settings.fuelgauge.BatteryUsageHistoricalLogEntry.Action;
|
||||
import com.android.settings.fuelgauge.batteryusage.bugreport.BatteryUsageLogUtils;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settingslib.fuelgauge.BatteryUtils;
|
||||
|
||||
import java.time.Duration;
|
||||
@@ -34,9 +33,7 @@ import java.time.Duration;
|
||||
/** Receives broadcasts to start or stop the periodic fetching job. */
|
||||
public final class BootBroadcastReceiver extends BroadcastReceiver {
|
||||
private static final String TAG = "BootBroadcastReceiver";
|
||||
private static final long RESCHEDULE_FOR_BOOT_ACTION_WITH_DELAY =
|
||||
Duration.ofMinutes(40).toMillis();
|
||||
private static final long RESCHEDULE_FOR_BOOT_ACTION_WITHOUT_DELAY =
|
||||
private static final long RESCHEDULE_FOR_BOOT_ACTION_DELAY_MILLIS =
|
||||
Duration.ofSeconds(6).toMillis();
|
||||
|
||||
private final Handler mHandler = new Handler(Looper.getMainLooper());
|
||||
@@ -81,7 +78,7 @@ public final class BootBroadcastReceiver extends BroadcastReceiver {
|
||||
if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
|
||||
final Intent recheckIntent = new Intent(ACTION_PERIODIC_JOB_RECHECK);
|
||||
recheckIntent.setClass(context, BootBroadcastReceiver.class);
|
||||
final long delayedTime = getRescheduleTimeForBootAction(context);
|
||||
final long delayedTime = RESCHEDULE_FOR_BOOT_ACTION_DELAY_MILLIS;
|
||||
mHandler.postDelayed(() -> context.sendBroadcast(recheckIntent), delayedTime);
|
||||
|
||||
// Refreshes the usage source from UsageStatsManager when booting.
|
||||
@@ -93,16 +90,6 @@ public final class BootBroadcastReceiver extends BroadcastReceiver {
|
||||
}
|
||||
}
|
||||
|
||||
private long getRescheduleTimeForBootAction(Context context) {
|
||||
final boolean delayHourlyJobWhenBooting =
|
||||
FeatureFactory.getFeatureFactory()
|
||||
.getPowerUsageFeatureProvider()
|
||||
.delayHourlyJobWhenBooting();
|
||||
return delayHourlyJobWhenBooting
|
||||
? RESCHEDULE_FOR_BOOT_ACTION_WITH_DELAY
|
||||
: RESCHEDULE_FOR_BOOT_ACTION_WITHOUT_DELAY;
|
||||
}
|
||||
|
||||
private static void refreshJobs(Context context) {
|
||||
PeriodicJobManager.getInstance(context).refreshJob(/* fromBoot= */ true);
|
||||
}
|
||||
|
||||
@@ -158,13 +158,14 @@ public class AppLocalePickerActivity extends SettingsBaseActivity
|
||||
|
||||
private void broadcastAppLocaleChange(LocaleStore.LocaleInfo localeInfo) {
|
||||
if (!localeNotificationEnabled()) {
|
||||
Log.w(TAG, "Locale notification is not enabled");
|
||||
return;
|
||||
}
|
||||
String localeTag = localeInfo.getLocale().toLanguageTag();
|
||||
if (LocaleUtils.isInSystemLocale(localeTag) || localeInfo.isAppCurrentLocale()) {
|
||||
if (localeInfo.isAppCurrentLocale()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
String localeTag = localeInfo.getLocale().toLanguageTag();
|
||||
int uid = getPackageManager().getApplicationInfo(mPackageName,
|
||||
PackageManager.GET_META_DATA).uid;
|
||||
boolean launchNotification = mNotificationController.shouldTriggerNotification(
|
||||
|
||||
@@ -270,12 +270,14 @@ class LocaleDragAndDropAdapter
|
||||
void removeChecked() {
|
||||
int itemCount = mFeedItemList.size();
|
||||
LocaleStore.LocaleInfo localeInfo;
|
||||
NotificationController controller = NotificationController.getInstance(mContext);
|
||||
for (int i = itemCount - 1; i >= 0; i--) {
|
||||
localeInfo = mFeedItemList.get(i);
|
||||
if (localeInfo.getChecked()) {
|
||||
FeatureFactory.getFeatureFactory().getMetricsFeatureProvider()
|
||||
.action(mContext, SettingsEnums.ACTION_REMOVE_LANGUAGE);
|
||||
mFeedItemList.remove(i);
|
||||
controller.removeNotificationInfo(localeInfo.getLocale().toLanguageTag());
|
||||
}
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
|
||||
@@ -62,6 +62,17 @@ public class LocaleNotificationDataManager {
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes one entry with the corresponding locale from the {@link SharedPreferences}.
|
||||
*
|
||||
* @param locale A locale which the application sets to
|
||||
*/
|
||||
public void removeNotificationInfo(String locale) {
|
||||
SharedPreferences.Editor editor = getSharedPreferences(mContext).edit();
|
||||
editor.remove(locale);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link NotificationInfo} with the associated locale from the
|
||||
* {@link SharedPreferences}.
|
||||
|
||||
@@ -110,6 +110,15 @@ public class NotificationController {
|
||||
return (info != null) ? info.getNotificationId() : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the {@link NotificationInfo} with the corresponding locale
|
||||
*
|
||||
* @param locale The locale which the application sets to
|
||||
*/
|
||||
public void removeNotificationInfo(@NonNull String locale) {
|
||||
mDataManager.removeNotificationInfo(locale);
|
||||
}
|
||||
|
||||
private boolean updateLocaleNotificationInfo(int uid, String locale) {
|
||||
NotificationInfo info = mDataManager.getNotificationInfo(locale);
|
||||
if (info == null) {
|
||||
@@ -135,20 +144,20 @@ public class NotificationController {
|
||||
int notificationCount = info.getNotificationCount();
|
||||
long lastNotificationTime = info.getLastNotificationTimeMs();
|
||||
int notificationId = info.getNotificationId();
|
||||
|
||||
// Add the uid into the locale's uid list
|
||||
uidSet.add(uid);
|
||||
if (dismissCount < DISMISS_COUNT_THRESHOLD
|
||||
&& notificationCount < NOTIFICATION_COUNT_THRESHOLD
|
||||
// Notification should fire on multiples of 2 apps using the locale.
|
||||
&& uidSet.size() % MULTIPLE_BASE == 0
|
||||
&& !isNotificationFrequent(lastNotificationTime)) {
|
||||
// Increment the count because the notification can be triggered.
|
||||
notificationCount = info.getNotificationCount() + 1;
|
||||
lastNotificationTime = Calendar.getInstance().getTimeInMillis();
|
||||
Log.i(TAG, "notificationCount:" + notificationCount);
|
||||
if (notificationCount == 1) {
|
||||
notificationId = (int) SystemClock.uptimeMillis();
|
||||
&& notificationCount < NOTIFICATION_COUNT_THRESHOLD) {
|
||||
// Add the uid into the locale's uid list
|
||||
uidSet.add(uid);
|
||||
// Notification should fire on multiples of 2 apps using the locale.
|
||||
if (uidSet.size() % MULTIPLE_BASE == 0
|
||||
&& !isNotificationFrequent(lastNotificationTime)) {
|
||||
// Increment the count because the notification can be triggered.
|
||||
notificationCount = info.getNotificationCount() + 1;
|
||||
lastNotificationTime = Calendar.getInstance().getTimeInMillis();
|
||||
Log.i(TAG, "notificationCount:" + notificationCount);
|
||||
if (notificationCount == 1) {
|
||||
notificationId = (int) SystemClock.uptimeMillis();
|
||||
}
|
||||
}
|
||||
}
|
||||
return new NotificationInfo(uidSet, notificationCount, dismissCount, lastNotificationTime,
|
||||
|
||||
@@ -1,219 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.network.telephony;
|
||||
|
||||
import android.telephony.CellIdentity;
|
||||
import android.telephony.CellIdentityGsm;
|
||||
import android.telephony.CellIdentityLte;
|
||||
import android.telephony.CellIdentityNr;
|
||||
import android.telephony.CellIdentityTdscdma;
|
||||
import android.telephony.CellIdentityWcdma;
|
||||
import android.telephony.CellInfo;
|
||||
import android.telephony.CellInfoCdma;
|
||||
import android.telephony.CellInfoGsm;
|
||||
import android.telephony.CellInfoLte;
|
||||
import android.telephony.CellInfoNr;
|
||||
import android.telephony.CellInfoTdscdma;
|
||||
import android.telephony.CellInfoWcdma;
|
||||
import android.text.BidiFormatter;
|
||||
import android.text.TextDirectionHeuristics;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.internal.telephony.OperatorInfo;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Add static Utility functions to get information from the CellInfo object.
|
||||
* TODO: Modify {@link CellInfo} for simplify those functions
|
||||
*/
|
||||
public final class CellInfoUtil {
|
||||
private static final String TAG = "NetworkSelectSetting";
|
||||
|
||||
private CellInfoUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the title of the network obtained in the manual search.
|
||||
*
|
||||
* @param cellId contains the identity of the network.
|
||||
* @param networkMccMnc contains the MCCMNC string of the network
|
||||
* @return Long Name if not null/empty, otherwise Short Name if not null/empty,
|
||||
* else MCCMNC string.
|
||||
*/
|
||||
public static String getNetworkTitle(CellIdentity cellId, String networkMccMnc) {
|
||||
if (cellId != null) {
|
||||
String title = Objects.toString(cellId.getOperatorAlphaLong(), "");
|
||||
if (TextUtils.isEmpty(title)) {
|
||||
title = Objects.toString(cellId.getOperatorAlphaShort(), "");
|
||||
}
|
||||
if (!TextUtils.isEmpty(title)) {
|
||||
return title;
|
||||
}
|
||||
}
|
||||
if (TextUtils.isEmpty(networkMccMnc)) {
|
||||
return "";
|
||||
}
|
||||
final BidiFormatter bidiFormatter = BidiFormatter.getInstance();
|
||||
return bidiFormatter.unicodeWrap(networkMccMnc, TextDirectionHeuristics.LTR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the CellIdentity from CellInfo
|
||||
*
|
||||
* @param cellInfo contains the information of the network.
|
||||
* @return CellIdentity within CellInfo
|
||||
*/
|
||||
public static CellIdentity getCellIdentity(CellInfo cellInfo) {
|
||||
if (cellInfo == null) {
|
||||
return null;
|
||||
}
|
||||
CellIdentity cellId = null;
|
||||
if (cellInfo instanceof CellInfoGsm) {
|
||||
cellId = ((CellInfoGsm) cellInfo).getCellIdentity();
|
||||
} else if (cellInfo instanceof CellInfoCdma) {
|
||||
cellId = ((CellInfoCdma) cellInfo).getCellIdentity();
|
||||
} else if (cellInfo instanceof CellInfoWcdma) {
|
||||
cellId = ((CellInfoWcdma) cellInfo).getCellIdentity();
|
||||
} else if (cellInfo instanceof CellInfoTdscdma) {
|
||||
cellId = ((CellInfoTdscdma) cellInfo).getCellIdentity();
|
||||
} else if (cellInfo instanceof CellInfoLte) {
|
||||
cellId = ((CellInfoLte) cellInfo).getCellIdentity();
|
||||
} else if (cellInfo instanceof CellInfoNr) {
|
||||
cellId = ((CellInfoNr) cellInfo).getCellIdentity();
|
||||
}
|
||||
return cellId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a CellInfo object from OperatorInfo. GsmCellInfo is used here only because
|
||||
* operatorInfo does not contain technology type while CellInfo is an abstract object that
|
||||
* requires to specify technology type. It doesn't matter which CellInfo type to use here, since
|
||||
* we only want to wrap the operator info and PLMN to a CellInfo object.
|
||||
*/
|
||||
public static CellInfo convertOperatorInfoToCellInfo(OperatorInfo operatorInfo) {
|
||||
final String operatorNumeric = operatorInfo.getOperatorNumeric();
|
||||
String mcc = null;
|
||||
String mnc = null;
|
||||
if (operatorNumeric != null && operatorNumeric.matches("^[0-9]{5,6}$")) {
|
||||
mcc = operatorNumeric.substring(0, 3);
|
||||
mnc = operatorNumeric.substring(3);
|
||||
}
|
||||
final CellIdentityGsm cig = new CellIdentityGsm(
|
||||
Integer.MAX_VALUE /* lac */,
|
||||
Integer.MAX_VALUE /* cid */,
|
||||
Integer.MAX_VALUE /* arfcn */,
|
||||
Integer.MAX_VALUE /* bsic */,
|
||||
mcc,
|
||||
mnc,
|
||||
operatorInfo.getOperatorAlphaLong(),
|
||||
operatorInfo.getOperatorAlphaShort(),
|
||||
Collections.emptyList());
|
||||
|
||||
final CellInfoGsm ci = new CellInfoGsm();
|
||||
ci.setCellIdentity(cig);
|
||||
return ci;
|
||||
}
|
||||
|
||||
/** Convert a list of cellInfos to readable string without sensitive info. */
|
||||
public static String cellInfoListToString(List<CellInfo> cellInfos) {
|
||||
return cellInfos.stream()
|
||||
.map(cellInfo -> cellInfoToString(cellInfo))
|
||||
.collect(Collectors.joining(", "));
|
||||
}
|
||||
|
||||
/** Convert {@code cellInfo} to a readable string without sensitive info. */
|
||||
public static String cellInfoToString(CellInfo cellInfo) {
|
||||
final String cellType = cellInfo.getClass().getSimpleName();
|
||||
final CellIdentity cid = getCellIdentity(cellInfo);
|
||||
String mcc = getCellIdentityMcc(cid);
|
||||
String mnc = getCellIdentityMnc(cid);
|
||||
CharSequence alphaLong = null;
|
||||
CharSequence alphaShort = null;
|
||||
if (cid != null) {
|
||||
alphaLong = cid.getOperatorAlphaLong();
|
||||
alphaShort = cid.getOperatorAlphaShort();
|
||||
}
|
||||
return String.format(
|
||||
"{CellType = %s, isRegistered = %b, mcc = %s, mnc = %s, alphaL = %s, alphaS = %s}",
|
||||
cellType, cellInfo.isRegistered(), mcc, mnc,
|
||||
alphaLong, alphaShort);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the MccMnc.
|
||||
*
|
||||
* @param cid contains the identity of the network.
|
||||
* @return MccMnc string.
|
||||
*/
|
||||
public static String getCellIdentityMccMnc(CellIdentity cid) {
|
||||
String mcc = getCellIdentityMcc(cid);
|
||||
String mnc = getCellIdentityMnc(cid);
|
||||
return (mcc == null || mnc == null) ? null : mcc + mnc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Mcc.
|
||||
*
|
||||
* @param cid contains the identity of the network.
|
||||
* @return Mcc string.
|
||||
*/
|
||||
public static String getCellIdentityMcc(CellIdentity cid) {
|
||||
String mcc = null;
|
||||
if (cid != null) {
|
||||
if (cid instanceof CellIdentityGsm) {
|
||||
mcc = ((CellIdentityGsm) cid).getMccString();
|
||||
} else if (cid instanceof CellIdentityWcdma) {
|
||||
mcc = ((CellIdentityWcdma) cid).getMccString();
|
||||
} else if (cid instanceof CellIdentityTdscdma) {
|
||||
mcc = ((CellIdentityTdscdma) cid).getMccString();
|
||||
} else if (cid instanceof CellIdentityLte) {
|
||||
mcc = ((CellIdentityLte) cid).getMccString();
|
||||
} else if (cid instanceof CellIdentityNr) {
|
||||
mcc = ((CellIdentityNr) cid).getMccString();
|
||||
}
|
||||
}
|
||||
return (mcc == null) ? null : mcc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Mnc.
|
||||
*
|
||||
* @param cid contains the identity of the network.
|
||||
* @return Mcc string.
|
||||
*/
|
||||
public static String getCellIdentityMnc(CellIdentity cid) {
|
||||
String mnc = null;
|
||||
if (cid != null) {
|
||||
if (cid instanceof CellIdentityGsm) {
|
||||
mnc = ((CellIdentityGsm) cid).getMncString();
|
||||
} else if (cid instanceof CellIdentityWcdma) {
|
||||
mnc = ((CellIdentityWcdma) cid).getMncString();
|
||||
} else if (cid instanceof CellIdentityTdscdma) {
|
||||
mnc = ((CellIdentityTdscdma) cid).getMncString();
|
||||
} else if (cid instanceof CellIdentityLte) {
|
||||
mnc = ((CellIdentityLte) cid).getMncString();
|
||||
} else if (cid instanceof CellIdentityNr) {
|
||||
mnc = ((CellIdentityNr) cid).getMncString();
|
||||
}
|
||||
}
|
||||
return (mnc == null) ? null : mnc;
|
||||
}
|
||||
}
|
||||
113
src/com/android/settings/network/telephony/CellInfoUtil.kt
Normal file
113
src/com/android/settings/network/telephony/CellInfoUtil.kt
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* 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.network.telephony
|
||||
|
||||
import android.telephony.CellIdentity
|
||||
import android.telephony.CellIdentityGsm
|
||||
import android.telephony.CellInfo
|
||||
import android.telephony.CellInfoGsm
|
||||
import android.text.BidiFormatter
|
||||
import android.text.TextDirectionHeuristics
|
||||
import com.android.internal.telephony.OperatorInfo
|
||||
|
||||
/**
|
||||
* Add static Utility functions to get information from the CellInfo object.
|
||||
* TODO: Modify [CellInfo] for simplify those functions
|
||||
*/
|
||||
object CellInfoUtil {
|
||||
|
||||
/**
|
||||
* Returns the title of the network obtained in the manual search.
|
||||
*
|
||||
* By the following order,
|
||||
* 1. Long Name if not null/empty
|
||||
* 2. Short Name if not null/empty
|
||||
* 3. OperatorNumeric (MCCMNC) string
|
||||
*/
|
||||
@JvmStatic
|
||||
fun CellIdentity.getNetworkTitle(): String? {
|
||||
operatorAlphaLong?.takeIf { it.isNotBlank() }?.let { return it.toString() }
|
||||
operatorAlphaShort?.takeIf { it.isNotBlank() }?.let { return it.toString() }
|
||||
val operatorNumeric = getOperatorNumeric() ?: return null
|
||||
val bidiFormatter = BidiFormatter.getInstance()
|
||||
return bidiFormatter.unicodeWrap(operatorNumeric, TextDirectionHeuristics.LTR)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a CellInfo object from OperatorInfo. GsmCellInfo is used here only because
|
||||
* operatorInfo does not contain technology type while CellInfo is an abstract object that
|
||||
* requires to specify technology type. It doesn't matter which CellInfo type to use here, since
|
||||
* we only want to wrap the operator info and PLMN to a CellInfo object.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun convertOperatorInfoToCellInfo(operatorInfo: OperatorInfo): CellInfo {
|
||||
val operatorNumeric = operatorInfo.operatorNumeric
|
||||
var mcc: String? = null
|
||||
var mnc: String? = null
|
||||
if (operatorNumeric?.matches("^[0-9]{5,6}$".toRegex()) == true) {
|
||||
mcc = operatorNumeric.substring(0, 3)
|
||||
mnc = operatorNumeric.substring(3)
|
||||
}
|
||||
return CellInfoGsm().apply {
|
||||
cellIdentity = CellIdentityGsm(
|
||||
/* lac = */ Int.MAX_VALUE,
|
||||
/* cid = */ Int.MAX_VALUE,
|
||||
/* arfcn = */ Int.MAX_VALUE,
|
||||
/* bsic = */ Int.MAX_VALUE,
|
||||
/* mccStr = */ mcc,
|
||||
/* mncStr = */ mnc,
|
||||
/* alphal = */ operatorInfo.operatorAlphaLong,
|
||||
/* alphas = */ operatorInfo.operatorAlphaShort,
|
||||
/* additionalPlmns = */ emptyList(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a list of cellInfos to readable string without sensitive info.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun cellInfoListToString(cellInfos: List<CellInfo>): String =
|
||||
cellInfos.joinToString { cellInfo -> cellInfo.readableString() }
|
||||
|
||||
/**
|
||||
* Convert [CellInfo] to a readable string without sensitive info.
|
||||
*/
|
||||
private fun CellInfo.readableString(): String = buildString {
|
||||
append("{CellType = ${this@readableString::class.simpleName}, ")
|
||||
append("isRegistered = $isRegistered, ")
|
||||
append(cellIdentity.readableString())
|
||||
append("}")
|
||||
}
|
||||
|
||||
private fun CellIdentity.readableString(): String = buildString {
|
||||
append("mcc = $mccString, ")
|
||||
append("mnc = $mncString, ")
|
||||
append("alphaL = $operatorAlphaLong, ")
|
||||
append("alphaS = $operatorAlphaShort")
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the MccMnc.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun CellIdentity.getOperatorNumeric(): String? {
|
||||
val mcc = mccString
|
||||
val mnc = mncString
|
||||
return if (mcc == null || mnc == null) null else mcc + mnc
|
||||
}
|
||||
}
|
||||
@@ -18,14 +18,11 @@ package com.android.settings.network.telephony;
|
||||
|
||||
import static android.telephony.SignalStrength.NUM_SIGNAL_STRENGTH_BINS;
|
||||
|
||||
import static com.android.settings.network.telephony.CellInfoUtil.getOperatorNumeric;
|
||||
|
||||
import android.content.Context;
|
||||
import android.telephony.AccessNetworkConstants.AccessNetworkType;
|
||||
import android.telephony.CellIdentity;
|
||||
import android.telephony.CellIdentityGsm;
|
||||
import android.telephony.CellIdentityLte;
|
||||
import android.telephony.CellIdentityNr;
|
||||
import android.telephony.CellIdentityTdscdma;
|
||||
import android.telephony.CellIdentityWcdma;
|
||||
import android.telephony.CellInfo;
|
||||
import android.telephony.CellInfoCdma;
|
||||
import android.telephony.CellInfoGsm;
|
||||
@@ -36,6 +33,7 @@ import android.telephony.CellInfoWcdma;
|
||||
import android.telephony.CellSignalStrength;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
@@ -87,7 +85,7 @@ public class NetworkOperatorPreference extends Preference {
|
||||
* Change cell information
|
||||
*/
|
||||
public void updateCell(CellInfo cellinfo) {
|
||||
updateCell(cellinfo, CellInfoUtil.getCellIdentity(cellinfo));
|
||||
updateCell(cellinfo, cellinfo.getCellIdentity());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -104,14 +102,14 @@ public class NetworkOperatorPreference extends Preference {
|
||||
if (cellinfo == null) {
|
||||
return false;
|
||||
}
|
||||
return mCellId.equals(CellInfoUtil.getCellIdentity(cellinfo));
|
||||
return mCellId.equals(cellinfo.getCellIdentity());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true when this preference is for forbidden network
|
||||
*/
|
||||
public boolean isForbiddenNetwork() {
|
||||
return ((mForbiddenPlmns != null) && mForbiddenPlmns.contains(getOperatorNumeric()));
|
||||
return ((mForbiddenPlmns != null) && mForbiddenPlmns.contains(getOperatorNumeric(mCellId)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -147,41 +145,12 @@ public class NetworkOperatorPreference extends Preference {
|
||||
updateIcon(level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Operator numeric of this cell
|
||||
*/
|
||||
public String getOperatorNumeric() {
|
||||
final CellIdentity cellId = mCellId;
|
||||
if (cellId == null) {
|
||||
return null;
|
||||
}
|
||||
if (cellId instanceof CellIdentityGsm) {
|
||||
return ((CellIdentityGsm) cellId).getMobileNetworkOperator();
|
||||
}
|
||||
if (cellId instanceof CellIdentityWcdma) {
|
||||
return ((CellIdentityWcdma) cellId).getMobileNetworkOperator();
|
||||
}
|
||||
if (cellId instanceof CellIdentityTdscdma) {
|
||||
return ((CellIdentityTdscdma) cellId).getMobileNetworkOperator();
|
||||
}
|
||||
if (cellId instanceof CellIdentityLte) {
|
||||
return ((CellIdentityLte) cellId).getMobileNetworkOperator();
|
||||
}
|
||||
if (cellId instanceof CellIdentityNr) {
|
||||
final String mcc = ((CellIdentityNr) cellId).getMccString();
|
||||
if (mcc == null) {
|
||||
return null;
|
||||
}
|
||||
return mcc.concat(((CellIdentityNr) cellId).getMncString());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Operator name of this cell
|
||||
*/
|
||||
@Nullable
|
||||
public String getOperatorName() {
|
||||
return CellInfoUtil.getNetworkTitle(mCellId, getOperatorNumeric());
|
||||
return CellInfoUtil.getNetworkTitle(mCellId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -190,7 +159,7 @@ public class NetworkOperatorPreference extends Preference {
|
||||
public OperatorInfo getOperatorInfo() {
|
||||
return new OperatorInfo(Objects.toString(mCellId.getOperatorAlphaLong(), ""),
|
||||
Objects.toString(mCellId.getOperatorAlphaShort(), ""),
|
||||
getOperatorNumeric(), getAccessNetworkTypeFromCellInfo(mCellInfo));
|
||||
getOperatorNumeric(mCellId), getAccessNetworkTypeFromCellInfo(mCellInfo));
|
||||
}
|
||||
|
||||
private int getIconIdForCell(CellInfo ci) {
|
||||
|
||||
@@ -365,14 +365,12 @@ public class NetworkSelectSettings extends DashboardFragment {
|
||||
}
|
||||
ArrayList<CellInfo> aggregatedList = new ArrayList<>();
|
||||
for (CellInfo cellInfo : cellInfoListInput) {
|
||||
String plmn = CellInfoUtil.getNetworkTitle(cellInfo.getCellIdentity(),
|
||||
CellInfoUtil.getCellIdentityMccMnc(cellInfo.getCellIdentity()));
|
||||
String plmn = CellInfoUtil.getNetworkTitle(cellInfo.getCellIdentity());
|
||||
Class className = cellInfo.getClass();
|
||||
|
||||
Optional<CellInfo> itemInTheList = aggregatedList.stream().filter(
|
||||
item -> {
|
||||
String itemPlmn = CellInfoUtil.getNetworkTitle(item.getCellIdentity(),
|
||||
CellInfoUtil.getCellIdentityMccMnc(item.getCellIdentity()));
|
||||
String itemPlmn = CellInfoUtil.getNetworkTitle(item.getCellIdentity());
|
||||
return itemPlmn.equals(plmn) && item.getClass().equals(className);
|
||||
})
|
||||
.findFirst();
|
||||
|
||||
@@ -28,7 +28,7 @@ import com.google.common.annotations.VisibleForTesting;
|
||||
public class RecentConversationPreference extends TwoTargetPreference {
|
||||
|
||||
private OnClearClickListener mOnClearClickListener;
|
||||
|
||||
private final Context mContext;
|
||||
private View mClearView;
|
||||
|
||||
public interface OnClearClickListener {
|
||||
@@ -37,6 +37,7 @@ public class RecentConversationPreference extends TwoTargetPreference {
|
||||
|
||||
public RecentConversationPreference(Context context) {
|
||||
super(context);
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
public void setOnClearClickListener(
|
||||
@@ -70,6 +71,9 @@ public class RecentConversationPreference extends TwoTargetPreference {
|
||||
final View widgetFrame = view.findViewById(android.R.id.widget_frame);
|
||||
widgetFrame.setVisibility(mOnClearClickListener != null ? View.VISIBLE : View.GONE);
|
||||
mClearView = view.findViewById(getClearId());
|
||||
mClearView.setContentDescription(
|
||||
mContext.getString(R.string.clear_conversation, getTitle()));
|
||||
|
||||
mClearView.setOnClickListener(v -> {
|
||||
if (mOnClearClickListener != null) {
|
||||
mOnClearClickListener.onClear();
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* 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.usb;
|
||||
|
||||
import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.app.KeyguardManager;
|
||||
import android.content.Context;
|
||||
import android.hardware.usb.UsbPortStatus;
|
||||
import android.platform.test.annotations.RequiresFlagsEnabled;
|
||||
import android.platform.test.flag.junit.CheckFlagsRule;
|
||||
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
|
||||
|
||||
import com.android.settings.flags.Flags;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.Shadows;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowKeyguardManager;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {
|
||||
ShadowKeyguardManager.class
|
||||
})
|
||||
public class UsbDetailsControllerTest {
|
||||
|
||||
@Rule
|
||||
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
|
||||
|
||||
@Mock
|
||||
private UsbBackend mUsbBackend;
|
||||
|
||||
private Context mContext;
|
||||
private UsbDetailsController mUsbDetailsController;
|
||||
private UsbDetailsFragment mUsbDetailsFragment;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = getApplicationContext();
|
||||
mUsbDetailsFragment = new UsbDetailsFragment();
|
||||
mUsbDetailsController = new UsbDetailsController(
|
||||
mContext, mUsbDetailsFragment, mUsbBackend) {
|
||||
@Override
|
||||
protected void refresh(boolean connected, long functions, int powerRole, int dataRole) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_returnsTrue() {
|
||||
assertThat(mUsbDetailsController.isAvailable()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresFlagsEnabled(Flags.FLAG_ENABLE_AUTH_CHALLENGE_FOR_USB_PREFERENCES)
|
||||
public void requireAuthAndExecute_whenAlreadyAuthenticated_executes() {
|
||||
mUsbDetailsFragment.setUserAuthenticated(true);
|
||||
Runnable action = () -> mUsbBackend.setDataRole(UsbPortStatus.DATA_ROLE_HOST);
|
||||
|
||||
mUsbDetailsController.requireAuthAndExecute(action);
|
||||
|
||||
verify(mUsbBackend).setDataRole(anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresFlagsEnabled(Flags.FLAG_ENABLE_AUTH_CHALLENGE_FOR_USB_PREFERENCES)
|
||||
public void requireAuthAndExecute_authenticatesAndExecutes() {
|
||||
mUsbDetailsFragment.setUserAuthenticated(false);
|
||||
setAuthPassesAutomatically();
|
||||
Runnable action = () -> mUsbBackend.setDataRole(UsbPortStatus.DATA_ROLE_HOST);
|
||||
|
||||
mUsbDetailsController.requireAuthAndExecute(action);
|
||||
|
||||
assertThat(mUsbDetailsFragment.isUserAuthenticated()).isTrue();
|
||||
verify(mUsbBackend).setDataRole(anyInt());
|
||||
}
|
||||
|
||||
private void setAuthPassesAutomatically() {
|
||||
Shadows.shadowOf(mContext.getSystemService(KeyguardManager.class))
|
||||
.setIsKeyguardSecure(false);
|
||||
}
|
||||
}
|
||||
@@ -25,12 +25,15 @@ import static android.hardware.usb.UsbPortStatus.POWER_ROLE_SINK;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.KeyguardManager;
|
||||
import android.content.Context;
|
||||
import android.hardware.usb.UsbManager;
|
||||
import android.os.Handler;
|
||||
import android.platform.test.annotations.RequiresFlagsEnabled;
|
||||
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.preference.PreferenceCategory;
|
||||
@@ -38,6 +41,7 @@ import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.flags.Flags;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.widget.SelectorWithWidgetPreference;
|
||||
|
||||
@@ -49,6 +53,7 @@ import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.Shadows;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@@ -63,12 +68,11 @@ public class UsbDetailsDataRoleControllerTest {
|
||||
private PreferenceCategory mPreference;
|
||||
private PreferenceManager mPreferenceManager;
|
||||
private PreferenceScreen mScreen;
|
||||
private UsbDetailsFragment mFragment;
|
||||
|
||||
@Mock
|
||||
private UsbBackend mUsbBackend;
|
||||
@Mock
|
||||
private UsbDetailsFragment mFragment;
|
||||
@Mock
|
||||
private FragmentActivity mActivity;
|
||||
@Mock
|
||||
private Handler mHandler;
|
||||
@@ -76,7 +80,7 @@ public class UsbDetailsDataRoleControllerTest {
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mFragment = spy(new UsbDetailsFragment());
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mLifecycle = new Lifecycle(() -> mLifecycle);
|
||||
mPreferenceManager = new PreferenceManager(mContext);
|
||||
@@ -95,12 +99,12 @@ public class UsbDetailsDataRoleControllerTest {
|
||||
mScreen.addPreference(mPreference);
|
||||
|
||||
mDetailsDataRoleController.mHandler = mHandler;
|
||||
|
||||
mDetailsDataRoleController.displayPreference(mScreen);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayRefresh_deviceRole_shouldCheckDevice() {
|
||||
mDetailsDataRoleController.displayPreference(mScreen);
|
||||
|
||||
mDetailsDataRoleController.refresh(true, UsbManager.FUNCTION_NONE, POWER_ROLE_SINK,
|
||||
DATA_ROLE_DEVICE);
|
||||
|
||||
@@ -112,8 +116,6 @@ public class UsbDetailsDataRoleControllerTest {
|
||||
|
||||
@Test
|
||||
public void displayRefresh_hostRole_shouldCheckHost() {
|
||||
mDetailsDataRoleController.displayPreference(mScreen);
|
||||
|
||||
mDetailsDataRoleController.refresh(true, UsbManager.FUNCTION_NONE, POWER_ROLE_SINK,
|
||||
DATA_ROLE_HOST);
|
||||
|
||||
@@ -125,8 +127,6 @@ public class UsbDetailsDataRoleControllerTest {
|
||||
|
||||
@Test
|
||||
public void displayRefresh_disconnected_shouldDisable() {
|
||||
mDetailsDataRoleController.displayPreference(mScreen);
|
||||
|
||||
mDetailsDataRoleController.refresh(false, UsbManager.FUNCTION_NONE, POWER_ROLE_SINK,
|
||||
DATA_ROLE_DEVICE);
|
||||
|
||||
@@ -135,7 +135,6 @@ public class UsbDetailsDataRoleControllerTest {
|
||||
|
||||
@Test
|
||||
public void onClickDevice_hostEnabled_shouldSetDevice() {
|
||||
mDetailsDataRoleController.displayPreference(mScreen);
|
||||
when(mUsbBackend.getDataRole()).thenReturn(DATA_ROLE_HOST);
|
||||
|
||||
final SelectorWithWidgetPreference devicePref = getRadioPreference(DATA_ROLE_DEVICE);
|
||||
@@ -148,7 +147,6 @@ public class UsbDetailsDataRoleControllerTest {
|
||||
|
||||
@Test
|
||||
public void onClickDeviceTwice_hostEnabled_shouldSetDeviceOnce() {
|
||||
mDetailsDataRoleController.displayPreference(mScreen);
|
||||
when(mUsbBackend.getDataRole()).thenReturn(DATA_ROLE_HOST);
|
||||
|
||||
final SelectorWithWidgetPreference devicePref = getRadioPreference(DATA_ROLE_DEVICE);
|
||||
@@ -162,7 +160,6 @@ public class UsbDetailsDataRoleControllerTest {
|
||||
|
||||
@Test
|
||||
public void onClickDeviceAndRefresh_success_shouldClearSubtext() {
|
||||
mDetailsDataRoleController.displayPreference(mScreen);
|
||||
when(mUsbBackend.getDataRole()).thenReturn(DATA_ROLE_HOST);
|
||||
|
||||
final SelectorWithWidgetPreference devicePref = getRadioPreference(DATA_ROLE_DEVICE);
|
||||
@@ -180,7 +177,6 @@ public class UsbDetailsDataRoleControllerTest {
|
||||
|
||||
@Test
|
||||
public void onClickDeviceAndRefresh_failed_shouldShowFailureText() {
|
||||
mDetailsDataRoleController.displayPreference(mScreen);
|
||||
when(mUsbBackend.getDataRole()).thenReturn(DATA_ROLE_HOST);
|
||||
|
||||
final SelectorWithWidgetPreference devicePref = getRadioPreference(DATA_ROLE_DEVICE);
|
||||
@@ -199,7 +195,6 @@ public class UsbDetailsDataRoleControllerTest {
|
||||
|
||||
@Test
|
||||
public void onClickDevice_timedOut_shouldShowFailureText() {
|
||||
mDetailsDataRoleController.displayPreference(mScreen);
|
||||
when(mUsbBackend.getDataRole()).thenReturn(DATA_ROLE_HOST);
|
||||
|
||||
final SelectorWithWidgetPreference devicePref = getRadioPreference(DATA_ROLE_DEVICE);
|
||||
@@ -218,6 +213,22 @@ public class UsbDetailsDataRoleControllerTest {
|
||||
.isEqualTo(mContext.getString(R.string.usb_switching_failed));
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresFlagsEnabled(Flags.FLAG_ENABLE_AUTH_CHALLENGE_FOR_USB_PREFERENCES)
|
||||
public void onRadioButtonClicked_userAuthenticated() {
|
||||
SelectorWithWidgetPreference preference = getRadioPreference(DATA_ROLE_DEVICE);
|
||||
setAuthPassesAutomatically();
|
||||
|
||||
mDetailsDataRoleController.onRadioButtonClicked(preference);
|
||||
|
||||
assertThat(mFragment.isUserAuthenticated()).isTrue();
|
||||
}
|
||||
|
||||
private void setAuthPassesAutomatically() {
|
||||
Shadows.shadowOf(mContext.getSystemService(KeyguardManager.class))
|
||||
.setIsKeyguardSecure(false);
|
||||
}
|
||||
|
||||
private SelectorWithWidgetPreference getRadioPreference(int role) {
|
||||
return (SelectorWithWidgetPreference)
|
||||
mPreference.findPreference(UsbBackend.dataRoleToString(role));
|
||||
|
||||
@@ -30,15 +30,18 @@ import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.KeyguardManager;
|
||||
import android.content.Context;
|
||||
import android.hardware.usb.UsbManager;
|
||||
import android.net.TetheringManager;
|
||||
import android.platform.test.annotations.RequiresFlagsEnabled;
|
||||
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.preference.PreferenceCategory;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.flags.Flags;
|
||||
import com.android.settings.testutils.shadow.ShadowUtils;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.widget.SelectorWithWidgetPreference;
|
||||
@@ -51,6 +54,7 @@ import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.Shadows;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -70,12 +74,11 @@ public class UsbDetailsFunctionsControllerTest {
|
||||
private PreferenceManager mPreferenceManager;
|
||||
private PreferenceScreen mScreen;
|
||||
private SelectorWithWidgetPreference mRadioButtonPreference;
|
||||
private UsbDetailsFragment mFragment;
|
||||
|
||||
@Mock
|
||||
private UsbBackend mUsbBackend;
|
||||
@Mock
|
||||
private UsbDetailsFragment mFragment;
|
||||
@Mock
|
||||
private FragmentActivity mActivity;
|
||||
@Mock
|
||||
private TetheringManager mTetheringManager;
|
||||
@@ -83,7 +86,7 @@ public class UsbDetailsFunctionsControllerTest {
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mFragment = spy(new UsbDetailsFragment());
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
mLifecycle = new Lifecycle(() -> mLifecycle);
|
||||
mPreferenceManager = new PreferenceManager(mContext);
|
||||
@@ -334,6 +337,23 @@ public class UsbDetailsFunctionsControllerTest {
|
||||
eq(mDetailsFunctionsController.mOnStartTetheringCallback));
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresFlagsEnabled(Flags.FLAG_ENABLE_AUTH_CHALLENGE_FOR_USB_PREFERENCES)
|
||||
public void onRadioButtonClicked_userAuthenticated() {
|
||||
mRadioButtonPreference.setKey(UsbBackend.usbFunctionsToString(UsbManager.FUNCTION_PTP));
|
||||
doReturn(UsbManager.FUNCTION_MTP).when(mUsbBackend).getCurrentFunctions();
|
||||
setAuthPassesAutomatically();
|
||||
|
||||
mDetailsFunctionsController.onRadioButtonClicked(mRadioButtonPreference);
|
||||
|
||||
assertThat(mFragment.isUserAuthenticated()).isTrue();
|
||||
}
|
||||
|
||||
private void setAuthPassesAutomatically() {
|
||||
Shadows.shadowOf(mContext.getSystemService(KeyguardManager.class))
|
||||
.setIsKeyguardSecure(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onTetheringFailed_resetPreviousFunctions() {
|
||||
mDetailsFunctionsController.mPreviousFunction = UsbManager.FUNCTION_PTP;
|
||||
|
||||
@@ -21,11 +21,14 @@ import static android.hardware.usb.UsbPortStatus.POWER_ROLE_NONE;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.KeyguardManager;
|
||||
import android.content.Context;
|
||||
import android.hardware.usb.UsbManager;
|
||||
import android.os.SystemProperties;
|
||||
import android.platform.test.annotations.RequiresFlagsEnabled;
|
||||
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.preference.PreferenceCategory;
|
||||
@@ -33,6 +36,7 @@ import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.preference.SwitchPreference;
|
||||
|
||||
import com.android.settings.flags.Flags;
|
||||
import com.android.settings.testutils.shadow.ShadowUtils;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -43,6 +47,7 @@ import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.Shadows;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@@ -57,18 +62,18 @@ public class UsbDetailsTranscodeMtpControllerTest {
|
||||
private PreferenceManager mPreferenceManager;
|
||||
private PreferenceScreen mScreen;
|
||||
private UsbDetailsTranscodeMtpController mUnderTest;
|
||||
private UsbDetailsFragment mFragment;
|
||||
|
||||
@Mock
|
||||
private UsbBackend mUsbBackend;
|
||||
@Mock
|
||||
private UsbDetailsFragment mFragment;
|
||||
@Mock
|
||||
private FragmentActivity mActivity;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mFragment = spy(new UsbDetailsFragment());
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mPreferenceManager = new PreferenceManager(mContext);
|
||||
mScreen = mPreferenceManager.createPreferenceScreen(mContext);
|
||||
@@ -84,11 +89,12 @@ public class UsbDetailsTranscodeMtpControllerTest {
|
||||
mPreference = new PreferenceCategory(mContext);
|
||||
mPreference.setKey(mUnderTest.getPreferenceKey());
|
||||
mScreen.addPreference(mPreference);
|
||||
|
||||
mUnderTest.displayPreference(mScreen);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayRefresh_noUsbConnection_shouldDisablePrefCategory() {
|
||||
mUnderTest.displayPreference(mScreen);
|
||||
when(mUsbBackend.areAllRolesSupported()).thenReturn(true);
|
||||
|
||||
mUnderTest.refresh(false /* connected */, UsbManager.FUNCTION_MTP, POWER_ROLE_NONE,
|
||||
@@ -99,7 +105,6 @@ public class UsbDetailsTranscodeMtpControllerTest {
|
||||
|
||||
@Test
|
||||
public void displayRefresh_noDataTransfer_shouldDisablePrefCategory() {
|
||||
mUnderTest.displayPreference(mScreen);
|
||||
when(mUsbBackend.areAllRolesSupported()).thenReturn(true);
|
||||
|
||||
mUnderTest.refresh(true /* connected */, UsbManager.FUNCTION_NONE, POWER_ROLE_NONE,
|
||||
@@ -110,7 +115,6 @@ public class UsbDetailsTranscodeMtpControllerTest {
|
||||
|
||||
@Test
|
||||
public void displayRefresh_noDataRole_shouldDisablePrefCategory() throws InterruptedException {
|
||||
mUnderTest.displayPreference(mScreen);
|
||||
when(mUsbBackend.areAllRolesSupported()).thenReturn(true);
|
||||
|
||||
mUnderTest.refresh(true /* connected */, UsbManager.FUNCTION_MTP, POWER_ROLE_NONE,
|
||||
@@ -122,7 +126,6 @@ public class UsbDetailsTranscodeMtpControllerTest {
|
||||
@Ignore("b/313362757")
|
||||
@Test
|
||||
public void displayRefresh_fileTransfer_withAbsentProp_shouldCheck() {
|
||||
mUnderTest.displayPreference(mScreen);
|
||||
when(mUsbBackend.areAllRolesSupported()).thenReturn(true);
|
||||
|
||||
mUnderTest.refresh(true /* connected */, UsbManager.FUNCTION_MTP, POWER_ROLE_NONE,
|
||||
@@ -134,7 +137,6 @@ public class UsbDetailsTranscodeMtpControllerTest {
|
||||
@Ignore("b/313362757")
|
||||
@Test
|
||||
public void displayRefresh_fileTransfer_withUnsetProp_shouldUncheck() {
|
||||
mUnderTest.displayPreference(mScreen);
|
||||
SystemProperties.set(TRANSCODE_MTP_SYS_PROP_KEY, Boolean.toString(false));
|
||||
when(mUsbBackend.areAllRolesSupported()).thenReturn(true);
|
||||
|
||||
@@ -147,7 +149,6 @@ public class UsbDetailsTranscodeMtpControllerTest {
|
||||
@Ignore("b/313362757")
|
||||
@Test
|
||||
public void displayRefresh_fileTransfer_withSetProp_shouldCheck() {
|
||||
mUnderTest.displayPreference(mScreen);
|
||||
SystemProperties.set(TRANSCODE_MTP_SYS_PROP_KEY, Boolean.toString(true));
|
||||
when(mUsbBackend.areAllRolesSupported()).thenReturn(true);
|
||||
|
||||
@@ -160,7 +161,6 @@ public class UsbDetailsTranscodeMtpControllerTest {
|
||||
@Ignore("b/313362757")
|
||||
@Test
|
||||
public void click_checked_shouldSetSystemProperty() {
|
||||
mUnderTest.displayPreference(mScreen);
|
||||
getSwitchPreference().performClick();
|
||||
assertThat(SystemProperties.getBoolean(TRANSCODE_MTP_SYS_PROP_KEY, false)).isTrue();
|
||||
}
|
||||
@@ -168,7 +168,6 @@ public class UsbDetailsTranscodeMtpControllerTest {
|
||||
@Ignore("b/313362757")
|
||||
@Test
|
||||
public void click_unChecked_shouldUnsetSystemProperty() {
|
||||
mUnderTest.displayPreference(mScreen);
|
||||
getSwitchPreference().performClick();
|
||||
getSwitchPreference().performClick();
|
||||
assertThat(SystemProperties.getBoolean(TRANSCODE_MTP_SYS_PROP_KEY, true)).isFalse();
|
||||
@@ -181,6 +180,21 @@ public class UsbDetailsTranscodeMtpControllerTest {
|
||||
assertThat(mUnderTest.isAvailable()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresFlagsEnabled(Flags.FLAG_ENABLE_AUTH_CHALLENGE_FOR_USB_PREFERENCES)
|
||||
public void onClick_userAuthenticated() {
|
||||
setAuthPassesAutomatically();
|
||||
|
||||
mUnderTest.onPreferenceClick(null);
|
||||
|
||||
assertThat(mFragment.isUserAuthenticated()).isTrue();
|
||||
}
|
||||
|
||||
private void setAuthPassesAutomatically() {
|
||||
Shadows.shadowOf(mContext.getSystemService(KeyguardManager.class))
|
||||
.setIsKeyguardSecure(false);
|
||||
}
|
||||
|
||||
private SwitchPreference getSwitchPreference() {
|
||||
return (SwitchPreference) mPreference.getPreference(0);
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ public class BatteryDefenderTipTest {
|
||||
|
||||
@Test
|
||||
public void updatePreference_shouldSetPrimaryButtonText() {
|
||||
String expectedText = mContext.getString(R.string.battery_tip_charge_to_full_button);
|
||||
String expectedText = mContext.getString(R.string.learn_more);
|
||||
|
||||
mBatteryDefenderTip.updatePreference(mCardPreference);
|
||||
|
||||
@@ -113,7 +113,7 @@ public class BatteryDefenderTipTest {
|
||||
|
||||
@Test
|
||||
public void updatePreference_shouldSetSecondaryButtonText() {
|
||||
String expected = mContext.getString(R.string.learn_more);
|
||||
String expected = mContext.getString(R.string.battery_tip_charge_to_full_button);
|
||||
|
||||
mBatteryDefenderTip.updatePreference(mCardPreference);
|
||||
|
||||
@@ -121,10 +121,10 @@ public class BatteryDefenderTipTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updatePreference_shouldSetSecondaryButtonVisible() {
|
||||
public void updatePreference_shouldSetPrimaryButtonVisible() {
|
||||
mBatteryDefenderTip.updatePreference(mCardPreference);
|
||||
|
||||
verify(mCardPreference).setSecondaryButtonVisible(true);
|
||||
verify(mCardPreference).setPrimaryButtonVisible(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -138,19 +138,19 @@ public class BatteryDefenderTipTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updatePreference_whenNotCharging_setPrimaryButtonVisibleToBeFalse() {
|
||||
public void updatePreference_whenNotCharging_setSecondaryButtonVisibleToBeFalse() {
|
||||
mBatteryDefenderTip.updatePreference(mCardPreference);
|
||||
|
||||
verify(mCardPreference).setPrimaryButtonVisible(false);
|
||||
verify(mCardPreference).setSecondaryButtonVisible(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updatePreference_whenGetChargingStatusFailed_setPrimaryButtonVisibleToBeFalse() {
|
||||
public void updatePreference_whenGetChargingStatusFailed_setSecondaryButtonVisibleToBeFalse() {
|
||||
fakeGetChargingStatusFailed();
|
||||
|
||||
mBatteryDefenderTip.updatePreference(mCardPreference);
|
||||
|
||||
verify(mCardPreference).setPrimaryButtonVisible(false);
|
||||
verify(mCardPreference).setSecondaryButtonVisible(false);
|
||||
}
|
||||
|
||||
private void fakeGetChargingStatusFailed() {
|
||||
|
||||
@@ -369,7 +369,7 @@ public class AppLocalePickerActivityTest {
|
||||
// In the proto file, en-US's uid list contains 103, the notificationCount equals 1, and
|
||||
// LastNotificationTime > 0.
|
||||
NotificationInfo info = mDataManager.getNotificationInfo(EN_US);
|
||||
assertThat(info.getUidCollection().contains(sUid)).isTrue();
|
||||
assertThat(info.getUidCollection()).contains(sUid);
|
||||
assertThat(info.getNotificationCount()).isEqualTo(1);
|
||||
assertThat(info.getDismissCount()).isEqualTo(0);
|
||||
assertThat(info.getLastNotificationTimeMs()).isNotEqualTo(0);
|
||||
@@ -440,7 +440,7 @@ public class AppLocalePickerActivityTest {
|
||||
|
||||
@Test
|
||||
@RequiresFlagsEnabled(Flags.FLAG_LOCALE_NOTIFICATION_ENABLED)
|
||||
public void testEvaluateLocaleNotification_localeUpdateReachThreshold_uidAddedNoNotification()
|
||||
public void testEvaluateLocaleNotification_localeUpdateReachThreshold_noUidNorNotification()
|
||||
throws Exception {
|
||||
// App with uid 106 changed its locale from System to en-US.
|
||||
sUid = 106;
|
||||
@@ -460,7 +460,7 @@ public class AppLocalePickerActivityTest {
|
||||
// In the proto file, en-US's uid list contains 106, the notificationCount equals 2, and
|
||||
// LastNotificationTime > 0.
|
||||
NotificationInfo info = mDataManager.getNotificationInfo(EN_US);
|
||||
assertThat(info.getUidCollection()).contains(sUid);
|
||||
assertThat(info.getUidCollection().contains(sUid)).isFalse();
|
||||
assertThat(info.getNotificationCount()).isEqualTo(2);
|
||||
assertThat(info.getDismissCount()).isEqualTo(0);
|
||||
assertThat(info.getLastNotificationTimeMs()).isEqualTo(lastNotificationTime);
|
||||
|
||||
@@ -68,6 +68,18 @@ public class LocaleNotificationDataManagerTest {
|
||||
info.getLastNotificationTimeMs());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveNotificationInfo() {
|
||||
String locale = "en-US";
|
||||
Set<Integer> uidSet = Set.of(101);
|
||||
NotificationInfo info = new NotificationInfo(uidSet, 1, 1, 100L, 1000);
|
||||
|
||||
mDataManager.putNotificationInfo(locale, info);
|
||||
assertThat(mDataManager.getNotificationInfo(locale)).isEqualTo(info);
|
||||
mDataManager.removeNotificationInfo(locale);
|
||||
assertThat(mDataManager.getNotificationInfo(locale)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNotificationMap() {
|
||||
String enUS = "en-US";
|
||||
|
||||
@@ -71,6 +71,19 @@ public class NotificationControllerTest {
|
||||
assertThat(result.getNotificationId()).isEqualTo(id);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveNotificationInfo_removed() throws Exception {
|
||||
String enUS = "en-US";
|
||||
Set<Integer> uidSet = Set.of(100, 101);
|
||||
long lastNotificationTime = Calendar.getInstance().getTimeInMillis();
|
||||
int id = (int) SystemClock.uptimeMillis();
|
||||
initSharedPreference(enUS, uidSet, 0, 1, lastNotificationTime, id);
|
||||
|
||||
mNotificationController.removeNotificationInfo(enUS);
|
||||
|
||||
assertThat(mDataManager.getNotificationInfo(enUS)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldTriggerNotification_inSystemLocale_returnFalse() throws Exception {
|
||||
int uid = 102;
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* 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.network.telephony
|
||||
|
||||
import android.telephony.CellIdentityCdma
|
||||
import android.telephony.CellIdentityGsm
|
||||
import android.telephony.CellInfoCdma
|
||||
import android.telephony.CellInfoGsm
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.android.internal.telephony.OperatorInfo
|
||||
import com.android.settings.network.telephony.CellInfoUtil.getNetworkTitle
|
||||
import com.android.settings.network.telephony.CellInfoUtil.getOperatorNumeric
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class CellInfoUtilTest {
|
||||
|
||||
@Test
|
||||
fun getNetworkTitle_alphaLong() {
|
||||
val networkTitle = CELL_IDENTITY_GSM.getNetworkTitle()
|
||||
|
||||
assertThat(networkTitle).isEqualTo(LONG)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getNetworkTitle_alphaShort() {
|
||||
val cellIdentity = CellIdentityGsm(
|
||||
/* lac = */ 1,
|
||||
/* cid = */ 2,
|
||||
/* arfcn = */ 3,
|
||||
/* bsic = */ 4,
|
||||
/* mccStr = */ "123",
|
||||
/* mncStr = */ "01",
|
||||
/* alphal = */ "",
|
||||
/* alphas = */ SHORT,
|
||||
/* additionalPlmns = */ emptyList(),
|
||||
)
|
||||
|
||||
val networkTitle = cellIdentity.getNetworkTitle()
|
||||
|
||||
assertThat(networkTitle).isEqualTo(SHORT)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getNetworkTitle_operatorNumeric() {
|
||||
val cellIdentity = CellIdentityGsm(
|
||||
/* lac = */ 1,
|
||||
/* cid = */ 2,
|
||||
/* arfcn = */ 3,
|
||||
/* bsic = */ 4,
|
||||
/* mccStr = */ "123",
|
||||
/* mncStr = */ "01",
|
||||
/* alphal = */ "",
|
||||
/* alphas = */ "",
|
||||
/* additionalPlmns = */ emptyList(),
|
||||
)
|
||||
|
||||
val networkTitle = cellIdentity.getNetworkTitle()
|
||||
|
||||
assertThat(networkTitle).isEqualTo("12301")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getNetworkTitle_null() {
|
||||
val cellIdentity = CellIdentityGsm(
|
||||
/* lac = */ 1,
|
||||
/* cid = */ 2,
|
||||
/* arfcn = */ 3,
|
||||
/* bsic = */ 4,
|
||||
/* mccStr = */ null,
|
||||
/* mncStr = */ null,
|
||||
/* alphal = */ null,
|
||||
/* alphas = */ null,
|
||||
/* additionalPlmns = */ emptyList(),
|
||||
)
|
||||
|
||||
val networkTitle = cellIdentity.getNetworkTitle()
|
||||
|
||||
assertThat(networkTitle).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun convertOperatorInfoToCellInfo() {
|
||||
val operatorInfo = OperatorInfo(LONG, SHORT, "12301")
|
||||
|
||||
val cellInfo = CellInfoUtil.convertOperatorInfoToCellInfo(operatorInfo)
|
||||
|
||||
assertThat(cellInfo.cellIdentity.mccString).isEqualTo("123")
|
||||
assertThat(cellInfo.cellIdentity.mncString).isEqualTo("01")
|
||||
assertThat(cellInfo.cellIdentity.operatorAlphaLong).isEqualTo(LONG)
|
||||
assertThat(cellInfo.cellIdentity.operatorAlphaShort).isEqualTo(SHORT)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun cellInfoListToString() {
|
||||
val cellInfoList =
|
||||
listOf(
|
||||
CellInfoCdma().apply {
|
||||
cellIdentity = CELL_IDENTITY_CDMA
|
||||
},
|
||||
CellInfoGsm().apply {
|
||||
isRegistered = true
|
||||
cellIdentity = CELL_IDENTITY_GSM
|
||||
},
|
||||
)
|
||||
|
||||
val string = CellInfoUtil.cellInfoListToString(cellInfoList)
|
||||
|
||||
assertThat(string).isEqualTo(
|
||||
"{CellType = CellInfoCdma, isRegistered = false, " +
|
||||
"mcc = null, mnc = null, alphaL = Long, alphaS = Short}, " +
|
||||
"{CellType = CellInfoGsm, isRegistered = true, " +
|
||||
"mcc = 123, mnc = 01, alphaL = Long, alphaS = Short}"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getOperatorNumeric_cdma() {
|
||||
val operatorNumeric = CELL_IDENTITY_CDMA.getOperatorNumeric()
|
||||
|
||||
assertThat(operatorNumeric).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getOperatorNumeric_gsm() {
|
||||
val operatorNumeric = CELL_IDENTITY_GSM.getOperatorNumeric()
|
||||
|
||||
assertThat(operatorNumeric).isEqualTo("12301")
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val LONG = "Long"
|
||||
const val SHORT = "Short"
|
||||
|
||||
val CELL_IDENTITY_GSM = CellIdentityGsm(
|
||||
/* lac = */ 1,
|
||||
/* cid = */ 2,
|
||||
/* arfcn = */ 3,
|
||||
/* bsic = */ 4,
|
||||
/* mccStr = */ "123",
|
||||
/* mncStr = */ "01",
|
||||
/* alphal = */ LONG,
|
||||
/* alphas = */ SHORT,
|
||||
/* additionalPlmns = */ emptyList(),
|
||||
)
|
||||
|
||||
val CELL_IDENTITY_CDMA = CellIdentityCdma(
|
||||
/* nid = */ 1,
|
||||
/* sid = */ 2,
|
||||
/* bid = */ 3,
|
||||
/* lon = */ 4,
|
||||
/* lat = */ 5,
|
||||
/* alphal = */ LONG,
|
||||
/* alphas = */ SHORT,
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user