Snap for 10171934 from 40dd0958d6 to udc-qpr1-release

Change-Id: I274ae8b21b03fb8811b55954677dfcdb8d389ae7
This commit is contained in:
Android Build Coastguard Worker
2023-05-20 05:02:12 +00:00
29 changed files with 462 additions and 93 deletions

View File

@@ -258,10 +258,10 @@
<!-- Title for stylus device details page [CHAR LIMIT=50] -->
<string name="stylus_device_details_title">Stylus</string>
<!-- Preference title for setting the app that opens when stylus button is pressed [CHAR LIMIT=none] -->
<!-- Preference title for setting the app that opens user presses stylus button [CHAR LIMIT=none] -->
<string name="stylus_default_notes_app">Tail button press</string>
<!-- Summary for the app that opens when tail button is pressed, if set to a work profile app [CHAR LIMIT=none] -->
<string name="stylus_default_notes_summary_work"><xliff:g id="app_name" example="WhatsApp">%s</xliff:g> (Work profile)</string>
<!-- Summary for the app that opens when user presses stylus tail button, if set to a work profile app [CHAR LIMIT=none] -->
<string name="stylus_default_notes_summary_work"><xliff:g id="app_name" example="Mail">%s</xliff:g> (Work profile)</string>
<!-- Preference title for toggling whether handwriting in textfields is enabled [CHAR LIMIT=none] -->
<string name="stylus_textfield_handwriting">Write in text fields</string>
<!-- Preference title for toggling whether stylus button presses are ignored [CHAR LIMIT=none] -->
@@ -1446,6 +1446,9 @@
<!-- Title for the dialog to enter PIN. [CHAR LIMIT=40] -->
<string name="bluetooth_pairing_request">Pair with <xliff:g id="device_name">%1$s</xliff:g>?</string>
<!-- Message when a bluetooth device from a coordinated set is bonding late. [CHAR LIMIT=NONE] -->
<string name="bluetooth_pairing_group_late_bonding">Add new member to the existing coordinated set</string>
<!-- Message when bluetooth is informing the user of the pairing key. [CHAR LIMIT=NONE] -->
<string name="bluetooth_pairing_key_msg">Bluetooth pairing code</string>

View File

@@ -33,21 +33,6 @@
android:summary="@string/summary_placeholder"/>
</PreferenceCategory>
<PreferenceCategory
android:key="speech_category"
android:title="@string/speech_category_title">
<com.android.settings.widget.GearPreference
android:key="voice_input_settings"
android:title="@string/voice_input_settings_title"
android:fragment="com.android.settings.language.DefaultVoiceInputPicker" />
<Preference
android:key="tts_settings_summary"
android:title="@string/tts_settings_title"
android:fragment="com.android.settings.tts.TextToSpeechSettings"
settings:searchable="false"/>
</PreferenceCategory>
<PreferenceCategory
android:key="input_assistance_category"
android:title="@string/input_assistance">

View File

@@ -73,13 +73,6 @@
android:title="@string/voice_input_settings_title"
android:fragment="com.android.settings.language.DefaultVoiceInputPicker" />
<Preference
android:key="on_device_recognition_settings"
android:title="@string/on_device_recognition_settings_title"
android:summary="@string/on_device_recognition_settings_summary"
settings:controller=
"com.android.settings.language.OnDeviceRecognitionPreferenceController" />
<Preference
android:key="tts_settings_summary"
android:title="@string/tts_settings_title"

View File

@@ -46,4 +46,26 @@
settings:controller="com.android.settings.regionalpreferences.RegionalPreferencesController" />
</PreferenceCategory>
<PreferenceCategory
android:key="speech_category"
android:title="@string/speech_category_title">
<com.android.settings.widget.GearPreference
android:key="voice_input_settings"
android:title="@string/voice_input_settings_title"
android:fragment="com.android.settings.language.DefaultVoiceInputPicker" />
<Preference
android:key="on_device_recognition_settings"
android:title="@string/on_device_recognition_settings_title"
android:summary="@string/on_device_recognition_settings_summary"
settings:controller=
"com.android.settings.language.OnDeviceRecognitionPreferenceController" />
<Preference
android:key="tts_settings_summary"
android:title="@string/tts_settings_title"
android:fragment="com.android.settings.tts.TextToSpeechSettings"
settings:searchable="false"/>
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -58,6 +58,11 @@ public class AppStateClonedAppsBridge extends AppStateBaseBridge{
mCloneProfileApps = mContext.getPackageManager()
.getInstalledPackagesAsUser(GET_ACTIVITIES,
mCloneUserId).stream().map(x -> x.packageName).toList();
} else if (!mCloneProfileApps.isEmpty()) {
// In case we remove clone profile (mCloneUserId becomes -1), the bridge state should
// reflect the same by setting cloneProfileApps as empty, without building the entire
// page.
mCloneProfileApps = new ArrayList<>();
}
final List<ApplicationsState.AppEntry> allApps = mAppSession.getAllApps();

View File

@@ -16,8 +16,6 @@
package com.android.settings.applications;
import static android.content.pm.PackageManager.GET_ACTIVITIES;
import static com.android.settings.Utils.PROPERTY_CLONED_APPS_ENABLED;
import android.content.Context;
@@ -87,8 +85,8 @@ public class ClonedAppsPreferenceController extends BasePreferenceController
mContext.getResources().getStringArray(
com.android.internal.R.array.cloneable_apps));
List<String> primaryUserApps = mContext.getPackageManager()
.getInstalledPackagesAsUser(GET_ACTIVITIES,
UserHandle.myUserId()).stream().map(x -> x.packageName).toList();
.getInstalledPackagesAsUser(/* flags*/ 0, UserHandle.myUserId()).stream()
.map(x -> x.packageName).toList();
// Count number of installed apps in system user.
int availableAppsCount = (int) cloneableApps.stream()
.filter(x -> primaryUserApps.contains(x)).count();
@@ -99,8 +97,8 @@ public class ClonedAppsPreferenceController extends BasePreferenceController
}
// Get all apps in clone profile if present.
List<String> cloneProfileApps = mContext.getPackageManager()
.getInstalledPackagesAsUser(GET_ACTIVITIES,
cloneUserId).stream().map(x -> x.packageName).toList();
.getInstalledPackagesAsUser(/* flags*/ 0, cloneUserId).stream()
.map(x -> x.packageName).toList();
// Count number of allowlisted app present in clone profile.
int clonedAppsCount = (int) cloneableApps.stream()
.filter(x -> cloneProfileApps.contains(x)).count();

View File

@@ -165,4 +165,13 @@ public class CloneBackend {
public int getCloneUserId() {
return mCloneUserId;
}
/**
* Resets {@link #mCloneUserId} to -1.
* Typically called after the cloneUser is removed, so that the obsolete clonedUserId present
* with the CloneBackend instance can be cleared.
*/
public void resetCloneUserId() {
mCloneUserId = -1;
}
}

View File

@@ -923,10 +923,15 @@ public class ManageApplications extends InstrumentedFragment
}
IUserManager um = IUserManager.Stub.asInterface(
ServiceManager.getService(Context.USER_SERVICE));
CloneBackend cloneBackend = CloneBackend.getInstance(getContext());
try {
// Warning: This removes all the data, media & images present in cloned user.
um.removeUser(clonedUserId);
mApplications.rebuild();
if (um.removeUser(clonedUserId)) {
cloneBackend.resetCloneUserId();
mApplications.rebuild();
} else if (ManageApplications.DEBUG) {
Log.e(TAG, "Failed to remove cloned user");
}
} catch (RemoteException e) {
Log.e(TAG, "Failed to remove cloned apps", e);
Toast.makeText(getContext(),

View File

@@ -16,10 +16,8 @@
package com.android.settings.applications.specialaccess.interactacrossprofiles;
import static android.app.admin.DevicePolicyResources.Strings.Settings.CONNECTED_WORK_AND_PERSONAL_APPS_TITLE;
import static android.content.pm.PackageManager.GET_ACTIVITIES;
import android.annotation.Nullable;
import android.app.admin.DevicePolicyManager;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -157,9 +155,9 @@ public class InteractAcrossProfilesSettings extends EmptyTextSettings {
private static List<PackageInfo> getAllInstalledPackages(
PackageManager packageManager, UserHandle personalProfile, UserHandle workProfile) {
List<PackageInfo> personalPackages = packageManager.getInstalledPackagesAsUser(
GET_ACTIVITIES, personalProfile.getIdentifier());
/* flags= */ 0, personalProfile.getIdentifier());
List<PackageInfo> workPackages = packageManager.getInstalledPackagesAsUser(
GET_ACTIVITIES, workProfile.getIdentifier());
/* flags= */ 0, workProfile.getIdentifier());
List<PackageInfo> allPackages = new ArrayList<>(personalPackages);
for (PackageInfo workPackage : workPackages) {
if (allPackages.stream().noneMatch(

View File

@@ -319,7 +319,7 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll
}
/**
* Disable the Le Audio profile, VCP, and CSIP for each of the Le Audio devices.
* Disable the Le Audio profile for each of the Le Audio devices.
*
* @param profile the LeAudio profile
*/
@@ -328,20 +328,12 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll
Log.e(TAG, "There is no the LE profile or no device in mProfileDeviceMap. Do nothing.");
return;
}
LocalBluetoothProfile vcp = mProfileManager.getVolumeControlProfile();
LocalBluetoothProfile csip = mProfileManager.getCsipSetCoordinatorProfile();
for (CachedBluetoothDevice leAudioDevice : mProfileDeviceMap.get(profile.toString())) {
Log.d(TAG,
"device:" + leAudioDevice.getDevice().getAnonymizedAddress()
+ "disable LE profile");
profile.setEnabled(leAudioDevice.getDevice(), false);
if (vcp != null) {
vcp.setEnabled(leAudioDevice.getDevice(), false);
}
if (csip != null) {
csip.setEnabled(leAudioDevice.getDevice(), false);
}
}
if (!SystemProperties.getBoolean(ENABLE_DUAL_MODE_AUDIO, false)) {
@@ -352,7 +344,7 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll
}
/**
* Enable the Le Audio profile, VCP, and CSIP for each of the Le Audio devices.
* Enable the Le Audio profile for each of the Le Audio devices.
*
* @param profile the LeAudio profile
*/
@@ -368,19 +360,11 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll
disableProfileBeforeUserEnablesLeAudio(mProfileManager.getHeadsetProfile());
}
LocalBluetoothProfile vcp = mProfileManager.getVolumeControlProfile();
LocalBluetoothProfile csip = mProfileManager.getCsipSetCoordinatorProfile();
for (CachedBluetoothDevice leAudioDevice : mProfileDeviceMap.get(profile.toString())) {
Log.d(TAG,
"device:" + leAudioDevice.getDevice().getAnonymizedAddress()
+ "enable LE profile");
profile.setEnabled(leAudioDevice.getDevice(), true);
if (vcp != null) {
vcp.setEnabled(leAudioDevice.getDevice(), true);
}
if (csip != null) {
csip.setEnabled(leAudioDevice.getDevice(), true);
}
}
}

View File

@@ -72,6 +72,7 @@ public class BluetoothPairingController implements OnCheckedChangeListener,
private boolean mIsCoordinatedSetMember;
private boolean mIsLeAudio;
private boolean mIsLeContactSharingEnabled;
private boolean mIsLateBonding;
/**
* Creates an instance of a BluetoothPairingController.
@@ -98,6 +99,7 @@ public class BluetoothPairingController implements OnCheckedChangeListener,
mDeviceName = mBluetoothManager.getCachedDeviceManager().getName(mDevice);
mPbapClientProfile = mBluetoothManager.getProfileManager().getPbapClientProfile();
mPasskeyFormatted = formatKey(mPasskey);
mIsLateBonding = mBluetoothManager.getCachedDeviceManager().isLateBonding(mDevice);
final CachedBluetoothDevice cachedDevice =
mBluetoothManager.getCachedDeviceManager().findDevice(mDevice);
@@ -116,7 +118,10 @@ public class BluetoothPairingController implements OnCheckedChangeListener,
mIsLeContactSharingEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SETTINGS_UI,
SettingsUIDeviceConfig.BT_LE_AUDIO_CONTACT_SHARING_ENABLED, true);
Log.d(TAG, "BT_LE_AUDIO_CONTACT_SHARING_ENABLED is " + mIsLeContactSharingEnabled);
Log.d(TAG,
"BT_LE_AUDIO_CONTACT_SHARING_ENABLED is "
+ mIsLeContactSharingEnabled + " isCooridnatedSetMember "
+ mIsCoordinatedSetMember);
}
}
@@ -192,6 +197,15 @@ public class BluetoothPairingController implements OnCheckedChangeListener,
return mIsCoordinatedSetMember;
}
/**
* A method for querying if the bluetooth device from a coordinated set is bonding late.
*
* @return - A boolean indicating if the device is bonding late.
*/
public boolean isLateBonding() {
return mIsLateBonding;
}
/**
* A method for querying if the bluetooth device has a profile already set up on this device.
*

View File

@@ -357,8 +357,14 @@ public class BluetoothPairingDialogFragment extends InstrumentedDialogFragment i
pairingViewContent.setText(mPairingController.getPairingContent());
}
final TextView messagePairingSet = (TextView) view.findViewById(R.id.pairing_group_message);
messagePairingSet.setVisibility(mPairingController.isCoordinatedSetMemberDevice()
? View.VISIBLE : View.GONE);
if (mPairingController.isLateBonding()) {
messagePairingSet.setText(getString(R.string.bluetooth_pairing_group_late_bonding));
}
boolean setPairingMessage =
mPairingController.isCoordinatedSetMemberDevice() || mPairingController.isLateBonding();
messagePairingSet.setVisibility(setPairingMessage ? View.VISIBLE : View.GONE);
return view;
}
}

View File

@@ -26,6 +26,7 @@ import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
/**
@@ -53,17 +54,28 @@ public final class BluetoothPairingRequest extends BroadcastReceiver {
boolean shouldShowDialog = LocalBluetoothPreferences.shouldShowDialogInForeground(
context, device);
// Skips consent pairing dialog if the device was recently associated with CDM
Log.d(TAG,
"Receive ACTION_PAIRING_REQUEST pairingVariant=" + pairingVariant
+ " canBondWithoutDialog=" + device.canBondWithoutDialog()
+ " isOngoingPairByCsip="
+ mBluetoothManager.getCachedDeviceManager().isOngoingPairByCsip(device)
+ " isLateBonding="
+ mBluetoothManager.getCachedDeviceManager().isLateBonding(device));
/* Skips consent pairing dialog if the device was recently associated with CDM
* or if the device is a member of the coordinated set and is not bonding late.
*/
if (pairingVariant == BluetoothDevice.PAIRING_VARIANT_CONSENT
&& (device.canBondWithoutDialog()
|| mBluetoothManager.getCachedDeviceManager().isOngoingPairByCsip(device))) {
&& (device.canBondWithoutDialog()
|| (mBluetoothManager.getCachedDeviceManager().isOngoingPairByCsip(device)
&& !mBluetoothManager.getCachedDeviceManager().isLateBonding(device)))) {
device.setPairingConfirmation(true);
} else if (powerManager.isInteractive() && shouldShowDialog) {
// Since the screen is on and the BT-related activity is in the foreground,
// just open the dialog
// convert broadcast intent into activity intent (same action string)
Intent pairingIntent = BluetoothPairingService.getPairingDialogIntent(context,
intent, BluetoothDevice.EXTRA_PAIRING_INITIATOR_FOREGROUND);
Intent pairingIntent = BluetoothPairingService.getPairingDialogIntent(
context, intent, BluetoothDevice.EXTRA_PAIRING_INITIATOR_FOREGROUND);
context.startActivityAsUser(pairingIntent, UserHandle.CURRENT);
} else {

View File

@@ -254,16 +254,17 @@ public class StylusDevicesController extends AbstractPreferenceController implem
private List<UserHandle> getUserAndManagedProfiles() {
UserManager um = mContext.getSystemService(UserManager.class);
final ArrayList<UserHandle> userManagedProfiles = new ArrayList<>();
final List<UserHandle> userManagedProfiles = new ArrayList<>();
// Add the current user, then add all the associated managed profiles.
final UserHandle currentUser = Process.myUserHandle();
userManagedProfiles.add(currentUser);
final List<UserInfo> userInfos = um.getUsers();
for (UserInfo info : userInfos) {
if (um.isManagedProfile(info.id)
&& um.getProfileParent(info.id).id == currentUser.getIdentifier()) {
userManagedProfiles.add(UserHandle.of(info.id));
int userId = info.id;
if (um.isManagedProfile(userId)
&& um.getProfileParent(userId).id == currentUser.getIdentifier()) {
userManagedProfiles.add(UserHandle.of(userId));
}
}
return userManagedProfiles;

View File

@@ -0,0 +1,35 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.deviceinfo.batteryinfo;
/**
* Feature Provider used for getting battery information.
*/
public interface BatteryInfoFeatureProvider {
/** Returns true if Manufacture date should be shown */
boolean isManufactureDateAvailable();
/** Returns true if First use date should be shown */
boolean isFirstUseDateAvailable();
/** Returns the summary of battery manufacture date */
CharSequence getManufactureDateSummary();
/** Returns the summary of battery first use date */
CharSequence getFirstUseDateSummary();
}

View File

@@ -0,0 +1,91 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.deviceinfo.batteryinfo;
import android.content.Context;
import android.os.BatteryManager;
import java.text.DateFormat;
import java.util.Date;
/** Implementation of {@code BatteryInfoFeatureProvider} */
public class BatteryInfoFeatureProviderImpl implements BatteryInfoFeatureProvider {
private BatteryManager mBatteryManager;
private Context mContext;
private long mManufactureDateInSec;
private long mFirstUseDateInSec;
public BatteryInfoFeatureProviderImpl(Context context) {
mContext = context;
mBatteryManager = mContext.getSystemService(BatteryManager.class);
}
@Override
public boolean isManufactureDateAvailable() {
return false;
}
@Override
public boolean isFirstUseDateAvailable() {
return false;
}
@Override
public CharSequence getManufactureDateSummary() {
if (!isManufactureDateAvailable()) {
return null;
}
final long manufactureDateInSec = getManufactureDate();
return getFormattedDate(manufactureDateInSec * 1000L);
}
@Override
public CharSequence getFirstUseDateSummary() {
if (!isFirstUseDateAvailable()) {
return null;
}
final long firstUseDateInSec = getFirstUseDate();
return getFormattedDate(firstUseDateInSec * 1000L);
}
protected long getManufactureDate() {
if (mManufactureDateInSec == 0L) {
mManufactureDateInSec = mBatteryManager.getLongProperty(
BatteryManager.BATTERY_PROPERTY_MANUFACTURING_DATE);
}
return mManufactureDateInSec;
}
protected long getFirstUseDate() {
if (mFirstUseDateInSec == 0L) {
mFirstUseDateInSec = mBatteryManager.getLongProperty(
BatteryManager.BATTERY_PROPERTY_FIRST_USAGE_DATE);
}
return mFirstUseDateInSec;
}
private CharSequence getFormattedDate(long dateInMs) {
final Date date = new Date(dateInMs);
final CharSequence formattedDate =
DateFormat.getDateInstance(DateFormat.LONG).format(date.getTime());
return formattedDate;
}
}

View File

@@ -30,9 +30,7 @@ import androidx.annotation.Nullable;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.language.DefaultVoiceInputPreferenceController;
import com.android.settings.language.PointerSpeedController;
import com.android.settings.language.TtsPreferenceController;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.widget.PreferenceCategoryController;
import com.android.settingslib.core.AbstractPreferenceController;
@@ -49,8 +47,6 @@ public class KeyboardSettings extends DashboardFragment {
private static final String TAG = "KeyboardSettings";
private static final String KEY_KEYBOARDS_CATEGORY = "keyboards_category";
private static final String KEY_SPEECH_CATEGORY = "speech_category";
private static final String KEY_TEXT_TO_SPEECH = "tts_settings_summary";
private static final String KEY_POINTER_CATEGORY = "pointer_category";
@Override
@@ -102,17 +98,6 @@ public class KeyboardSettings extends DashboardFragment {
Arrays.asList(virtualKeyboardPreferenceController,
physicalKeyboardPreferenceController)));
// Speech
final DefaultVoiceInputPreferenceController defaultVoiceInputPreferenceController =
new DefaultVoiceInputPreferenceController(context, lifecycle);
final TtsPreferenceController ttsPreferenceController =
new TtsPreferenceController(context, KEY_TEXT_TO_SPEECH);
controllers.add(defaultVoiceInputPreferenceController);
controllers.add(ttsPreferenceController);
controllers.add(new PreferenceCategoryController(context,
KEY_SPEECH_CATEGORY).setChildren(
Arrays.asList(defaultVoiceInputPreferenceController, ttsPreferenceController)));
// Pointer
final PointerSpeedController pointerController = new PointerSpeedController(context);
controllers.add(pointerController);

View File

@@ -21,14 +21,25 @@ import android.app.settings.SettingsEnums;
import android.content.Context;
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.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.List;
@SearchIndexable
public class LanguageSettings extends DashboardFragment {
private static final String KEY_SPEECH_CATEGORY = "speech_category";
private static final String TAG = "LanguageSettings";
@Override
@@ -59,8 +70,43 @@ public class LanguageSettings extends DashboardFragment {
return R.xml.language_settings;
}
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<>();
final DefaultVoiceInputPreferenceController defaultVoiceInputPreferenceController =
new DefaultVoiceInputPreferenceController(context, lifecycle);
final TtsPreferenceController ttsPreferenceController =
new TtsPreferenceController(context);
final OnDeviceRecognitionPreferenceController onDeviceRecognitionPreferenceController =
new OnDeviceRecognitionPreferenceController(context);
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));
return controllers;
}
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.language_settings) {
public List<AbstractPreferenceController> createPreferenceControllers(
Context context) {
return buildPreferenceControllers(context, null);
}
@Override
protected boolean isPageSearchEnabled(Context context) {
return FeatureFlagUtils

View File

@@ -33,10 +33,16 @@ import java.util.Optional;
/** Controller of the On-device recognition preference. */
public class OnDeviceRecognitionPreferenceController extends BasePreferenceController {
private static final String KEY_ON_DEVICE_RECOGNITION = "on_device_recognition_settings";
private static final String TAG = "OnDeviceRecognitionPreferenceController";
private Optional<Intent> mIntent;
public OnDeviceRecognitionPreferenceController(Context context) {
this(context, KEY_ON_DEVICE_RECOGNITION);
}
public OnDeviceRecognitionPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
}
@@ -51,6 +57,10 @@ public class OnDeviceRecognitionPreferenceController extends BasePreferenceContr
: CONDITIONALLY_UNAVAILABLE;
}
public String getPreferenceKey() {
return KEY_ON_DEVICE_RECOGNITION;
}
@Override
public void updateState(Preference preference) {
super.updateState(preference);

View File

@@ -26,9 +26,15 @@ import com.android.settings.core.BasePreferenceController;
public class TtsPreferenceController extends BasePreferenceController {
private static final String KEY_TEXT_TO_SPEECH = "tts_settings_summary";
@VisibleForTesting
TtsEngines mTtsEngines;
public TtsPreferenceController(Context context) {
this(context, KEY_TEXT_TO_SPEECH);
}
public TtsPreferenceController(Context context, String key) {
super(context, key);
mTtsEngines = new TtsEngines(context);
@@ -40,4 +46,8 @@ public class TtsPreferenceController extends BasePreferenceController {
mContext.getResources().getBoolean(R.bool.config_show_tts_settings_summary)
? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
}
public String getPreferenceKey() {
return KEY_TEXT_TO_SPEECH;
}
}

View File

@@ -33,6 +33,7 @@ import com.android.settings.biometrics2.factory.BiometricsRepositoryProvider;
import com.android.settings.bluetooth.BluetoothFeatureProvider;
import com.android.settings.dashboard.DashboardFeatureProvider;
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
import com.android.settings.deviceinfo.batteryinfo.BatteryInfoFeatureProvider;
import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider;
import com.android.settings.fuelgauge.BatterySettingsFeatureProvider;
import com.android.settings.fuelgauge.BatteryStatusFeatureProvider;
@@ -204,6 +205,11 @@ public abstract class FeatureFactory {
*/
public abstract KeyboardSettingsFeatureProvider getKeyboardSettingsFeatureProvider();
/**
* Retrieves implementation for Battery information feature.
*/
public abstract BatteryInfoFeatureProvider getBatteryInfoFeatureProvider();
public static final class FactoryNotFoundException extends RuntimeException {
public FactoryNotFoundException(Throwable throwable) {
super("Unable to create factory. Did you misconfigure Proguard?", throwable);

View File

@@ -47,6 +47,8 @@ import com.android.settings.dashboard.DashboardFeatureProvider;
import com.android.settings.dashboard.DashboardFeatureProviderImpl;
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
import com.android.settings.dashboard.suggestions.SuggestionFeatureProviderImpl;
import com.android.settings.deviceinfo.batteryinfo.BatteryInfoFeatureProvider;
import com.android.settings.deviceinfo.batteryinfo.BatteryInfoFeatureProviderImpl;
import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider;
import com.android.settings.enterprise.EnterprisePrivacyFeatureProviderImpl;
import com.android.settings.fuelgauge.BatterySettingsFeatureProvider;
@@ -117,6 +119,7 @@ public class FeatureFactoryImpl extends FeatureFactory {
private AdvancedVpnFeatureProvider mAdvancedVpnFeatureProvider;
private WifiFeatureProvider mWifiFeatureProvider;
private KeyboardSettingsFeatureProvider mKeyboardSettingsFeatureProvider;
private BatteryInfoFeatureProvider mBatteryInfoFeatureProvider;
@Override
public SupportFeatureProvider getSupportFeatureProvider(Context context) {
@@ -376,4 +379,12 @@ public class FeatureFactoryImpl extends FeatureFactory {
}
return mKeyboardSettingsFeatureProvider;
}
@Override
public BatteryInfoFeatureProvider getBatteryInfoFeatureProvider() {
if (mBatteryInfoFeatureProvider == null) {
mBatteryInfoFeatureProvider = new BatteryInfoFeatureProviderImpl(getAppContext());
}
return mBatteryInfoFeatureProvider;
}
}

View File

@@ -102,7 +102,6 @@ public class WifiHotspotRepository {
protected Boolean mIs6gBandSupported;
protected Boolean mIs6gAvailable;
protected MutableLiveData<Boolean> m6gAvailable;
protected String mCurrentCountryCode;
protected ActiveCountryCodeChangedCallback mActiveCountryCodeChangedCallback;
@VisibleForTesting
@@ -568,17 +567,12 @@ public class WifiHotspotRepository {
@Override
public void onActiveCountryCodeChanged(String country) {
log("onActiveCountryCodeChanged(), country:" + country);
mCurrentCountryCode = country;
purgeRefreshData();
refresh();
}
@Override
public void onCountryCodeInactive() {
log("onCountryCodeInactive()");
mCurrentCountryCode = null;
purgeRefreshData();
refresh();
}
}

View File

@@ -315,7 +315,7 @@ public class StylusDevicesControllerTest {
}
@Test
public void defaultNotesPreferenceClick_multiUser_showsProfileSelectorDialog() {
public void defaultNotesPreferenceClick_multiUserManagedProfile_showsProfileSelectorDialog() {
mContext.setTheme(R.style.Theme_AppCompat);
final String permissionPackageName = "permissions.package";
final UserHandle currentUser = Process.myUserHandle();
@@ -337,13 +337,43 @@ public class StylusDevicesControllerTest {
assertTrue(mController.mDialog.isShowing());
}
@Test
public void defaultNotesPreferenceClick_noManagedProfile_sendsManageDefaultRoleIntent() {
final ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
mContext.setTheme(R.style.Theme_AppCompat);
final String permissionPackageName = "permissions.package";
final UserHandle currentUser = Process.myUserHandle();
List<UserInfo> userInfos = Arrays.asList(
new UserInfo(currentUser.getIdentifier(), "current", 0),
new UserInfo(1, "other", UserInfo.FLAG_FULL)
);
when(mUserManager.getUsers()).thenReturn(userInfos);
when(mUserManager.isManagedProfile(1)).thenReturn(false);
when(mUserManager.getUserInfo(currentUser.getIdentifier())).thenReturn(userInfos.get(0));
when(mUserManager.getUserInfo(1)).thenReturn(userInfos.get(1));
when(mUserManager.getProfileParent(any())).thenReturn(null);
when(mPm.getPermissionControllerPackageName()).thenReturn(permissionPackageName);
showScreen(mController);
Preference defaultNotesPref = mPreferenceContainer.getPreference(0);
mController.onPreferenceClick(defaultNotesPref);
verify(mContext).startActivity(captor.capture());
Intent intent = captor.getValue();
assertThat(intent.getAction()).isEqualTo(Intent.ACTION_MANAGE_DEFAULT_APP);
assertThat(intent.getPackage()).isEqualTo(permissionPackageName);
assertThat(intent.getStringExtra(Intent.EXTRA_ROLE_NAME)).isEqualTo(
RoleManager.ROLE_NOTES);
assertNull(mController.mDialog);
}
@Test
public void profileSelectDialogClickCallback_onClick_sendsIntent() {
Intent intent = new Intent();
UserHandle user1 = mock(UserHandle.class);
UserHandle user2 = mock(UserHandle.class);
List<UserHandle> users = Arrays.asList(new UserHandle[] {user1, user2});
mController.mDialog = mock(Dialog.class);
List<UserHandle> users = Arrays.asList(user1, user2);
mController.mDialog = new Dialog(mContext);
UserAdapter.OnClickListener callback = mController
.createProfileDialogClickCallback(intent, users);

View File

@@ -0,0 +1,97 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.deviceinfo.batteryinfo;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.os.BatteryManager;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
public class BatteryInfoFeatureProviderImplTest {
@Mock
private BatteryManager mBatteryManager;
private Context mContext;
private BatteryInfoFeatureProviderImpl mImpl;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(org.robolectric.RuntimeEnvironment.application);
doReturn(mBatteryManager).when(mContext).getSystemService(BatteryManager.class);
mImpl = spy(new BatteryInfoFeatureProviderImpl(mContext));
}
@Test
public void isManufactureDateAvailable_returnFalse() {
assertThat(mImpl.isManufactureDateAvailable()).isFalse();
}
@Test
public void isFirstUseDateAvailable_returnFalse() {
assertThat(mImpl.isFirstUseDateAvailable()).isFalse();
}
@Test
public void getManufactureDateSummary_available_returnExpectedDate() {
doReturn(true).when(mImpl).isManufactureDateAvailable();
when(mBatteryManager.getLongProperty(BatteryManager.BATTERY_PROPERTY_MANUFACTURING_DATE))
.thenReturn(1669680000L);
final CharSequence result = mImpl.getManufactureDateSummary();
assertThat(result).isEqualTo("November 29, 2022");
}
@Test
public void getManufactureDateSummary_unavailable_returnNull() {
doReturn(false).when(mImpl).isManufactureDateAvailable();
assertThat(mImpl.getManufactureDateSummary()).isNull();
}
@Test
public void getFirstUseDateSummary_available_returnExpectedDate() {
doReturn(true).when(mImpl).isFirstUseDateAvailable();
when(mBatteryManager.getLongProperty(BatteryManager.BATTERY_PROPERTY_FIRST_USAGE_DATE))
.thenReturn(1669680000L);
final CharSequence result = mImpl.getFirstUseDateSummary();
assertThat(result).isEqualTo("November 29, 2022");
}
@Test
public void getFirstUseDateSummary_unavailable_returnNull() {
doReturn(false).when(mImpl).isFirstUseDateAvailable();
assertThat(mImpl.getFirstUseDateSummary()).isNull();
}
}

View File

@@ -31,6 +31,7 @@ import com.android.settings.biometrics2.factory.BiometricsRepositoryProvider;
import com.android.settings.bluetooth.BluetoothFeatureProvider;
import com.android.settings.dashboard.DashboardFeatureProvider;
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
import com.android.settings.deviceinfo.batteryinfo.BatteryInfoFeatureProvider;
import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider;
import com.android.settings.fuelgauge.BatterySettingsFeatureProvider;
import com.android.settings.fuelgauge.BatteryStatusFeatureProvider;
@@ -82,6 +83,7 @@ public class FakeFeatureFactory extends FeatureFactory {
public final AwareFeatureProvider mAwareFeatureProvider;
public final FaceFeatureProvider mFaceFeatureProvider;
public final BiometricsRepositoryProvider mBiometricsRepositoryProvider;
public final BatteryInfoFeatureProvider mBatteryInfoFeatureProvider;
public PanelFeatureProvider panelFeatureProvider;
public SlicesFeatureProvider slicesFeatureProvider;
@@ -148,6 +150,7 @@ public class FakeFeatureFactory extends FeatureFactory {
mAdvancedVpnFeatureProvider = mock(AdvancedVpnFeatureProvider.class);
mWifiFeatureProvider = mock(WifiFeatureProvider.class);
mKeyboardSettingsFeatureProvider = mock(KeyboardSettingsFeatureProvider.class);
mBatteryInfoFeatureProvider = mock(BatteryInfoFeatureProvider.class);
}
@Override
@@ -304,4 +307,9 @@ public class FakeFeatureFactory extends FeatureFactory {
public KeyboardSettingsFeatureProvider getKeyboardSettingsFeatureProvider() {
return mKeyboardSettingsFeatureProvider;
}
@Override
public BatteryInfoFeatureProvider getBatteryInfoFeatureProvider() {
return mBatteryInfoFeatureProvider;
}
}

View File

@@ -27,6 +27,7 @@ import com.android.settings.biometrics2.factory.BiometricsRepositoryProvider
import com.android.settings.bluetooth.BluetoothFeatureProvider
import com.android.settings.dashboard.DashboardFeatureProvider
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider
import com.android.settings.deviceinfo.batteryinfo.BatteryInfoFeatureProvider
import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider
import com.android.settings.fuelgauge.BatterySettingsFeatureProvider
import com.android.settings.fuelgauge.BatteryStatusFeatureProvider
@@ -187,4 +188,8 @@ class FakeFeatureFactory : FeatureFactory() {
override fun getKeyboardSettingsFeatureProvider(): KeyboardSettingsFeatureProvider {
TODO("Not yet implemented")
}
override fun getBatteryInfoFeatureProvider(): BatteryInfoFeatureProvider {
TODO("Not yet implemented")
}
}

View File

@@ -29,6 +29,7 @@ import com.android.settings.biometrics2.factory.BiometricsRepositoryProvider;
import com.android.settings.bluetooth.BluetoothFeatureProvider;
import com.android.settings.dashboard.DashboardFeatureProvider;
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
import com.android.settings.deviceinfo.batteryinfo.BatteryInfoFeatureProvider;
import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider;
import com.android.settings.fuelgauge.BatterySettingsFeatureProvider;
import com.android.settings.fuelgauge.BatteryStatusFeatureProvider;
@@ -77,6 +78,7 @@ public class FakeFeatureFactory extends FeatureFactory {
public final AwareFeatureProvider mAwareFeatureProvider;
public final FaceFeatureProvider mFaceFeatureProvider;
public final BiometricsRepositoryProvider mBiometricsRepositoryProvider;
public final BatteryInfoFeatureProvider mBatteryInfoFeatureProvider;
public PanelFeatureProvider panelFeatureProvider;
public SlicesFeatureProvider slicesFeatureProvider;
@@ -134,6 +136,7 @@ public class FakeFeatureFactory extends FeatureFactory {
mAdvancedVpnFeatureProvider = mock(AdvancedVpnFeatureProvider.class);
mWifiFeatureProvider = mock(WifiFeatureProvider.class);
mKeyboardSettingsFeatureProvider = mock(KeyboardSettingsFeatureProvider.class);
mBatteryInfoFeatureProvider = mock(BatteryInfoFeatureProvider.class);
}
@Override
@@ -290,4 +293,9 @@ public class FakeFeatureFactory extends FeatureFactory {
public KeyboardSettingsFeatureProvider getKeyboardSettingsFeatureProvider() {
return mKeyboardSettingsFeatureProvider;
}
@Override
public BatteryInfoFeatureProvider getBatteryInfoFeatureProvider() {
return mBatteryInfoFeatureProvider;
}
}

View File

@@ -78,7 +78,6 @@ import java.util.List;
public class WifiHotspotRepositoryTest {
static final String WIFI_SSID = "wifi_ssid";
static final String WIFI_PASSWORD = "wifi_password";
static final String WIFI_CURRENT_COUNTRY_CODE = "US";
static final int WIFI_5GHZ_BAND_PREFERRED = BAND_2GHZ_5GHZ;
static final int WIFI_6GHZ_BAND_PREFERRED = BAND_2GHZ_5GHZ_6GHZ;
@@ -112,7 +111,6 @@ public class WifiHotspotRepositoryTest {
mRepository = new WifiHotspotRepository(mContext, mWifiManager, mTetheringManager);
mRepository.mSecurityType = mSecurityType;
mRepository.mSpeedType = mSpeedType;
mRepository.mCurrentCountryCode = WIFI_CURRENT_COUNTRY_CODE;
mRepository.mIsDualBand = true;
mRepository.mIs5gAvailable = true;
mRepository.mIs6gAvailable = true;