Snap for 11722130 from ea8c0f7716 to 24Q3-release
Change-Id: If21ee31077b197be0812efc34135f793b47eb6b5
This commit is contained in:
@@ -8794,13 +8794,13 @@
|
|||||||
<!-- [CHAR LIMIT=NONE] App notification settings: link to app notification settings-->
|
<!-- [CHAR LIMIT=NONE] App notification settings: link to app notification settings-->
|
||||||
<string name="app_settings_link">Additional settings in the app</string>
|
<string name="app_settings_link">Additional settings in the app</string>
|
||||||
|
|
||||||
<!-- [CHAR LIMIT=20] 3-dot menu option, reloads the screen to show channels that have not
|
<!-- [CHAR LIMIT=35] 3-dot menu option, reloads the screen to show channels that have not
|
||||||
received notifications in the last two week -->
|
received notifications in the last two week -->
|
||||||
<string name="show_unused_channels">Show unused channels</string>
|
<string name="show_unused_channels">Show unused categories</string>
|
||||||
|
|
||||||
<!-- [CHAR LIMIT=20] 3-dot menu option, reloads the screen to hide channels that have not
|
<!-- [CHAR LIMIT=35] 3-dot menu option, reloads the screen to hide channels that have not
|
||||||
received notifications in the last two week -->
|
received notifications in the last two week -->
|
||||||
<string name="hide_unused_channels">Hide unused channels</string>
|
<string name="hide_unused_channels">Hide unused categories</string>
|
||||||
|
|
||||||
<!-- [CHAR LIMIT=NONE] Footer listing a count of deleted channels. -->
|
<!-- [CHAR LIMIT=NONE] Footer listing a count of deleted channels. -->
|
||||||
<string name="deleted_channels">{count, plural,
|
<string name="deleted_channels">{count, plural,
|
||||||
|
|||||||
@@ -20,14 +20,6 @@
|
|||||||
android:key="system_dashboard_screen"
|
android:key="system_dashboard_screen"
|
||||||
android:title="@string/header_category_system">
|
android:title="@string/header_category_system">
|
||||||
|
|
||||||
<Preference
|
|
||||||
android:key="language_input_settings"
|
|
||||||
android:title="@string/language_settings"
|
|
||||||
android:icon="@drawable/ic_settings_language"
|
|
||||||
android:order="-260"
|
|
||||||
android:fragment="com.android.settings.language.LanguageAndInputSettings"
|
|
||||||
settings:controller="com.android.settings.language.LanguageAndInputPreferenceController"/>
|
|
||||||
|
|
||||||
<Preference
|
<Preference
|
||||||
android:key="language_settings"
|
android:key="language_settings"
|
||||||
android:title="@string/languages_settings"
|
android:title="@string/languages_settings"
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ import com.android.settings.homepage.DeepLinkHomepageActivityInternal;
|
|||||||
import com.android.settings.homepage.SettingsHomepageActivity;
|
import com.android.settings.homepage.SettingsHomepageActivity;
|
||||||
import com.android.settings.overlay.FeatureFactory;
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
import com.android.settings.password.ChooseLockPattern;
|
import com.android.settings.password.ChooseLockPattern;
|
||||||
|
import com.android.settings.privatespace.PrivateSpaceSetupActivity;
|
||||||
import com.android.settings.remoteauth.RemoteAuthActivity;
|
import com.android.settings.remoteauth.RemoteAuthActivity;
|
||||||
import com.android.settings.remoteauth.RemoteAuthActivityInternal;
|
import com.android.settings.remoteauth.RemoteAuthActivityInternal;
|
||||||
|
|
||||||
@@ -264,6 +265,7 @@ public class ActivityEmbeddingRulesController {
|
|||||||
addActivityFilter(activityFilters, RemoteAuthActivity.class);
|
addActivityFilter(activityFilters, RemoteAuthActivity.class);
|
||||||
addActivityFilter(activityFilters, RemoteAuthActivityInternal.class);
|
addActivityFilter(activityFilters, RemoteAuthActivityInternal.class);
|
||||||
addActivityFilter(activityFilters, ChooseLockPattern.class);
|
addActivityFilter(activityFilters, ChooseLockPattern.class);
|
||||||
|
addActivityFilter(activityFilters, PrivateSpaceSetupActivity.class);
|
||||||
String action = mContext.getString(R.string.config_avatar_picker_action);
|
String action = mContext.getString(R.string.config_avatar_picker_action);
|
||||||
addActivityFilter(activityFilters, new Intent(action));
|
addActivityFilter(activityFilters, new Intent(action));
|
||||||
|
|
||||||
|
|||||||
@@ -135,7 +135,6 @@ import com.android.settings.inputmethod.SpellCheckersSettings;
|
|||||||
import com.android.settings.inputmethod.TrackpadSettings;
|
import com.android.settings.inputmethod.TrackpadSettings;
|
||||||
import com.android.settings.inputmethod.UserDictionaryList;
|
import com.android.settings.inputmethod.UserDictionaryList;
|
||||||
import com.android.settings.inputmethod.UserDictionarySettings;
|
import com.android.settings.inputmethod.UserDictionarySettings;
|
||||||
import com.android.settings.language.LanguageAndInputSettings;
|
|
||||||
import com.android.settings.language.LanguageSettings;
|
import com.android.settings.language.LanguageSettings;
|
||||||
import com.android.settings.localepicker.LocaleListEditor;
|
import com.android.settings.localepicker.LocaleListEditor;
|
||||||
import com.android.settings.location.LocationServices;
|
import com.android.settings.location.LocationServices;
|
||||||
@@ -226,7 +225,6 @@ public class SettingsGateway {
|
|||||||
DateTimeSettings.class.getName(),
|
DateTimeSettings.class.getName(),
|
||||||
LocaleListEditor.class.getName(),
|
LocaleListEditor.class.getName(),
|
||||||
AvailableVirtualKeyboardFragment.class.getName(),
|
AvailableVirtualKeyboardFragment.class.getName(),
|
||||||
LanguageAndInputSettings.class.getName(),
|
|
||||||
LanguageSettings.class.getName(),
|
LanguageSettings.class.getName(),
|
||||||
KeyboardSettings.class.getName(),
|
KeyboardSettings.class.getName(),
|
||||||
ModifierKeysSettings.class.getName(),
|
ModifierKeysSettings.class.getName(),
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ import com.android.settings.fuelgauge.batterysaver.BatterySaverSettings;
|
|||||||
import com.android.settings.fuelgauge.batteryusage.PowerUsageSummary;
|
import com.android.settings.fuelgauge.batteryusage.PowerUsageSummary;
|
||||||
import com.android.settings.gestures.GestureSettings;
|
import com.android.settings.gestures.GestureSettings;
|
||||||
import com.android.settings.homepage.TopLevelSettings;
|
import com.android.settings.homepage.TopLevelSettings;
|
||||||
import com.android.settings.language.LanguageAndInputSettings;
|
|
||||||
import com.android.settings.network.NetworkDashboardFragment;
|
import com.android.settings.network.NetworkDashboardFragment;
|
||||||
import com.android.settings.notification.ConfigureNotificationSettings;
|
import com.android.settings.notification.ConfigureNotificationSettings;
|
||||||
import com.android.settings.notification.SoundSettings;
|
import com.android.settings.notification.SoundSettings;
|
||||||
@@ -102,8 +101,6 @@ public class DashboardFragmentRegistry {
|
|||||||
CategoryKey.CATEGORY_ACCOUNT);
|
CategoryKey.CATEGORY_ACCOUNT);
|
||||||
PARENT_TO_CATEGORY_KEY_MAP.put(
|
PARENT_TO_CATEGORY_KEY_MAP.put(
|
||||||
SystemDashboardFragment.class.getName(), CategoryKey.CATEGORY_SYSTEM);
|
SystemDashboardFragment.class.getName(), CategoryKey.CATEGORY_SYSTEM);
|
||||||
PARENT_TO_CATEGORY_KEY_MAP.put(LanguageAndInputSettings.class.getName(),
|
|
||||||
CategoryKey.CATEGORY_SYSTEM_LANGUAGE);
|
|
||||||
// TODO(b/242680328) Tie new category key to LanguageSettings and KeyboardSettings page
|
// TODO(b/242680328) Tie new category key to LanguageSettings and KeyboardSettings page
|
||||||
PARENT_TO_CATEGORY_KEY_MAP.put(DevelopmentSettingsDashboardFragment.class.getName(),
|
PARENT_TO_CATEGORY_KEY_MAP.put(DevelopmentSettingsDashboardFragment.class.getName(),
|
||||||
CategoryKey.CATEGORY_SYSTEM_DEVELOPMENT);
|
CategoryKey.CATEGORY_SYSTEM_DEVELOPMENT);
|
||||||
|
|||||||
@@ -78,6 +78,10 @@ public class BluetoothCodecListPreferenceController
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onPreferenceChange(@Nullable Preference preference, @NonNull Object newValue) {
|
public boolean onPreferenceChange(@Nullable Preference preference, @NonNull Object newValue) {
|
||||||
|
if (!Flags.a2dpOffloadCodecExtensibilitySettings()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "onPreferenceChange: newValue=" + (String) newValue);
|
Log.d(TAG, "onPreferenceChange: newValue=" + (String) newValue);
|
||||||
}
|
}
|
||||||
@@ -120,6 +124,10 @@ public class BluetoothCodecListPreferenceController
|
|||||||
@Override
|
@Override
|
||||||
public void updateState(@Nullable Preference preference) {
|
public void updateState(@Nullable Preference preference) {
|
||||||
super.updateState(preference);
|
super.updateState(preference);
|
||||||
|
if (!Flags.a2dpOffloadCodecExtensibilitySettings()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
final List<String> codecIds = new ArrayList<>();
|
final List<String> codecIds = new ArrayList<>();
|
||||||
final List<String> labels = new ArrayList<>();
|
final List<String> labels = new ArrayList<>();
|
||||||
String selectedCodecId = mDefaultValue;
|
String selectedCodecId = mDefaultValue;
|
||||||
|
|||||||
@@ -80,7 +80,6 @@ public class MainlineModuleVersionPreferenceController extends BasePreferenceCon
|
|||||||
try {
|
try {
|
||||||
mModuleVersion =
|
mModuleVersion =
|
||||||
mPackageManager.getPackageInfo(moduleProvider, 0 /* flags */).versionName;
|
mPackageManager.getPackageInfo(moduleProvider, 0 /* flags */).versionName;
|
||||||
return;
|
|
||||||
} catch (PackageManager.NameNotFoundException e) {
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
Log.e(TAG, "Failed to get mainline version.", e);
|
Log.e(TAG, "Failed to get mainline version.", e);
|
||||||
mModuleVersion = null;
|
mModuleVersion = null;
|
||||||
@@ -124,7 +123,8 @@ public class MainlineModuleVersionPreferenceController extends BasePreferenceCon
|
|||||||
return mModuleVersion;
|
return mModuleVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DateFormat.getLongDateFormat(mContext).format(parsedDate.get());
|
String format = DateFormat.getBestDateTimePattern(Locale.getDefault(), "dMMMMyyyy");
|
||||||
|
return DateFormat.format(format, parsedDate.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<Date> parseDateFromVersionName(String text) {
|
private Optional<Date> parseDateFromVersionName(String text) {
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ package com.android.settings.inputmethod;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.hardware.input.InputManager;
|
import android.hardware.input.InputManager;
|
||||||
import android.util.FeatureFlagUtils;
|
|
||||||
|
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
|
|
||||||
@@ -78,9 +77,7 @@ public class KeyboardPreferenceController extends BasePreferenceController
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getAvailabilityStatus() {
|
public int getAvailabilityStatus() {
|
||||||
return FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI)
|
return AVAILABLE;
|
||||||
? AVAILABLE
|
|
||||||
: CONDITIONALLY_UNAVAILABLE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateSummary() {
|
private void updateSummary() {
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROF
|
|||||||
import android.app.settings.SettingsEnums;
|
import android.app.settings.SettingsEnums;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.FeatureFlagUtils;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
@@ -111,11 +110,5 @@ public class KeyboardSettings extends DashboardFragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
||||||
new BaseSearchIndexProvider(R.xml.keyboard_settings) {
|
new BaseSearchIndexProvider(R.xml.keyboard_settings);
|
||||||
@Override
|
|
||||||
protected boolean isPageSearchEnabled(Context context) {
|
|
||||||
return FeatureFlagUtils
|
|
||||||
.isEnabled(context, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
@@ -20,7 +20,6 @@ import android.app.settings.SettingsEnums;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.util.FeatureFlagUtils;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
@@ -69,8 +68,7 @@ public class KeyboardSettingsPreferenceController extends BasePreferenceControll
|
|||||||
@Override
|
@Override
|
||||||
public int getAvailabilityStatus() {
|
public int getAvailabilityStatus() {
|
||||||
List<HardKeyboardDeviceInfo> newHardKeyboards = getHardKeyboardList();
|
List<HardKeyboardDeviceInfo> newHardKeyboards = getHardKeyboardList();
|
||||||
if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI)
|
if (!newHardKeyboards.isEmpty()) {
|
||||||
&& !newHardKeyboards.isEmpty()) {
|
|
||||||
for (HardKeyboardDeviceInfo hardKeyboardDeviceInfo : newHardKeyboards) {
|
for (HardKeyboardDeviceInfo hardKeyboardDeviceInfo : newHardKeyboards) {
|
||||||
if (mCachedDevice.getAddress() != null
|
if (mCachedDevice.getAddress() != null
|
||||||
&& hardKeyboardDeviceInfo.mBluetoothAddress != null
|
&& hardKeyboardDeviceInfo.mBluetoothAddress != null
|
||||||
|
|||||||
@@ -110,7 +110,6 @@ public final class PhysicalKeyboardFragment extends SettingsPreferenceFragment
|
|||||||
|
|
||||||
|
|
||||||
private Intent mIntentWaitingForResult;
|
private Intent mIntentWaitingForResult;
|
||||||
private boolean mIsNewKeyboardSettings;
|
|
||||||
private boolean mSupportsFirmwareUpdate;
|
private boolean mSupportsFirmwareUpdate;
|
||||||
|
|
||||||
static final String EXTRA_BT_ADDRESS = "extra_bt_address";
|
static final String EXTRA_BT_ADDRESS = "extra_bt_address";
|
||||||
@@ -152,8 +151,6 @@ public final class PhysicalKeyboardFragment extends SettingsPreferenceFragment
|
|||||||
if (mSupportsFirmwareUpdate) {
|
if (mSupportsFirmwareUpdate) {
|
||||||
mFeatureProvider.addFirmwareUpdateCategory(getContext(), getPreferenceScreen());
|
mFeatureProvider.addFirmwareUpdateCategory(getContext(), getPreferenceScreen());
|
||||||
}
|
}
|
||||||
mIsNewKeyboardSettings = FeatureFlagUtils.isEnabled(
|
|
||||||
getContext(), FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI);
|
|
||||||
boolean isModifierKeySettingsEnabled = FeatureFlagUtils
|
boolean isModifierKeySettingsEnabled = FeatureFlagUtils
|
||||||
.isEnabled(getContext(), FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_MODIFIER_KEY);
|
.isEnabled(getContext(), FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_MODIFIER_KEY);
|
||||||
if (!isModifierKeySettingsEnabled) {
|
if (!isModifierKeySettingsEnabled) {
|
||||||
@@ -287,27 +284,19 @@ public final class PhysicalKeyboardFragment extends SettingsPreferenceFragment
|
|||||||
// TODO(yukawa): Consider using com.android.settings.widget.GearPreference
|
// TODO(yukawa): Consider using com.android.settings.widget.GearPreference
|
||||||
final Preference pref = new Preference(getPrefContext());
|
final Preference pref = new Preference(getPrefContext());
|
||||||
pref.setTitle(hardKeyboardDeviceInfo.mDeviceName);
|
pref.setTitle(hardKeyboardDeviceInfo.mDeviceName);
|
||||||
if (mIsNewKeyboardSettings) {
|
String currentLayout =
|
||||||
String currentLayout =
|
NewKeyboardSettingsUtils.getSelectedKeyboardLayoutLabelForUser(getContext(),
|
||||||
NewKeyboardSettingsUtils.getSelectedKeyboardLayoutLabelForUser(getContext(),
|
UserHandle.myUserId(), hardKeyboardDeviceInfo.mDeviceIdentifier);
|
||||||
UserHandle.myUserId(), hardKeyboardDeviceInfo.mDeviceIdentifier);
|
if (currentLayout != null) {
|
||||||
if (currentLayout != null) {
|
pref.setSummary(currentLayout);
|
||||||
pref.setSummary(currentLayout);
|
|
||||||
}
|
|
||||||
pref.setOnPreferenceClickListener(
|
|
||||||
preference -> {
|
|
||||||
showEnabledLocalesKeyboardLayoutList(
|
|
||||||
hardKeyboardDeviceInfo.mDeviceIdentifier);
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
pref.setSummary(hardKeyboardDeviceInfo.mLayoutLabel);
|
|
||||||
pref.setOnPreferenceClickListener(
|
|
||||||
preference -> {
|
|
||||||
showKeyboardLayoutDialog(hardKeyboardDeviceInfo.mDeviceIdentifier);
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
pref.setOnPreferenceClickListener(
|
||||||
|
preference -> {
|
||||||
|
showEnabledLocalesKeyboardLayoutList(
|
||||||
|
hardKeyboardDeviceInfo.mDeviceIdentifier);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
category.addPreference(pref);
|
category.addPreference(pref);
|
||||||
StringBuilder vendorAndProductId = new StringBuilder();
|
StringBuilder vendorAndProductId = new StringBuilder();
|
||||||
String vendorId = String.valueOf(hardKeyboardDeviceInfo.mVendorId);
|
String vendorId = String.valueOf(hardKeyboardDeviceInfo.mVendorId);
|
||||||
|
|||||||
@@ -1,66 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2019 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.language;
|
|
||||||
|
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.provider.Settings;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.util.FeatureFlagUtils;
|
|
||||||
import android.view.inputmethod.InputMethodInfo;
|
|
||||||
import android.view.inputmethod.InputMethodManager;
|
|
||||||
|
|
||||||
import com.android.settings.core.BasePreferenceController;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class LanguageAndInputPreferenceController extends BasePreferenceController {
|
|
||||||
|
|
||||||
private PackageManager mPackageManager;
|
|
||||||
private InputMethodManager mInputMethodManager;
|
|
||||||
|
|
||||||
public LanguageAndInputPreferenceController(Context context, String key) {
|
|
||||||
super(context, key);
|
|
||||||
mPackageManager = mContext.getPackageManager();
|
|
||||||
mInputMethodManager = mContext.getSystemService(InputMethodManager.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getAvailabilityStatus() {
|
|
||||||
boolean isFeatureOn = FeatureFlagUtils
|
|
||||||
.isEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI);
|
|
||||||
return isFeatureOn ? CONDITIONALLY_UNAVAILABLE : AVAILABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence getSummary() {
|
|
||||||
final String flattenComponent = Settings.Secure.getString(
|
|
||||||
mContext.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
|
|
||||||
if (!TextUtils.isEmpty(flattenComponent)) {
|
|
||||||
final String pkg = ComponentName.unflattenFromString(flattenComponent)
|
|
||||||
.getPackageName();
|
|
||||||
final List<InputMethodInfo> imis = mInputMethodManager.getInputMethodList();
|
|
||||||
for (InputMethodInfo imi : imis) {
|
|
||||||
if (TextUtils.equals(imi.getPackageName(), pkg)) {
|
|
||||||
return imi.loadLabel(mPackageManager);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,168 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2016 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.language;
|
|
||||||
|
|
||||||
import static android.app.admin.DevicePolicyResources.Strings.Settings.PERSONAL_DICTIONARY_FOR_WORK;
|
|
||||||
import static android.app.admin.DevicePolicyResources.Strings.Settings.SPELL_CHECKER_FOR_WORK;
|
|
||||||
import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_KEYBOARDS_AND_TOOLS;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.settings.SettingsEnums;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.util.FeatureFlagUtils;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import com.android.settings.R;
|
|
||||||
import com.android.settings.dashboard.DashboardFragment;
|
|
||||||
import com.android.settings.inputmethod.PhysicalKeyboardPreferenceController;
|
|
||||||
import com.android.settings.inputmethod.SpellCheckerPreferenceController;
|
|
||||||
import com.android.settings.inputmethod.VirtualKeyboardPreferenceController;
|
|
||||||
import com.android.settings.search.BaseSearchIndexProvider;
|
|
||||||
import com.android.settings.widget.PreferenceCategoryController;
|
|
||||||
import com.android.settingslib.core.AbstractPreferenceController;
|
|
||||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
|
||||||
import com.android.settingslib.search.SearchIndexable;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@SearchIndexable
|
|
||||||
public class LanguageAndInputSettings extends DashboardFragment {
|
|
||||||
|
|
||||||
private static final String TAG = "LangAndInputSettings";
|
|
||||||
|
|
||||||
private static final String KEY_KEYBOARDS_CATEGORY = "keyboards_category";
|
|
||||||
private static final String KEY_SPEECH_CATEGORY = "speech_category";
|
|
||||||
private static final String KEY_ON_DEVICE_RECOGNITION = "odsr_settings";
|
|
||||||
private static final String KEY_TEXT_TO_SPEECH = "tts_settings_summary";
|
|
||||||
private static final String KEY_POINTER_CATEGORY = "pointer_category";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMetricsCategory() {
|
|
||||||
return SettingsEnums.SETTINGS_LANGUAGE_CATEGORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getLogTag() {
|
|
||||||
return TAG;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
// Hack to update action bar title. It's necessary to refresh title because this page user
|
|
||||||
// can change locale from here and fragment won't relaunch. Once language changes, title
|
|
||||||
// must display in the new language.
|
|
||||||
final Activity activity = getActivity();
|
|
||||||
if (activity == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
activity.setTitle(R.string.language_settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle icicle) {
|
|
||||||
super.onCreate(icicle);
|
|
||||||
replaceEnterpriseStringTitle("language_and_input_for_work_category",
|
|
||||||
WORK_PROFILE_KEYBOARDS_AND_TOOLS,
|
|
||||||
R.string.language_and_input_for_work_category_title);
|
|
||||||
replaceEnterpriseStringTitle("spellcheckers_settings_for_work_pref",
|
|
||||||
SPELL_CHECKER_FOR_WORK,
|
|
||||||
R.string.spellcheckers_settings_for_work_title);
|
|
||||||
replaceEnterpriseStringTitle("user_dictionary_settings_for_work_pref",
|
|
||||||
PERSONAL_DICTIONARY_FOR_WORK,
|
|
||||||
R.string.user_dict_settings_for_work_title);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getPreferenceScreenResId() {
|
|
||||||
return R.xml.language_and_input;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
|
|
||||||
return buildPreferenceControllers(context, getSettingsLifecycle());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<AbstractPreferenceController> buildPreferenceControllers(
|
|
||||||
@NonNull Context context, @Nullable Lifecycle lifecycle) {
|
|
||||||
final List<AbstractPreferenceController> controllers = new ArrayList<>();
|
|
||||||
|
|
||||||
// Input
|
|
||||||
final VirtualKeyboardPreferenceController virtualKeyboardPreferenceController =
|
|
||||||
new VirtualKeyboardPreferenceController(context);
|
|
||||||
final PhysicalKeyboardPreferenceController physicalKeyboardPreferenceController =
|
|
||||||
new PhysicalKeyboardPreferenceController(context, lifecycle);
|
|
||||||
controllers.add(virtualKeyboardPreferenceController);
|
|
||||||
controllers.add(physicalKeyboardPreferenceController);
|
|
||||||
controllers.add(new PreferenceCategoryController(context,
|
|
||||||
KEY_KEYBOARDS_CATEGORY).setChildren(
|
|
||||||
Arrays.asList(virtualKeyboardPreferenceController,
|
|
||||||
physicalKeyboardPreferenceController)));
|
|
||||||
|
|
||||||
// Speech
|
|
||||||
final DefaultVoiceInputPreferenceController defaultVoiceInputPreferenceController =
|
|
||||||
new DefaultVoiceInputPreferenceController(context, lifecycle);
|
|
||||||
final TtsPreferenceController ttsPreferenceController =
|
|
||||||
new TtsPreferenceController(context, KEY_TEXT_TO_SPEECH);
|
|
||||||
final OnDeviceRecognitionPreferenceController onDeviceRecognitionPreferenceController =
|
|
||||||
new OnDeviceRecognitionPreferenceController(context, KEY_ON_DEVICE_RECOGNITION);
|
|
||||||
|
|
||||||
controllers.add(defaultVoiceInputPreferenceController);
|
|
||||||
controllers.add(ttsPreferenceController);
|
|
||||||
List<AbstractPreferenceController> speechCategoryChildren = new ArrayList<>(
|
|
||||||
List.of(defaultVoiceInputPreferenceController, ttsPreferenceController));
|
|
||||||
|
|
||||||
if (onDeviceRecognitionPreferenceController.isAvailable()) {
|
|
||||||
controllers.add(onDeviceRecognitionPreferenceController);
|
|
||||||
speechCategoryChildren.add(onDeviceRecognitionPreferenceController);
|
|
||||||
}
|
|
||||||
|
|
||||||
controllers.add(new PreferenceCategoryController(context, KEY_SPEECH_CATEGORY)
|
|
||||||
.setChildren(speechCategoryChildren));
|
|
||||||
|
|
||||||
// Pointer
|
|
||||||
final PointerSpeedController pointerController = new PointerSpeedController(context);
|
|
||||||
controllers.add(pointerController);
|
|
||||||
controllers.add(new PreferenceCategoryController(context,
|
|
||||||
KEY_POINTER_CATEGORY).setChildren(Arrays.asList(pointerController)));
|
|
||||||
|
|
||||||
// Input Assistance
|
|
||||||
controllers.add(new SpellCheckerPreferenceController(context));
|
|
||||||
|
|
||||||
return controllers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
|
||||||
new BaseSearchIndexProvider(R.xml.language_and_input) {
|
|
||||||
@Override
|
|
||||||
public List<AbstractPreferenceController> createPreferenceControllers(
|
|
||||||
Context context) {
|
|
||||||
return buildPreferenceControllers(context, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isPageSearchEnabled(Context context) {
|
|
||||||
return !FeatureFlagUtils
|
|
||||||
.isEnabled(context, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -19,7 +19,6 @@ package com.android.settings.language;
|
|||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.util.FeatureFlagUtils;
|
|
||||||
|
|
||||||
import com.android.settings.Settings;
|
import com.android.settings.Settings;
|
||||||
import com.android.settings.core.BasePreferenceController;
|
import com.android.settings.core.BasePreferenceController;
|
||||||
@@ -29,28 +28,14 @@ import com.android.settings.core.BasePreferenceController;
|
|||||||
* TODO(b/273642892): When new layout is on board, this class shall be removed.
|
* TODO(b/273642892): When new layout is on board, this class shall be removed.
|
||||||
*/
|
*/
|
||||||
public class LanguagePreferenceController extends BasePreferenceController {
|
public class LanguagePreferenceController extends BasePreferenceController {
|
||||||
private static final String TAG = LanguagePreferenceController.class.getSimpleName();
|
|
||||||
|
|
||||||
private boolean mCacheIsFeatureOn = false;
|
|
||||||
|
|
||||||
public LanguagePreferenceController(Context context, String key) {
|
public LanguagePreferenceController(Context context, String key) {
|
||||||
super(context, key);
|
super(context, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getAvailabilityStatus() {
|
public int getAvailabilityStatus() {
|
||||||
boolean isFeatureOn = FeatureFlagUtils
|
setActivityEnabled(mContext, Settings.LanguageSettingsActivity.class, true);
|
||||||
.isEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI);
|
return AVAILABLE;
|
||||||
|
|
||||||
// LanguageSettingsActivity is a new entry page for new language layout.
|
|
||||||
// LanguageAndInputSettingsActivity is existed entry page for current language layout.
|
|
||||||
if (mCacheIsFeatureOn != isFeatureOn) {
|
|
||||||
setActivityEnabled(
|
|
||||||
mContext, Settings.LanguageAndInputSettingsActivity.class, !isFeatureOn);
|
|
||||||
setActivityEnabled(mContext, Settings.LanguageSettingsActivity.class, isFeatureOn);
|
|
||||||
mCacheIsFeatureOn = isFeatureOn;
|
|
||||||
}
|
|
||||||
return isFeatureOn ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setActivityEnabled(Context context, Class klass, final boolean isEnabled) {
|
private static void setActivityEnabled(Context context, Class klass, final boolean isEnabled) {
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ package com.android.settings.language;
|
|||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.settings.SettingsEnums;
|
import android.app.settings.SettingsEnums;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.FeatureFlagUtils;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
@@ -112,8 +111,7 @@ public class LanguageSettings extends DashboardFragment {
|
|||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
protected boolean isPageSearchEnabled(Context context) {
|
protected boolean isPageSearchEnabled(Context context) {
|
||||||
return FeatureFlagUtils
|
return true;
|
||||||
.isEnabled(context, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -81,7 +81,7 @@ public class MediaDeviceUpdateWorker extends SliceBackgroundWorker
|
|||||||
mIsTouched = false;
|
mIsTouched = false;
|
||||||
if (mLocalMediaManager == null || !TextUtils.equals(mPackageName,
|
if (mLocalMediaManager == null || !TextUtils.equals(mPackageName,
|
||||||
mLocalMediaManager.getPackageName())) {
|
mLocalMediaManager.getPackageName())) {
|
||||||
mLocalMediaManager = new LocalMediaManager(mContext, mPackageName, null);
|
mLocalMediaManager = new LocalMediaManager(mContext, mPackageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delaying initialization to allow mocking in Roboelectric tests.
|
// Delaying initialization to allow mocking in Roboelectric tests.
|
||||||
|
|||||||
@@ -92,8 +92,7 @@ public class MediaOutputIndicatorWorker extends SliceBackgroundWorker implements
|
|||||||
}
|
}
|
||||||
if (mLocalMediaManager == null || !TextUtils.equals(mPackageName,
|
if (mLocalMediaManager == null || !TextUtils.equals(mPackageName,
|
||||||
mLocalMediaManager.getPackageName())) {
|
mLocalMediaManager.getPackageName())) {
|
||||||
mLocalMediaManager = new LocalMediaManager(mContext, mPackageName,
|
mLocalMediaManager = new LocalMediaManager(mContext, mPackageName);
|
||||||
null /* notification */);
|
|
||||||
}
|
}
|
||||||
mLocalMediaManager.registerCallback(this);
|
mLocalMediaManager.registerCallback(this);
|
||||||
mLocalMediaManager.startScan();
|
mLocalMediaManager.startScan();
|
||||||
|
|||||||
@@ -1,69 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.os.OutcomeReceiver
|
|
||||||
import android.telephony.satellite.SatelliteManager
|
|
||||||
import android.util.Log
|
|
||||||
import androidx.concurrent.futures.CallbackToFutureAdapter
|
|
||||||
import com.google.common.util.concurrent.Futures.immediateFuture
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture
|
|
||||||
import java.util.concurrent.Executor
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility class for interacting with the SatelliteManager API.
|
|
||||||
*/
|
|
||||||
object SatelliteManagerUtil {
|
|
||||||
|
|
||||||
private const val TAG: String = "SatelliteManagerUtil"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the satellite modem is enabled.
|
|
||||||
*
|
|
||||||
* @param context The application context
|
|
||||||
* @param executor The executor to run the asynchronous operation on
|
|
||||||
* @return A ListenableFuture that will resolve to `true` if the satellite modem enabled,
|
|
||||||
* `false` otherwise.
|
|
||||||
*/
|
|
||||||
@JvmStatic
|
|
||||||
fun requestIsEnabled(context: Context, executor: Executor): ListenableFuture<Boolean> {
|
|
||||||
val satelliteManager: SatelliteManager? =
|
|
||||||
context.getSystemService(SatelliteManager::class.java)
|
|
||||||
if (satelliteManager == null) {
|
|
||||||
Log.w(TAG, "SatelliteManager is null")
|
|
||||||
return immediateFuture(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
return CallbackToFutureAdapter.getFuture { completer ->
|
|
||||||
satelliteManager.requestIsEnabled(executor,
|
|
||||||
object : OutcomeReceiver<Boolean, SatelliteManager.SatelliteException> {
|
|
||||||
override fun onResult(result: Boolean) {
|
|
||||||
Log.i(TAG, "Satellite modem enabled status: $result")
|
|
||||||
completer.set(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onError(error: SatelliteManager.SatelliteException) {
|
|
||||||
super.onError(error)
|
|
||||||
Log.w(TAG, "Can't get satellite modem enabled status", error)
|
|
||||||
completer.set(false)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
"requestIsEnabled"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
137
src/com/android/settings/network/SatelliteRepository.kt
Normal file
137
src/com/android/settings/network/SatelliteRepository.kt
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.os.OutcomeReceiver
|
||||||
|
import android.telephony.satellite.SatelliteManager
|
||||||
|
import android.telephony.satellite.SatelliteModemStateCallback
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.annotation.VisibleForTesting
|
||||||
|
import androidx.concurrent.futures.CallbackToFutureAdapter
|
||||||
|
import com.google.common.util.concurrent.Futures.immediateFuture
|
||||||
|
import com.google.common.util.concurrent.ListenableFuture
|
||||||
|
import java.util.concurrent.Executor
|
||||||
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.asExecutor
|
||||||
|
import kotlinx.coroutines.channels.awaitClose
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.callbackFlow
|
||||||
|
import kotlinx.coroutines.flow.flowOf
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A repository class for interacting with the SatelliteManager API.
|
||||||
|
*/
|
||||||
|
class SatelliteRepository(
|
||||||
|
private val context: Context,
|
||||||
|
) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the satellite modem is enabled.
|
||||||
|
*
|
||||||
|
* @param executor The executor to run the asynchronous operation on
|
||||||
|
* @return A ListenableFuture that will resolve to `true` if the satellite modem enabled,
|
||||||
|
* `false` otherwise.
|
||||||
|
*/
|
||||||
|
fun requestIsEnabled(executor: Executor): ListenableFuture<Boolean> {
|
||||||
|
val satelliteManager: SatelliteManager? =
|
||||||
|
context.getSystemService(SatelliteManager::class.java)
|
||||||
|
if (satelliteManager == null) {
|
||||||
|
Log.w(TAG, "SatelliteManager is null")
|
||||||
|
return immediateFuture(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
return CallbackToFutureAdapter.getFuture { completer ->
|
||||||
|
satelliteManager.requestIsEnabled(executor,
|
||||||
|
object : OutcomeReceiver<Boolean, SatelliteManager.SatelliteException> {
|
||||||
|
override fun onResult(result: Boolean) {
|
||||||
|
Log.i(TAG, "Satellite modem enabled status: $result")
|
||||||
|
completer.set(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onError(error: SatelliteManager.SatelliteException) {
|
||||||
|
super.onError(error)
|
||||||
|
Log.w(TAG, "Can't get satellite modem enabled status", error)
|
||||||
|
completer.set(false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
"requestIsEnabled"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a Flow that emits the enabled state of the satellite modem. Updates are triggered
|
||||||
|
* when the modem state changes.
|
||||||
|
*
|
||||||
|
* @param defaultDispatcher The CoroutineDispatcher to use (Defaults to `Dispatchers.Default`).
|
||||||
|
* @return A Flow emitting `true` when the modem is enabled and `false` otherwise.
|
||||||
|
*/
|
||||||
|
fun getIsModemEnabledFlow(
|
||||||
|
defaultDispatcher: CoroutineDispatcher = Dispatchers.Default,
|
||||||
|
): Flow<Boolean> {
|
||||||
|
val satelliteManager: SatelliteManager? =
|
||||||
|
context.getSystemService(SatelliteManager::class.java)
|
||||||
|
if (satelliteManager == null) {
|
||||||
|
Log.w(TAG, "SatelliteManager is null")
|
||||||
|
return flowOf(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
return callbackFlow {
|
||||||
|
val callback = SatelliteModemStateCallback { state ->
|
||||||
|
val isEnabled = convertSatelliteModemStateToEnabledState(state)
|
||||||
|
Log.i(TAG, "Satellite modem state changed: state=$state, isEnabled=$isEnabled")
|
||||||
|
trySend(isEnabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
val result = satelliteManager.registerForModemStateChanged(
|
||||||
|
defaultDispatcher.asExecutor(),
|
||||||
|
callback
|
||||||
|
)
|
||||||
|
Log.i(TAG, "Call registerForModemStateChanged: result=$result")
|
||||||
|
|
||||||
|
awaitClose { satelliteManager.unregisterForModemStateChanged(callback) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a [SatelliteManager.SatelliteModemState] to a boolean representing whether the modem
|
||||||
|
* is enabled.
|
||||||
|
*
|
||||||
|
* @param state The SatelliteModemState provided by the SatelliteManager.
|
||||||
|
* @return `true` if the modem is enabled, `false` otherwise.
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
fun convertSatelliteModemStateToEnabledState(
|
||||||
|
@SatelliteManager.SatelliteModemState state: Int,
|
||||||
|
): Boolean {
|
||||||
|
// Mapping table based on logic from b/315928920#comment24
|
||||||
|
return when (state) {
|
||||||
|
SatelliteManager.SATELLITE_MODEM_STATE_IDLE,
|
||||||
|
SatelliteManager.SATELLITE_MODEM_STATE_LISTENING,
|
||||||
|
SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING,
|
||||||
|
SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_RETRYING,
|
||||||
|
SatelliteManager.SATELLITE_MODEM_STATE_NOT_CONNECTED,
|
||||||
|
SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED -> true
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val TAG: String = "SatelliteRepository"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -46,15 +46,18 @@ import androidx.compose.runtime.rememberCoroutineScope
|
|||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalLifecycleOwner
|
import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.lifecycle.LifecycleRegistry
|
||||||
import com.android.settings.R
|
import com.android.settings.R
|
||||||
import com.android.settings.SidecarFragment
|
import com.android.settings.SidecarFragment
|
||||||
import com.android.settings.network.telephony.SubscriptionActionDialogActivity
|
import com.android.settings.network.telephony.SubscriptionActionDialogActivity
|
||||||
import com.android.settings.network.telephony.ToggleSubscriptionDialogActivity
|
import com.android.settings.network.telephony.ToggleSubscriptionDialogActivity
|
||||||
import com.android.settings.spa.SpaActivity.Companion.startSpaActivity
|
import com.android.settings.spa.SpaActivity.Companion.startSpaActivity
|
||||||
import com.android.settings.spa.network.SimOnboardingPageProvider.getRoute
|
import com.android.settings.spa.network.SimOnboardingPageProvider.getRoute
|
||||||
|
import com.android.settings.wifi.WifiPickerTrackerHelper
|
||||||
import com.android.settingslib.spa.SpaBaseDialogActivity
|
import com.android.settingslib.spa.SpaBaseDialogActivity
|
||||||
import com.android.settingslib.spa.framework.theme.SettingsDimension
|
import com.android.settingslib.spa.framework.theme.SettingsDimension
|
||||||
import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
|
import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
|
||||||
@@ -74,6 +77,8 @@ import kotlinx.coroutines.launch
|
|||||||
|
|
||||||
class SimOnboardingActivity : SpaBaseDialogActivity() {
|
class SimOnboardingActivity : SpaBaseDialogActivity() {
|
||||||
lateinit var scope: CoroutineScope
|
lateinit var scope: CoroutineScope
|
||||||
|
lateinit var wifiPickerTrackerHelper: WifiPickerTrackerHelper
|
||||||
|
lateinit var context: Context
|
||||||
lateinit var showStartingDialog: MutableState<Boolean>
|
lateinit var showStartingDialog: MutableState<Boolean>
|
||||||
lateinit var showError: MutableState<ErrorType>
|
lateinit var showError: MutableState<ErrorType>
|
||||||
lateinit var showProgressDialog: MutableState<Boolean>
|
lateinit var showProgressDialog: MutableState<Boolean>
|
||||||
@@ -86,6 +91,7 @@ class SimOnboardingActivity : SpaBaseDialogActivity() {
|
|||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
if (!this.userManager.isAdminUser) {
|
if (!this.userManager.isAdminUser) {
|
||||||
Log.e(TAG, "It is not the admin user. Unable to toggle subscription.")
|
Log.e(TAG, "It is not the admin user. Unable to toggle subscription.")
|
||||||
finish()
|
finish()
|
||||||
@@ -152,7 +158,10 @@ class SimOnboardingActivity : SpaBaseDialogActivity() {
|
|||||||
|
|
||||||
CallbackType.CALLBACK_SETUP_PRIMARY_SIM -> {
|
CallbackType.CALLBACK_SETUP_PRIMARY_SIM -> {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
onboardingService.startSetupPrimarySim(this@SimOnboardingActivity)
|
onboardingService.startSetupPrimarySim(
|
||||||
|
this@SimOnboardingActivity,
|
||||||
|
wifiPickerTrackerHelper
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,6 +193,12 @@ class SimOnboardingActivity : SpaBaseDialogActivity() {
|
|||||||
showDsdsProgressDialog = rememberSaveable { mutableStateOf(false) }
|
showDsdsProgressDialog = rememberSaveable { mutableStateOf(false) }
|
||||||
showRestartDialog = rememberSaveable { mutableStateOf(false) }
|
showRestartDialog = rememberSaveable { mutableStateOf(false) }
|
||||||
scope = rememberCoroutineScope()
|
scope = rememberCoroutineScope()
|
||||||
|
context = LocalContext.current
|
||||||
|
val lifecycleOwner = LocalLifecycleOwner.current
|
||||||
|
wifiPickerTrackerHelper = WifiPickerTrackerHelper(
|
||||||
|
LifecycleRegistry(lifecycleOwner), context,
|
||||||
|
null /* WifiPickerTrackerCallback */
|
||||||
|
)
|
||||||
|
|
||||||
registerSidecarReceiverFlow()
|
registerSidecarReceiverFlow()
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import com.android.settings.spa.network.setAutomaticData
|
|||||||
import com.android.settings.spa.network.setDefaultData
|
import com.android.settings.spa.network.setDefaultData
|
||||||
import com.android.settings.spa.network.setDefaultSms
|
import com.android.settings.spa.network.setDefaultSms
|
||||||
import com.android.settings.spa.network.setDefaultVoice
|
import com.android.settings.spa.network.setDefaultVoice
|
||||||
|
import com.android.settings.wifi.WifiPickerTrackerHelper
|
||||||
import com.android.settingslib.utils.ThreadUtils
|
import com.android.settingslib.utils.ThreadUtils
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
@@ -336,14 +337,17 @@ class SimOnboardingService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun startSetupPrimarySim(context: Context) {
|
suspend fun startSetupPrimarySim(
|
||||||
|
context: Context,
|
||||||
|
wifiPickerTrackerHelper: WifiPickerTrackerHelper
|
||||||
|
) {
|
||||||
withContext(Dispatchers.Default) {
|
withContext(Dispatchers.Default) {
|
||||||
setDefaultVoice(subscriptionManager, targetPrimarySimCalls)
|
setDefaultVoice(subscriptionManager, targetPrimarySimCalls)
|
||||||
setDefaultSms(subscriptionManager, targetPrimarySimTexts)
|
setDefaultSms(subscriptionManager, targetPrimarySimTexts)
|
||||||
setDefaultData(
|
setDefaultData(
|
||||||
context,
|
context,
|
||||||
subscriptionManager,
|
subscriptionManager,
|
||||||
null,
|
wifiPickerTrackerHelper,
|
||||||
targetPrimarySimMobileData
|
targetPrimarySimMobileData
|
||||||
)
|
)
|
||||||
TelephonyRepository(context).setAutomaticData(
|
TelephonyRepository(context).setAutomaticData(
|
||||||
|
|||||||
@@ -26,16 +26,19 @@ import androidx.compose.ui.platform.LocalContext
|
|||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.android.settings.R
|
import com.android.settings.R
|
||||||
|
import com.android.settings.network.SatelliteRepository
|
||||||
import com.android.settings.network.SubscriptionUtil
|
import com.android.settings.network.SubscriptionUtil
|
||||||
import com.android.settings.spa.preference.ComposePreferenceController
|
import com.android.settings.spa.preference.ComposePreferenceController
|
||||||
import com.android.settingslib.spa.widget.preference.MainSwitchPreference
|
import com.android.settingslib.spa.widget.preference.MainSwitchPreference
|
||||||
import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
|
import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
|
||||||
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
|
|
||||||
class MobileNetworkSwitchController @JvmOverloads constructor(
|
class MobileNetworkSwitchController @JvmOverloads constructor(
|
||||||
context: Context,
|
context: Context,
|
||||||
preferenceKey: String,
|
preferenceKey: String,
|
||||||
private val subscriptionRepository: SubscriptionRepository = SubscriptionRepository(context),
|
private val subscriptionRepository: SubscriptionRepository = SubscriptionRepository(context),
|
||||||
|
private val satelliteRepository: SatelliteRepository = SatelliteRepository(context)
|
||||||
) : ComposePreferenceController(context, preferenceKey) {
|
) : ComposePreferenceController(context, preferenceKey) {
|
||||||
|
|
||||||
private var subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID
|
private var subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID
|
||||||
@@ -54,7 +57,12 @@ class MobileNetworkSwitchController @JvmOverloads constructor(
|
|||||||
subscriptionRepository.isSubscriptionEnabledFlow(subId)
|
subscriptionRepository.isSubscriptionEnabledFlow(subId)
|
||||||
}.collectAsStateWithLifecycle(initialValue = null)
|
}.collectAsStateWithLifecycle(initialValue = null)
|
||||||
val changeable by remember {
|
val changeable by remember {
|
||||||
context.callStateFlow(subId).map { it == TelephonyManager.CALL_STATE_IDLE }
|
combine(
|
||||||
|
context.callStateFlow(subId).map { it == TelephonyManager.CALL_STATE_IDLE },
|
||||||
|
satelliteRepository.getIsModemEnabledFlow()
|
||||||
|
) { isCallStateIdle, isSatelliteModemEnabled ->
|
||||||
|
isCallStateIdle && !isSatelliteModemEnabled
|
||||||
|
}
|
||||||
}.collectAsStateWithLifecycle(initialValue = true)
|
}.collectAsStateWithLifecycle(initialValue = true)
|
||||||
MainSwitchPreference(model = object : SwitchPreferenceModel {
|
MainSwitchPreference(model = object : SwitchPreferenceModel {
|
||||||
override val title = stringResource(R.string.mobile_network_use_sim_on)
|
override val title = stringResource(R.string.mobile_network_use_sim_on)
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ import android.telephony.SubscriptionManager
|
|||||||
import android.telephony.TelephonyCallback
|
import android.telephony.TelephonyCallback
|
||||||
import android.telephony.TelephonyManager
|
import android.telephony.TelephonyManager
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import com.android.settings.network.mobileDataEnabledFlow
|
||||||
|
import com.android.settings.wifi.WifiPickerTrackerHelper
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.asExecutor
|
import kotlinx.coroutines.asExecutor
|
||||||
import kotlinx.coroutines.channels.ProducerScope
|
import kotlinx.coroutines.channels.ProducerScope
|
||||||
@@ -62,6 +64,42 @@ class TelephonyRepository(
|
|||||||
telephonyManager.setMobileDataPolicyEnabled(policy, enabled)
|
telephonyManager.setMobileDataPolicyEnabled(policy, enabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isDataEnabled(
|
||||||
|
subId: Int,
|
||||||
|
): Flow<Boolean> {
|
||||||
|
if (!SubscriptionManager.isValidSubscriptionId(subId)) return flowOf(false)
|
||||||
|
|
||||||
|
Log.d(TAG, "register mobileDataEnabledFlow: [$subId]")
|
||||||
|
return context.mobileDataEnabledFlow(subId)
|
||||||
|
.map {
|
||||||
|
Log.d(TAG, "mobileDataEnabledFlow: receive mobile data [$subId] start")
|
||||||
|
val telephonyManager = context.telephonyManager(subId)
|
||||||
|
telephonyManager.isDataEnabledForReason(TelephonyManager.DATA_ENABLED_REASON_USER)
|
||||||
|
.also { Log.d(TAG, "mobileDataEnabledFlow: [$subId] isDataEnabled(): $it") }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setMobileData(
|
||||||
|
subId: Int,
|
||||||
|
enabled: Boolean,
|
||||||
|
wifiPickerTrackerHelper: WifiPickerTrackerHelper? = null
|
||||||
|
) {
|
||||||
|
if (!SubscriptionManager.isValidSubscriptionId(subId)) return
|
||||||
|
|
||||||
|
Log.d(TAG, "setMobileData: $enabled")
|
||||||
|
MobileNetworkUtils.setMobileDataEnabled(
|
||||||
|
context,
|
||||||
|
subId,
|
||||||
|
enabled /* enabled */,
|
||||||
|
true /* disableOtherSubscriptions */
|
||||||
|
)
|
||||||
|
|
||||||
|
if (wifiPickerTrackerHelper != null
|
||||||
|
&& !wifiPickerTrackerHelper.isCarrierNetworkProvisionEnabled(subId)
|
||||||
|
) {
|
||||||
|
wifiPickerTrackerHelper.setCarrierNetworkEnabled(enabled)
|
||||||
|
}
|
||||||
|
}
|
||||||
private companion object {
|
private companion object {
|
||||||
private const val TAG = "TelephonyRepository"
|
private const val TAG = "TelephonyRepository"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ public class RemoteVolumeGroupController extends BasePreferenceController implem
|
|||||||
public RemoteVolumeGroupController(Context context, String preferenceKey) {
|
public RemoteVolumeGroupController(Context context, String preferenceKey) {
|
||||||
super(context, preferenceKey);
|
super(context, preferenceKey);
|
||||||
if (mLocalMediaManager == null) {
|
if (mLocalMediaManager == null) {
|
||||||
mLocalMediaManager = new LocalMediaManager(mContext, null, null);
|
mLocalMediaManager = new LocalMediaManager(mContext, /* packageName= */ null);
|
||||||
mLocalMediaManager.registerCallback(this);
|
mLocalMediaManager.registerCallback(this);
|
||||||
mLocalMediaManager.startScan();
|
mLocalMediaManager.startScan();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,6 +123,12 @@ public class SetupPreFinishDelayFragment extends InstrumentedFragment {
|
|||||||
sHandler.postDelayed(mRunnable, MAX_DELAY_BEFORE_SETUP_FINISH);
|
sHandler.postDelayed(mRunnable, MAX_DELAY_BEFORE_SETUP_FINISH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
sHandler.removeCallbacks(mRunnable);
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMetricsCategory() {
|
public int getMetricsCategory() {
|
||||||
return SettingsEnums.PRIVATE_SPACE_SETUP_PRE_FINISH;
|
return SettingsEnums.PRIVATE_SPACE_SETUP_PRE_FINISH;
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ import android.util.Log;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.network.SatelliteManagerUtil;
|
import com.android.settings.network.SatelliteRepository;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
@@ -58,8 +58,8 @@ public class SimSlotChangeReceiver extends BroadcastReceiver {
|
|||||||
if (shouldHandleSlotChange(context)) {
|
if (shouldHandleSlotChange(context)) {
|
||||||
Log.d(TAG, "Checking satellite enabled status");
|
Log.d(TAG, "Checking satellite enabled status");
|
||||||
Executor executor = Executors.newSingleThreadExecutor();
|
Executor executor = Executors.newSingleThreadExecutor();
|
||||||
ListenableFuture<Boolean> satelliteEnabledFuture = SatelliteManagerUtil
|
ListenableFuture<Boolean> satelliteEnabledFuture = new SatelliteRepository(context)
|
||||||
.requestIsEnabled(context, executor);
|
.requestIsEnabled(executor);
|
||||||
satelliteEnabledFuture.addListener(() -> {
|
satelliteEnabledFuture.addListener(() -> {
|
||||||
boolean isSatelliteEnabled = false;
|
boolean isSatelliteEnabled = false;
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import android.content.Intent
|
|||||||
import android.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
import android.content.pm.ApplicationInfo
|
import android.content.pm.ApplicationInfo
|
||||||
import android.content.pm.PackageInstaller
|
import android.content.pm.PackageInstaller
|
||||||
|
import android.content.pm.PackageManager
|
||||||
import android.os.UserHandle
|
import android.os.UserHandle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
@@ -87,11 +88,15 @@ class AppArchiveButton(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun ApplicationInfo.isActionButtonEnabled(): Boolean {
|
private fun ApplicationInfo.isActionButtonEnabled(): Boolean {
|
||||||
return !isArchived
|
return try {
|
||||||
&& userPackageManager.isAppArchivable(packageName)
|
(!isArchived
|
||||||
// We apply the same device policy for both the uninstallation and archive
|
&& userPackageManager.isAppArchivable(packageName)
|
||||||
// button.
|
// We apply the same device policy for both the uninstallation and archive
|
||||||
&& !appButtonRepository.isUninstallBlockedByAdmin(this)
|
// button.
|
||||||
|
&& !appButtonRepository.isUninstallBlockedByAdmin(this))
|
||||||
|
} catch (e: PackageManager.NameNotFoundException) {
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onArchiveClicked(app: ApplicationInfo) {
|
private fun onArchiveClicked(app: ApplicationInfo) {
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* 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.spa.network
|
||||||
|
|
||||||
|
import android.telephony.TelephonyManager
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import com.android.settings.R
|
||||||
|
import com.android.settings.network.telephony.TelephonyRepository
|
||||||
|
import com.android.settingslib.spa.widget.preference.SwitchPreference
|
||||||
|
import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun MobileDataSwitchingPreference(
|
||||||
|
isMobileDataEnabled: () -> Boolean?,
|
||||||
|
setMobileDataEnabled: (newEnabled: Boolean) -> Unit,
|
||||||
|
) {
|
||||||
|
val mobileDataSummary = stringResource(id = R.string.primary_sim_automatic_data_msg)
|
||||||
|
val coroutineScope = rememberCoroutineScope()
|
||||||
|
SwitchPreference(
|
||||||
|
object : SwitchPreferenceModel {
|
||||||
|
override val title = stringResource(id = R.string.mobile_data_settings_title)
|
||||||
|
override val summary = { mobileDataSummary }
|
||||||
|
override val checked = { isMobileDataEnabled() }
|
||||||
|
override val onCheckedChange: (Boolean) -> Unit = { newEnabled ->
|
||||||
|
coroutineScope.launch(Dispatchers.Default) {
|
||||||
|
setMobileDataEnabled(newEnabled)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
override val changeable:() -> Boolean = {true}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -38,11 +38,12 @@ import androidx.compose.ui.platform.LocalContext
|
|||||||
import androidx.compose.ui.platform.LocalLifecycleOwner
|
import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.res.vectorResource
|
import androidx.compose.ui.res.vectorResource
|
||||||
|
import androidx.lifecycle.LifecycleOwner
|
||||||
|
import androidx.lifecycle.LifecycleRegistry
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import com.android.settings.R
|
import com.android.settings.R
|
||||||
import com.android.settings.network.SubscriptionInfoListViewModel
|
import com.android.settings.network.SubscriptionInfoListViewModel
|
||||||
import com.android.settings.network.telephony.MobileNetworkUtils
|
|
||||||
import com.android.settings.network.telephony.TelephonyRepository
|
import com.android.settings.network.telephony.TelephonyRepository
|
||||||
import com.android.settings.spa.network.PrimarySimRepository.PrimarySimInfo
|
import com.android.settings.spa.network.PrimarySimRepository.PrimarySimInfo
|
||||||
import com.android.settings.wifi.WifiPickerTrackerHelper
|
import com.android.settings.wifi.WifiPickerTrackerHelper
|
||||||
@@ -167,7 +168,7 @@ fun PageImpl(
|
|||||||
defaultVoiceSubId: MutableIntState,
|
defaultVoiceSubId: MutableIntState,
|
||||||
defaultSmsSubId: MutableIntState,
|
defaultSmsSubId: MutableIntState,
|
||||||
defaultDataSubId: MutableIntState,
|
defaultDataSubId: MutableIntState,
|
||||||
nonDds: MutableIntState
|
nonDds: MutableIntState,
|
||||||
) {
|
) {
|
||||||
val selectableSubscriptionInfoList by selectableSubscriptionInfoListFlow
|
val selectableSubscriptionInfoList by selectableSubscriptionInfoListFlow
|
||||||
.collectAsStateWithLifecycle(initialValue = emptyList())
|
.collectAsStateWithLifecycle(initialValue = emptyList())
|
||||||
@@ -175,22 +176,76 @@ fun PageImpl(
|
|||||||
val stringSims = stringResource(R.string.provider_network_settings_title)
|
val stringSims = stringResource(R.string.provider_network_settings_title)
|
||||||
RegularScaffold(title = stringSims) {
|
RegularScaffold(title = stringSims) {
|
||||||
SimsSection(selectableSubscriptionInfoList)
|
SimsSection(selectableSubscriptionInfoList)
|
||||||
|
MobileDataSectionImpl(defaultDataSubId,
|
||||||
|
nonDds,
|
||||||
|
)
|
||||||
|
|
||||||
PrimarySimSectionImpl(
|
PrimarySimSectionImpl(
|
||||||
selectableSubscriptionInfoListFlow,
|
selectableSubscriptionInfoListFlow,
|
||||||
defaultVoiceSubId,
|
defaultVoiceSubId,
|
||||||
defaultSmsSubId,
|
defaultSmsSubId,
|
||||||
defaultDataSubId,
|
defaultDataSubId,
|
||||||
nonDds
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun MobileDataSectionImpl(
|
||||||
|
mobileDataSelectedId: MutableIntState,
|
||||||
|
nonDds: MutableIntState,
|
||||||
|
) {
|
||||||
|
val context = LocalContext.current
|
||||||
|
val localLifecycleOwner = LocalLifecycleOwner.current
|
||||||
|
val wifiPickerTrackerHelper = getWifiPickerTrackerHelper(context, localLifecycleOwner)
|
||||||
|
|
||||||
|
val subscriptionManager: SubscriptionManager? =
|
||||||
|
context.getSystemService(SubscriptionManager::class.java)
|
||||||
|
|
||||||
|
Category(title = stringResource(id = R.string.mobile_data_settings_title)) {
|
||||||
|
val isAutoDataEnabled by remember(nonDds.intValue) {
|
||||||
|
TelephonyRepository(context).isMobileDataPolicyEnabledFlow(
|
||||||
|
subId = nonDds.intValue,
|
||||||
|
policy = TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH
|
||||||
|
)
|
||||||
|
}.collectAsStateWithLifecycle(initialValue = null)
|
||||||
|
|
||||||
|
val mobileDataStateChanged by remember(mobileDataSelectedId.intValue) {
|
||||||
|
TelephonyRepository(context).isDataEnabled(mobileDataSelectedId.intValue)
|
||||||
|
}.collectAsStateWithLifecycle(initialValue = false)
|
||||||
|
val coroutineScope = rememberCoroutineScope()
|
||||||
|
|
||||||
|
MobileDataSwitchingPreference(
|
||||||
|
isMobileDataEnabled = { mobileDataStateChanged },
|
||||||
|
setMobileDataEnabled = { newEnabled ->
|
||||||
|
coroutineScope.launch {
|
||||||
|
setMobileData(
|
||||||
|
context,
|
||||||
|
subscriptionManager,
|
||||||
|
wifiPickerTrackerHelper,
|
||||||
|
mobileDataSelectedId.intValue,
|
||||||
|
newEnabled
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if (nonDds.intValue != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
|
||||||
|
AutomaticDataSwitchingPreference(
|
||||||
|
isAutoDataEnabled = { isAutoDataEnabled },
|
||||||
|
setAutoDataEnabled = { newEnabled ->
|
||||||
|
TelephonyRepository(context).setAutomaticData(nonDds.intValue, newEnabled)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun PrimarySimImpl(
|
fun PrimarySimImpl(
|
||||||
primarySimInfo: PrimarySimInfo,
|
primarySimInfo: PrimarySimInfo,
|
||||||
callsSelectedId: MutableIntState,
|
callsSelectedId: MutableIntState,
|
||||||
textsSelectedId: MutableIntState,
|
textsSelectedId: MutableIntState,
|
||||||
mobileDataSelectedId: MutableIntState,
|
mobileDataSelectedId: MutableIntState,
|
||||||
|
wifiPickerTrackerHelper: WifiPickerTrackerHelper? = null,
|
||||||
subscriptionManager: SubscriptionManager? =
|
subscriptionManager: SubscriptionManager? =
|
||||||
LocalContext.current.getSystemService(SubscriptionManager::class.java),
|
LocalContext.current.getSystemService(SubscriptionManager::class.java),
|
||||||
coroutineScope: CoroutineScope = rememberCoroutineScope(),
|
coroutineScope: CoroutineScope = rememberCoroutineScope(),
|
||||||
@@ -208,20 +263,15 @@ fun PrimarySimImpl(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
actionSetMobileData: (Int) -> Unit = {
|
actionSetMobileData: (Int) -> Unit = {
|
||||||
mobileDataSelectedId.intValue = it
|
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
// TODO: to fix the WifiPickerTracker crash when create
|
|
||||||
// the wifiPickerTrackerHelper
|
|
||||||
setDefaultData(
|
setDefaultData(
|
||||||
context,
|
context,
|
||||||
subscriptionManager,
|
subscriptionManager,
|
||||||
null/*wifiPickerTrackerHelper*/,
|
wifiPickerTrackerHelper,
|
||||||
it
|
it
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
isAutoDataEnabled: () -> Boolean?,
|
|
||||||
setAutoDataEnabled: (newEnabled: Boolean) -> Unit,
|
|
||||||
) {
|
) {
|
||||||
CreatePrimarySimListPreference(
|
CreatePrimarySimListPreference(
|
||||||
stringResource(id = R.string.primary_sim_calls_title),
|
stringResource(id = R.string.primary_sim_calls_title),
|
||||||
@@ -244,8 +294,6 @@ fun PrimarySimImpl(
|
|||||||
Icons.Outlined.DataUsage,
|
Icons.Outlined.DataUsage,
|
||||||
actionSetMobileData
|
actionSetMobileData
|
||||||
)
|
)
|
||||||
|
|
||||||
AutomaticDataSwitchingPreference(isAutoDataEnabled, setAutoDataEnabled)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@@ -254,9 +302,11 @@ fun PrimarySimSectionImpl(
|
|||||||
callsSelectedId: MutableIntState,
|
callsSelectedId: MutableIntState,
|
||||||
textsSelectedId: MutableIntState,
|
textsSelectedId: MutableIntState,
|
||||||
mobileDataSelectedId: MutableIntState,
|
mobileDataSelectedId: MutableIntState,
|
||||||
nonDds: MutableIntState,
|
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
val localLifecycleOwner = LocalLifecycleOwner.current
|
||||||
|
val wifiPickerTrackerHelper = getWifiPickerTrackerHelper(context, localLifecycleOwner)
|
||||||
|
|
||||||
val primarySimInfo = remember(subscriptionInfoListFlow) {
|
val primarySimInfo = remember(subscriptionInfoListFlow) {
|
||||||
subscriptionInfoListFlow
|
subscriptionInfoListFlow
|
||||||
.map { subscriptionInfoList ->
|
.map { subscriptionInfoList ->
|
||||||
@@ -267,25 +317,25 @@ fun PrimarySimSectionImpl(
|
|||||||
}.collectAsStateWithLifecycle(initialValue = null).value ?: return
|
}.collectAsStateWithLifecycle(initialValue = null).value ?: return
|
||||||
|
|
||||||
Category(title = stringResource(id = R.string.primary_sim_title)) {
|
Category(title = stringResource(id = R.string.primary_sim_title)) {
|
||||||
val isAutoDataEnabled by remember(nonDds.intValue) {
|
|
||||||
TelephonyRepository(context).isMobileDataPolicyEnabledFlow(
|
|
||||||
subId = nonDds.intValue,
|
|
||||||
policy = TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH
|
|
||||||
)
|
|
||||||
}.collectAsStateWithLifecycle(initialValue = null)
|
|
||||||
PrimarySimImpl(
|
PrimarySimImpl(
|
||||||
primarySimInfo,
|
primarySimInfo,
|
||||||
callsSelectedId,
|
callsSelectedId,
|
||||||
textsSelectedId,
|
textsSelectedId,
|
||||||
mobileDataSelectedId,
|
mobileDataSelectedId,
|
||||||
isAutoDataEnabled = { isAutoDataEnabled },
|
wifiPickerTrackerHelper
|
||||||
setAutoDataEnabled = { newEnabled ->
|
|
||||||
TelephonyRepository(context).setAutomaticData(nonDds.intValue, newEnabled)
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getWifiPickerTrackerHelper(
|
||||||
|
context: Context,
|
||||||
|
lifecycleOwner: LifecycleOwner
|
||||||
|
): WifiPickerTrackerHelper {
|
||||||
|
return WifiPickerTrackerHelper(
|
||||||
|
LifecycleRegistry(lifecycleOwner), context,
|
||||||
|
null /* WifiPickerTrackerCallback */
|
||||||
|
)
|
||||||
|
}
|
||||||
private fun Context.defaultVoiceSubscriptionFlow(): Flow<Int> =
|
private fun Context.defaultVoiceSubscriptionFlow(): Flow<Int> =
|
||||||
merge(
|
merge(
|
||||||
flowOf(null), // kick an initial value
|
flowOf(null), // kick an initial value
|
||||||
@@ -334,19 +384,28 @@ suspend fun setDefaultData(
|
|||||||
subscriptionManager: SubscriptionManager?,
|
subscriptionManager: SubscriptionManager?,
|
||||||
wifiPickerTrackerHelper: WifiPickerTrackerHelper?,
|
wifiPickerTrackerHelper: WifiPickerTrackerHelper?,
|
||||||
subId: Int
|
subId: Int
|
||||||
|
): Unit =
|
||||||
|
setMobileData(
|
||||||
|
context,
|
||||||
|
subscriptionManager,
|
||||||
|
wifiPickerTrackerHelper,
|
||||||
|
subId,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
|
||||||
|
suspend fun setMobileData(
|
||||||
|
context: Context,
|
||||||
|
subscriptionManager: SubscriptionManager?,
|
||||||
|
wifiPickerTrackerHelper: WifiPickerTrackerHelper?,
|
||||||
|
subId: Int,
|
||||||
|
enabled: Boolean,
|
||||||
): Unit =
|
): Unit =
|
||||||
withContext(Dispatchers.Default) {
|
withContext(Dispatchers.Default) {
|
||||||
subscriptionManager?.setDefaultDataSubId(subId)
|
Log.d(NetworkCellularGroupProvider.name, "setMobileData: $enabled")
|
||||||
Log.d(NetworkCellularGroupProvider.name, "setMobileDataEnabled: true")
|
if (enabled) {
|
||||||
MobileNetworkUtils.setMobileDataEnabled(
|
Log.d(NetworkCellularGroupProvider.name, "setDefaultData: [$subId]")
|
||||||
context,
|
subscriptionManager?.setDefaultDataSubId(subId)
|
||||||
subId,
|
|
||||||
true /* enabled */,
|
|
||||||
true /* disableOtherSubscriptions */
|
|
||||||
)
|
|
||||||
if (wifiPickerTrackerHelper != null
|
|
||||||
&& !wifiPickerTrackerHelper.isCarrierNetworkProvisionEnabled(subId)
|
|
||||||
) {
|
|
||||||
wifiPickerTrackerHelper.setCarrierNetworkEnabled(true)
|
|
||||||
}
|
}
|
||||||
}
|
TelephonyRepository(context)
|
||||||
|
.setMobileData(subId, enabled, wifiPickerTrackerHelper)
|
||||||
|
}
|
||||||
@@ -102,18 +102,21 @@ fun SimOnboardingPrimarySimImpl(
|
|||||||
mobileDataSelectedId = mobileDataSelectedId,
|
mobileDataSelectedId = mobileDataSelectedId,
|
||||||
actionSetCalls = {
|
actionSetCalls = {
|
||||||
callsSelectedId.intValue = it
|
callsSelectedId.intValue = it
|
||||||
onboardingService.targetPrimarySimCalls = it},
|
onboardingService.targetPrimarySimCalls = it
|
||||||
|
},
|
||||||
actionSetTexts = {
|
actionSetTexts = {
|
||||||
textsSelectedId.intValue = it
|
textsSelectedId.intValue = it
|
||||||
onboardingService.targetPrimarySimTexts = it},
|
onboardingService.targetPrimarySimTexts = it
|
||||||
|
},
|
||||||
actionSetMobileData = {
|
actionSetMobileData = {
|
||||||
mobileDataSelectedId.intValue = it
|
mobileDataSelectedId.intValue = it
|
||||||
onboardingService.targetPrimarySimMobileData = it},
|
onboardingService.targetPrimarySimMobileData = it
|
||||||
isAutoDataEnabled = { isAutoDataEnabled },
|
}
|
||||||
|
)
|
||||||
|
AutomaticDataSwitchingPreference(isAutoDataEnabled = { isAutoDataEnabled },
|
||||||
setAutoDataEnabled = { newEnabled ->
|
setAutoDataEnabled = { newEnabled ->
|
||||||
onboardingService.targetPrimarySimAutoDataSwitch.value = newEnabled
|
onboardingService.targetPrimarySimAutoDataSwitch.value = newEnabled
|
||||||
},
|
})
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,6 @@ import org.mockito.Mock;
|
|||||||
import org.mockito.junit.MockitoJUnit;
|
import org.mockito.junit.MockitoJUnit;
|
||||||
import org.mockito.junit.MockitoRule;
|
import org.mockito.junit.MockitoRule;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
import org.robolectric.annotation.LooperMode;
|
|
||||||
import org.robolectric.shadows.ShadowApplication;
|
import org.robolectric.shadows.ShadowApplication;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -63,7 +62,6 @@ import java.util.List;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
@LooperMode(LooperMode.Mode.LEGACY)
|
|
||||||
public final class InstalledAppCounterTest {
|
public final class InstalledAppCounterTest {
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
|
|||||||
@@ -79,7 +79,6 @@ import org.mockito.MockitoAnnotations;
|
|||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
import org.robolectric.RuntimeEnvironment;
|
import org.robolectric.RuntimeEnvironment;
|
||||||
import org.robolectric.android.controller.ActivityController;
|
import org.robolectric.android.controller.ActivityController;
|
||||||
import org.robolectric.annotation.LooperMode;
|
|
||||||
import org.robolectric.util.ReflectionHelpers;
|
import org.robolectric.util.ReflectionHelpers;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -88,7 +87,6 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||||||
|
|
||||||
@Ignore("b/295325503")
|
@Ignore("b/295325503")
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
@LooperMode(LooperMode.Mode.LEGACY)
|
|
||||||
public class FingerprintEnrollEnrollingTest {
|
public class FingerprintEnrollEnrollingTest {
|
||||||
private static final String ENROLL_PROGRESS_COLOR_LIGHT = "#699FF3";
|
private static final String ENROLL_PROGRESS_COLOR_LIGHT = "#699FF3";
|
||||||
private static final String ENROLL_PROGRESS_COLOR_DARK = "#7DA7F1";
|
private static final String ENROLL_PROGRESS_COLOR_DARK = "#7DA7F1";
|
||||||
|
|||||||
@@ -35,12 +35,14 @@ import android.bluetooth.BluetoothCodecType;
|
|||||||
import android.bluetooth.BluetoothDevice;
|
import android.bluetooth.BluetoothDevice;
|
||||||
import android.bluetooth.BluetoothProfile;
|
import android.bluetooth.BluetoothProfile;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.platform.test.annotations.RequiresFlagsEnabled;
|
||||||
|
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
import androidx.preference.ListPreference;
|
import androidx.preference.ListPreference;
|
||||||
import androidx.preference.PreferenceScreen;
|
import androidx.preference.PreferenceScreen;
|
||||||
|
|
||||||
import com.android.settings.development.BluetoothA2dpConfigStore;
|
import com.android.settings.development.BluetoothA2dpConfigStore;
|
||||||
|
import com.android.settings.development.Flags;
|
||||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -57,7 +59,6 @@ import java.util.List;
|
|||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
public class BluetoothCodecListPreferenceControllerTest {
|
public class BluetoothCodecListPreferenceControllerTest {
|
||||||
|
|
||||||
private static final String DEVICE_ADDRESS = "00:11:22:33:44:55";
|
private static final String DEVICE_ADDRESS = "00:11:22:33:44:55";
|
||||||
|
|
||||||
@Mock private BluetoothA2dp mBluetoothA2dp;
|
@Mock private BluetoothA2dp mBluetoothA2dp;
|
||||||
@@ -245,6 +246,7 @@ public class BluetoothCodecListPreferenceControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@RequiresFlagsEnabled(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY_SETTINGS)
|
||||||
public void onPreferenceChange_notifyPreference() {
|
public void onPreferenceChange_notifyPreference() {
|
||||||
assertFalse(
|
assertFalse(
|
||||||
mController.onPreferenceChange(
|
mController.onPreferenceChange(
|
||||||
|
|||||||
@@ -1,71 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2019 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.language;
|
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.spy;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.content.ContentResolver;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.provider.Settings;
|
|
||||||
import android.view.inputmethod.InputMethodInfo;
|
|
||||||
|
|
||||||
import com.android.settings.testutils.shadow.ShadowInputMethodManagerWithMethodList;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.robolectric.RobolectricTestRunner;
|
|
||||||
import org.robolectric.RuntimeEnvironment;
|
|
||||||
import org.robolectric.annotation.Config;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
|
||||||
@Config(shadows = ShadowInputMethodManagerWithMethodList.class)
|
|
||||||
public class LanguageAndInputPreferenceControllerTest {
|
|
||||||
private Context mContext;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() {
|
|
||||||
mContext = spy(RuntimeEnvironment.application);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getSummary_shouldSetToCurrentImeName() {
|
|
||||||
final ComponentName componentName = new ComponentName("name1", "cls");
|
|
||||||
final ContentResolver cr = mContext.getContentResolver();
|
|
||||||
Settings.Secure.putString(cr, Settings.Secure.DEFAULT_INPUT_METHOD,
|
|
||||||
componentName.flattenToString());
|
|
||||||
final List<InputMethodInfo> imis = new ArrayList<>();
|
|
||||||
imis.add(mock(InputMethodInfo.class));
|
|
||||||
when(imis.get(0).getPackageName()).thenReturn("name1");
|
|
||||||
when(imis.get(0).loadLabel(any())).thenReturn("label");
|
|
||||||
ShadowInputMethodManagerWithMethodList.getShadow().setInputMethodList(imis);
|
|
||||||
|
|
||||||
final LanguageAndInputPreferenceController controller =
|
|
||||||
new LanguageAndInputPreferenceController(mContext, "key");
|
|
||||||
|
|
||||||
assertThat(controller.getSummary().toString()).contains("label");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,185 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2016 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.language;
|
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
|
||||||
import static org.mockito.Mockito.doReturn;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.spy;
|
|
||||||
import static org.mockito.Mockito.times;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.admin.DevicePolicyManager;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.hardware.input.InputManager;
|
|
||||||
import android.os.UserManager;
|
|
||||||
import android.util.FeatureFlagUtils;
|
|
||||||
import android.view.autofill.AutofillManager;
|
|
||||||
import android.view.inputmethod.InputMethodManager;
|
|
||||||
import android.view.textservice.TextServicesManager;
|
|
||||||
|
|
||||||
import androidx.lifecycle.LifecycleObserver;
|
|
||||||
|
|
||||||
import com.android.settings.R;
|
|
||||||
import com.android.settings.testutils.XmlTestUtils;
|
|
||||||
import com.android.settingslib.core.AbstractPreferenceController;
|
|
||||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.Answers;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.MockitoAnnotations;
|
|
||||||
import org.robolectric.RobolectricTestRunner;
|
|
||||||
import org.robolectric.RuntimeEnvironment;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
|
||||||
public class LanguageAndInputSettingsTest {
|
|
||||||
|
|
||||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
|
||||||
private Activity mActivity;
|
|
||||||
@Mock
|
|
||||||
private InputManager mIm;
|
|
||||||
@Mock
|
|
||||||
private InputMethodManager mImm;
|
|
||||||
@Mock
|
|
||||||
private DevicePolicyManager mDpm;
|
|
||||||
@Mock
|
|
||||||
private AutofillManager mAutofillManager;
|
|
||||||
private TestFragment mFragment;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() {
|
|
||||||
MockitoAnnotations.initMocks(this);
|
|
||||||
when(mActivity.getSystemService(Context.USER_SERVICE)).thenReturn(mock(UserManager.class));
|
|
||||||
when(mActivity.getSystemService(Context.INPUT_SERVICE))
|
|
||||||
.thenReturn(mock(InputManager.class));
|
|
||||||
when(mActivity.getSystemService(Context.INPUT_SERVICE)).thenReturn(mIm);
|
|
||||||
when(mActivity.getSystemService(Context.TEXT_SERVICES_MANAGER_SERVICE))
|
|
||||||
.thenReturn(mock(TextServicesManager.class));
|
|
||||||
when(mActivity.getSystemService(Context.DEVICE_POLICY_SERVICE)).thenReturn(mDpm);
|
|
||||||
when(mActivity.getSystemService(Context.INPUT_METHOD_SERVICE)).thenReturn(mImm);
|
|
||||||
when((Object) mActivity.getSystemService(AutofillManager.class))
|
|
||||||
.thenReturn(mAutofillManager);
|
|
||||||
mFragment = new TestFragment(mActivity);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetPreferenceScreenResId() {
|
|
||||||
assertThat(mFragment.getPreferenceScreenResId()).isEqualTo(R.xml.language_and_input);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetPreferenceControllers_shouldRegisterLifecycleObservers() {
|
|
||||||
final List<AbstractPreferenceController> controllers =
|
|
||||||
mFragment.createPreferenceControllers(mActivity);
|
|
||||||
int lifecycleObserverCount = 0;
|
|
||||||
for (AbstractPreferenceController controller : controllers) {
|
|
||||||
if (controller instanceof LifecycleObserver) {
|
|
||||||
lifecycleObserverCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
verify(mFragment.getSettingsLifecycle(), times(lifecycleObserverCount))
|
|
||||||
.addObserver(any(LifecycleObserver.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetPreferenceControllers_shouldAllBeCreated() {
|
|
||||||
final List<AbstractPreferenceController> controllers =
|
|
||||||
mFragment.createPreferenceControllers(mActivity);
|
|
||||||
|
|
||||||
assertThat(controllers.isEmpty()).isFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNonIndexableKeys_existInXmlLayout() {
|
|
||||||
final Context context = spy(RuntimeEnvironment.application);
|
|
||||||
final Resources res = spy(RuntimeEnvironment.application.getResources());
|
|
||||||
final InputManager inputManager = mock(InputManager.class);
|
|
||||||
final TextServicesManager textServicesManager = mock(TextServicesManager.class);
|
|
||||||
FeatureFlagUtils.setEnabled(context, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI, false);
|
|
||||||
when(inputManager.getInputDeviceIds()).thenReturn(new int[0]);
|
|
||||||
doReturn(inputManager).when(context).getSystemService(Context.INPUT_SERVICE);
|
|
||||||
doReturn(textServicesManager).when(context)
|
|
||||||
.getSystemService(Context.TEXT_SERVICES_MANAGER_SERVICE);
|
|
||||||
doReturn(res).when(context).getResources();
|
|
||||||
doReturn(false).when(res)
|
|
||||||
.getBoolean(com.android.internal.R.bool.config_supportSystemNavigationKeys);
|
|
||||||
final List<String> niks =
|
|
||||||
LanguageAndInputSettings.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(context);
|
|
||||||
LanguageAndInputSettings settings = new LanguageAndInputSettings();
|
|
||||||
final int xmlId = settings.getPreferenceScreenResId();
|
|
||||||
|
|
||||||
final List<String> keys = XmlTestUtils.getKeysFromPreferenceXml(context, xmlId);
|
|
||||||
|
|
||||||
assertThat(keys).containsAtLeastElementsIn(niks);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPreferenceControllers_getPreferenceKeys_existInPreferenceScreen() {
|
|
||||||
final Context context = spy(RuntimeEnvironment.application);
|
|
||||||
final TextServicesManager textServicesManager = mock(TextServicesManager.class);
|
|
||||||
doReturn(textServicesManager).when(context)
|
|
||||||
.getSystemService(Context.TEXT_SERVICES_MANAGER_SERVICE);
|
|
||||||
final LanguageAndInputSettings fragment = new LanguageAndInputSettings();
|
|
||||||
final List<String> preferenceScreenKeys =
|
|
||||||
XmlTestUtils.getKeysFromPreferenceXml(context, fragment.getPreferenceScreenResId());
|
|
||||||
final List<String> preferenceKeys = new ArrayList<>();
|
|
||||||
|
|
||||||
for (AbstractPreferenceController controller : fragment.createPreferenceControllers(context)) {
|
|
||||||
preferenceKeys.add(controller.getPreferenceKey());
|
|
||||||
}
|
|
||||||
|
|
||||||
assertThat(preferenceScreenKeys).containsAtLeastElementsIn(preferenceKeys);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test fragment to expose lifecycle and context so we can verify behavior for observables.
|
|
||||||
*/
|
|
||||||
public static class TestFragment extends LanguageAndInputSettings {
|
|
||||||
|
|
||||||
private Lifecycle mLifecycle;
|
|
||||||
private Context mContext;
|
|
||||||
|
|
||||||
public TestFragment(Context context) {
|
|
||||||
mContext = context;
|
|
||||||
mLifecycle = mock(Lifecycle.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Context getContext() {
|
|
||||||
return mContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Lifecycle getSettingsLifecycle() {
|
|
||||||
if (mLifecycle == null) {
|
|
||||||
return super.getSettingsLifecycle();
|
|
||||||
}
|
|
||||||
return mLifecycle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -20,10 +20,12 @@ import android.content.Context
|
|||||||
import android.os.OutcomeReceiver
|
import android.os.OutcomeReceiver
|
||||||
import android.telephony.satellite.SatelliteManager
|
import android.telephony.satellite.SatelliteManager
|
||||||
import android.telephony.satellite.SatelliteManager.SatelliteException
|
import android.telephony.satellite.SatelliteManager.SatelliteException
|
||||||
|
import android.telephony.satellite.SatelliteModemStateCallback
|
||||||
import androidx.test.core.app.ApplicationProvider
|
import androidx.test.core.app.ApplicationProvider
|
||||||
import com.android.settings.network.SatelliteManagerUtil.requestIsEnabled
|
import com.google.common.truth.Truth.assertThat
|
||||||
import com.google.common.util.concurrent.ListenableFuture
|
import com.google.common.util.concurrent.ListenableFuture
|
||||||
import java.util.concurrent.Executor
|
import java.util.concurrent.Executor
|
||||||
|
import kotlinx.coroutines.flow.first
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.junit.Assert.assertFalse
|
import org.junit.Assert.assertFalse
|
||||||
import org.junit.Assert.assertTrue
|
import org.junit.Assert.assertTrue
|
||||||
@@ -42,7 +44,7 @@ import org.robolectric.RobolectricTestRunner
|
|||||||
|
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner::class)
|
@RunWith(RobolectricTestRunner::class)
|
||||||
class SatelliteManagerUtilTest {
|
class SatelliteRepositoryTest {
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
@Rule
|
@Rule
|
||||||
@@ -57,10 +59,15 @@ class SatelliteManagerUtilTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private lateinit var mockExecutor: Executor
|
private lateinit var mockExecutor: Executor
|
||||||
|
|
||||||
|
private lateinit var repository: SatelliteRepository
|
||||||
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
`when`(this.spyContext.getSystemService(SatelliteManager::class.java))
|
`when`(this.spyContext.getSystemService(SatelliteManager::class.java))
|
||||||
.thenReturn(mockSatelliteManager)
|
.thenReturn(mockSatelliteManager)
|
||||||
|
|
||||||
|
repository = SatelliteRepository(spyContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -78,7 +85,7 @@ class SatelliteManagerUtilTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val result: ListenableFuture<Boolean> =
|
val result: ListenableFuture<Boolean> =
|
||||||
requestIsEnabled(spyContext, mockExecutor)
|
repository.requestIsEnabled(mockExecutor)
|
||||||
|
|
||||||
assertTrue(result.get())
|
assertTrue(result.get())
|
||||||
}
|
}
|
||||||
@@ -98,7 +105,7 @@ class SatelliteManagerUtilTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val result: ListenableFuture<Boolean> =
|
val result: ListenableFuture<Boolean> =
|
||||||
requestIsEnabled(spyContext, mockExecutor)
|
repository.requestIsEnabled(mockExecutor)
|
||||||
assertFalse(result.get())
|
assertFalse(result.get())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,7 +124,7 @@ class SatelliteManagerUtilTest {
|
|||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
val result = requestIsEnabled(spyContext, mockExecutor)
|
val result = repository.requestIsEnabled(mockExecutor)
|
||||||
|
|
||||||
assertFalse(result.get())
|
assertFalse(result.get())
|
||||||
}
|
}
|
||||||
@@ -126,8 +133,52 @@ class SatelliteManagerUtilTest {
|
|||||||
fun requestIsEnabled_nullSatelliteManager() = runBlocking {
|
fun requestIsEnabled_nullSatelliteManager() = runBlocking {
|
||||||
`when`(spyContext.getSystemService(SatelliteManager::class.java)).thenReturn(null)
|
`when`(spyContext.getSystemService(SatelliteManager::class.java)).thenReturn(null)
|
||||||
|
|
||||||
val result: ListenableFuture<Boolean> = requestIsEnabled(spyContext, mockExecutor)
|
val result: ListenableFuture<Boolean> = repository.requestIsEnabled(mockExecutor)
|
||||||
|
|
||||||
assertFalse(result.get())
|
assertFalse(result.get())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getIsModemEnabledFlow_isSatelliteEnabledState() = runBlocking {
|
||||||
|
`when`(
|
||||||
|
mockSatelliteManager.registerForModemStateChanged(
|
||||||
|
any(),
|
||||||
|
any()
|
||||||
|
)
|
||||||
|
).thenAnswer { invocation ->
|
||||||
|
val callback = invocation.getArgument<SatelliteModemStateCallback>(1)
|
||||||
|
callback.onSatelliteModemStateChanged(SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED)
|
||||||
|
SatelliteManager.SATELLITE_RESULT_SUCCESS
|
||||||
|
}
|
||||||
|
|
||||||
|
val flow = repository.getIsModemEnabledFlow()
|
||||||
|
|
||||||
|
assertThat(flow.first()).isTrue()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getIsModemEnabledFlow_isSatelliteDisabledState() = runBlocking {
|
||||||
|
`when`(
|
||||||
|
mockSatelliteManager.registerForModemStateChanged(
|
||||||
|
any(),
|
||||||
|
any()
|
||||||
|
)
|
||||||
|
).thenAnswer { invocation ->
|
||||||
|
val callback = invocation.getArgument<SatelliteModemStateCallback>(1)
|
||||||
|
callback.onSatelliteModemStateChanged(SatelliteManager.SATELLITE_MODEM_STATE_OFF)
|
||||||
|
SatelliteManager.SATELLITE_RESULT_SUCCESS
|
||||||
|
}
|
||||||
|
|
||||||
|
val flow = repository.getIsModemEnabledFlow()
|
||||||
|
|
||||||
|
assertThat(flow.first()).isFalse()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getIsModemEnabledFlow_nullSatelliteManager() = runBlocking {
|
||||||
|
`when`(spyContext.getSystemService(SatelliteManager::class.java)).thenReturn(null)
|
||||||
|
|
||||||
|
val flow = repository.getIsModemEnabledFlow()
|
||||||
|
assertThat(flow.first()).isFalse()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -91,6 +91,30 @@ class TelephonyRepositoryTest {
|
|||||||
.setMobileDataPolicyEnabled(TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH, true)
|
.setMobileDataPolicyEnabled(TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun isDataEnabled_invalidSub_returnFalse() = runBlocking {
|
||||||
|
val state = repository.isDataEnabled(
|
||||||
|
subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID,
|
||||||
|
)
|
||||||
|
|
||||||
|
assertThat(state.firstWithTimeoutOrNull()).isFalse()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun isDataEnabled_validSub_returnPolicyState() = runBlocking {
|
||||||
|
mockTelephonyManager.stub {
|
||||||
|
on {
|
||||||
|
isDataEnabledForReason(TelephonyManager.DATA_ENABLED_REASON_USER)
|
||||||
|
} doReturn true
|
||||||
|
}
|
||||||
|
|
||||||
|
val state = repository.isDataEnabled(
|
||||||
|
subId = SUB_ID,
|
||||||
|
)
|
||||||
|
|
||||||
|
assertThat(state.firstWithTimeoutOrNull()).isTrue()
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun telephonyCallbackFlow_callbackRegistered() = runBlocking {
|
fun telephonyCallbackFlow_callbackRegistered() = runBlocking {
|
||||||
val flow = context.telephonyCallbackFlow<Unit>(SUB_ID) {
|
val flow = context.telephonyCallbackFlow<Unit>(SUB_ID) {
|
||||||
|
|||||||
@@ -109,6 +109,19 @@ class AppArchiveButtonTest {
|
|||||||
assertThat(enabledActionButton.enabled).isFalse()
|
assertThat(enabledActionButton.enabled).isFalse()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun appArchiveButton_whenPackageIsNotFound_isDisabled() {
|
||||||
|
val app = ApplicationInfo().apply {
|
||||||
|
packageName = PACKAGE_NAME
|
||||||
|
isArchived = false
|
||||||
|
}
|
||||||
|
whenever(userPackageManager.isAppArchivable(app.packageName)).thenThrow(PackageManager.NameNotFoundException())
|
||||||
|
|
||||||
|
val actionButton = setContent(app)
|
||||||
|
|
||||||
|
assertThat(actionButton.enabled).isFalse()
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun appArchiveButton_displaysRightTextAndIcon() {
|
fun appArchiveButton_displaysRightTextAndIcon() {
|
||||||
val app = ApplicationInfo().apply {
|
val app = ApplicationInfo().apply {
|
||||||
|
|||||||
@@ -16,71 +16,32 @@
|
|||||||
|
|
||||||
package com.android.settings.language;
|
package com.android.settings.language;
|
||||||
|
|
||||||
import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.util.FeatureFlagUtils;
|
|
||||||
|
|
||||||
import androidx.test.core.app.ApplicationProvider;
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
|
|
||||||
import com.android.settings.Settings;
|
import com.android.settings.Settings;
|
||||||
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class LanguagePreferenceControllerTest {
|
public class LanguagePreferenceControllerTest {
|
||||||
private boolean mCacheFeatureFlagSwitch = false;
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private LanguagePreferenceController mController;
|
private LanguagePreferenceController mController;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
mContext = ApplicationProvider.getApplicationContext();
|
mContext = ApplicationProvider.getApplicationContext();
|
||||||
mCacheFeatureFlagSwitch =
|
|
||||||
FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI);
|
|
||||||
mController = new LanguagePreferenceController(mContext, "key");
|
mController = new LanguagePreferenceController(mContext, "key");
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void tearDown() {
|
|
||||||
FeatureFlagUtils.setEnabled(
|
|
||||||
mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI, mCacheFeatureFlagSwitch);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getAvailabilityStatus_featureFlagOff_returnUnavailable() {
|
|
||||||
FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI,
|
|
||||||
false);
|
|
||||||
|
|
||||||
int result = mController.getAvailabilityStatus();
|
|
||||||
|
|
||||||
assertEquals(CONDITIONALLY_UNAVAILABLE, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getAvailabilityStatus_featureFlagOff_LanguageAndInputSettingsActivityEnabled() {
|
|
||||||
FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI,
|
|
||||||
false);
|
|
||||||
|
|
||||||
mController.getAvailabilityStatus();
|
|
||||||
|
|
||||||
assertTrue(isActivityEnable(mContext, Settings.LanguageAndInputSettingsActivity.class));
|
|
||||||
assertFalse(isActivityEnable(mContext, Settings.LanguageSettingsActivity.class));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getAvailabilityStatus_featureFlagOff_LanguageAndInputSettingsActivitydisabled() {
|
public void getAvailabilityStatus_featureFlagOff_LanguageAndInputSettingsActivitydisabled() {
|
||||||
FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI,
|
|
||||||
true);
|
|
||||||
|
|
||||||
mController.getAvailabilityStatus();
|
mController.getAvailabilityStatus();
|
||||||
|
|
||||||
assertFalse(isActivityEnable(mContext, Settings.LanguageAndInputSettingsActivity.class));
|
assertFalse(isActivityEnable(mContext, Settings.LanguageAndInputSettingsActivity.class));
|
||||||
|
|||||||
Reference in New Issue
Block a user