Snap for 9358895 from e15c2c2a5b to udc-release

Change-Id: I1e5cb44eb1f9ee6153b7763a3ae17da720978678
This commit is contained in:
Android Build Coastguard Worker
2022-12-02 02:26:40 +00:00
30 changed files with 925 additions and 84 deletions

View File

@@ -0,0 +1,25 @@
<!--
Copyright (C) 2022 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M7,17H14V15H7ZM7,13H17V11H7ZM7,9H17V7H7ZM5,21Q4.175,21 3.587,20.413Q3,19.825 3,19V5Q3,4.175 3.587,3.587Q4.175,3 5,3H19Q19.825,3 20.413,3.587Q21,4.175 21,5V19Q21,19.825 20.413,20.413Q19.825,21 19,21ZM5,19H19Q19,19 19,19Q19,19 19,19V5Q19,5 19,5Q19,5 19,5H5Q5,5 5,5Q5,5 5,5V19Q5,19 5,19Q5,19 5,19ZM5,5Q5,5 5,5Q5,5 5,5V19Q5,19 5,19Q5,19 5,19Q5,19 5,19Q5,19 5,19V5Q5,5 5,5Q5,5 5,5Z"/>
</vector>

25
res/drawable/ic_block.xml Normal file
View File

@@ -0,0 +1,25 @@
<!--
Copyright (C) 2022 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M12,22Q9.925,22 8.1,21.212Q6.275,20.425 4.925,19.075Q3.575,17.725 2.788,15.9Q2,14.075 2,12Q2,9.925 2.788,8.1Q3.575,6.275 4.925,4.925Q6.275,3.575 8.1,2.787Q9.925,2 12,2Q14.075,2 15.9,2.787Q17.725,3.575 19.075,4.925Q20.425,6.275 21.212,8.1Q22,9.925 22,12Q22,14.075 21.212,15.9Q20.425,17.725 19.075,19.075Q17.725,20.425 15.9,21.212Q14.075,22 12,22ZM12,20Q15.35,20 17.675,17.675Q20,15.35 20,12Q20,10.65 19.562,9.4Q19.125,8.15 18.3,7.1L7.1,18.3Q8.15,19.125 9.4,19.562Q10.65,20 12,20ZM5.7,16.9 L16.9,5.7Q15.85,4.875 14.6,4.438Q13.35,4 12,4Q8.65,4 6.325,6.325Q4,8.65 4,12Q4,13.35 4.438,14.6Q4.875,15.85 5.7,16.9Z"/>
</vector>

View File

@@ -0,0 +1,25 @@
<!--
Copyright (C) 2022 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M2,21V19H22V21ZM19,17V3H20.5V17ZM4,17 L9.25,3H11.75L17,17H14.6L13.35,13.4H7.7L6.4,17ZM8.4,11.4H12.6L10.55,5.6H10.45Z"/>
</vector>

View File

@@ -105,11 +105,16 @@
<item>1800000</item>
</string-array>
<!-- NOTE: if you change this, you must also add the corresponding scale key and lookup table to
frameworks/base/core/java/android/content/res/FontScaleLookupTableFactory.java -->
<string-array name="entryvalues_font_size" translatable="false">
<item>0.85</item>
<item>1.0</item>
<item>1.15</item>
<item>1.30</item>
<item>1.50</item>
<item>1.80</item>
<item>2.0</item>
</string-array>
<!-- Wi-Fi settings -->

View File

@@ -228,6 +228,17 @@
<!-- Title to see all the previous connected devices [CHAR LIMIT=50] -->
<string name="previous_connected_see_all">See all</string>
<!-- Title for stylus device details page [CHAR LIMIT=50] -->
<string name="stylus_device_details_title">Stylus</string>
<!-- Preference title for setting the default note taking app [CHAR LIMIT=none] -->
<string name="stylus_default_notes_app">System note taking app</string>
<!-- Preference title for toggling whether handwriting in textfields is enabled [CHAR LIMIT=none] -->
<string name="stylus_textfield_handwriting">Stylus writing in textfields</string>
<!-- Preference title for toggling whether stylus button presses are ignored [CHAR LIMIT=none] -->
<string name="stylus_ignore_button">Ignore all stylus button presses</string>
<!-- Name shown in a USI stylus header in device details page [CHAR LIMIT=60] -->
<string name="stylus_usi_header_title">USI stylus</string>
<!-- Date & time settings screen title -->
<string name="date_and_time">Date &amp; time</string>

View File

@@ -44,15 +44,18 @@
<com.android.settingslib.widget.ButtonPreference
android:key="hearing_aid_pair_other_button"
android:gravity="center" />
android:gravity="center"/>
<com.android.settings.applications.SpacePreference
android:key="hearing_aid_space_layout"
android:layout_height="8dp" />
android:layout_height="8dp"/>
<com.android.settingslib.widget.ActionButtonsPreference
android:key="action_buttons"
settings:allowDividerBelow="true"/>
<PreferenceCategory
android:key="device_stylus"/>
<com.android.settings.slices.SlicePreference
android:key="bt_extra_control"
settings:controller="com.android.settings.slices.SlicePreferenceController"

View File

@@ -86,6 +86,7 @@ public class AccountTypePreference extends AppPreference implements OnPreference
setKey(buildKey(account));
setTitle(mTitle);
setSingleLineTitle(true);
setSummary(summary);
setIcon(icon);

View File

@@ -23,12 +23,15 @@ import android.app.settings.SettingsEnums;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.res.TypedArray;
import android.hardware.input.InputManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.UserManager;
import android.provider.DeviceConfig;
import android.text.TextUtils;
import android.util.FeatureFlagUtils;
import android.util.Log;
import android.view.InputDevice;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@@ -37,9 +40,11 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.connecteddevice.stylus.StylusDevicesController;
import com.android.settings.core.SettingsUIDeviceConfig;
import com.android.settings.dashboard.RestrictedDashboardFragment;
import com.android.settings.overlay.FeatureFactory;
@@ -72,6 +77,7 @@ public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment
CachedBluetoothDevice getDevice(String deviceAddress);
LocalBluetoothManager getManager(Context context);
UserManager getUserManager();
}
@@ -85,6 +91,9 @@ public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment
@VisibleForTesting
CachedBluetoothDevice mCachedDevice;
@Nullable
InputDevice mInputDevice;
private UserManager mUserManager;
public BluetoothDeviceDetailsFragment() {
@@ -118,6 +127,21 @@ public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment
return getSystemService(UserManager.class);
}
@Nullable
@VisibleForTesting
InputDevice getInputDevice(Context context) {
InputManager im = context.getSystemService(InputManager.class);
for (int deviceId : im.getInputDeviceIds()) {
String btAddress = im.getInputDeviceBluetoothAddress(deviceId);
if (btAddress != null && btAddress.equals(mDeviceAddress)) {
return im.getInputDevice(deviceId);
}
}
return null;
}
public static BluetoothDeviceDetailsFragment newInstance(String deviceAddress) {
Bundle args = new Bundle(1);
args.putString(KEY_DEVICE_ADDRESS, deviceAddress);
@@ -132,6 +156,12 @@ public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment
mManager = getLocalBluetoothManager(context);
mCachedDevice = getCachedDevice(mDeviceAddress);
mUserManager = getUserManager();
if (FeatureFlagUtils.isEnabled(context,
FeatureFlagUtils.SETTINGS_SHOW_STYLUS_PREFERENCES)) {
mInputDevice = getInputDevice(context);
}
super.onAttach(context);
if (mCachedDevice == null) {
// Close this page if device is null with invalid device mac address
@@ -191,6 +221,12 @@ public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTitleForInputDevice();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
@@ -269,6 +305,7 @@ public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment
mCachedDevice, lifecycle));
controllers.add(new BluetoothDetailsMacAddressController(context, this, mCachedDevice,
lifecycle));
controllers.add(new StylusDevicesController(context, mInputDevice, lifecycle));
controllers.add(new BluetoothDetailsRelatedToolsController(context, this, mCachedDevice,
lifecycle));
controllers.add(new BluetoothDetailsPairOtherController(context, this, mCachedDevice,
@@ -289,4 +326,16 @@ public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment
resolvedAttributes.recycle();
return width;
}
@VisibleForTesting
void setTitleForInputDevice() {
// TODO(b/254835745) once source filter for bt stylus merged
// && mInputDevice.supportsSource(InputDevice.SOURCE_BLUETOOTH_STYLUS))
if (mInputDevice != null) {
// This will override the default R.string.device_details_title "Device Details"
// that will show on non-stylus bluetooth devices.
// That title is set via the manifest and also from BluetoothDeviceUpdater.
getActivity().setTitle(getContext().getString(R.string.stylus_device_details_title));
}
}
}

View File

@@ -0,0 +1,199 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.connecteddevice.stylus;
import android.app.role.RoleManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.provider.Settings;
import android.util.Log;
import android.view.InputDevice;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import com.android.settings.R;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnResume;
import java.util.List;
/**
* This class adds stylus preferences.
*/
public class StylusDevicesController extends AbstractPreferenceController implements
Preference.OnPreferenceClickListener, LifecycleObserver, OnResume {
@VisibleForTesting
static final String KEY_STYLUS = "device_stylus";
@VisibleForTesting
static final String KEY_HANDWRITING = "handwriting_switch";
@VisibleForTesting
static final String KEY_IGNORE_BUTTON = "ignore_button";
@VisibleForTesting
static final String KEY_DEFAULT_NOTES = "default_notes";
private static final String TAG = "StylusDevicesController";
@Nullable
private final InputDevice mInputDevice;
@VisibleForTesting
PreferenceCategory mPreferencesContainer;
public StylusDevicesController(Context context, InputDevice inputDevice, Lifecycle lifecycle) {
super(context);
mInputDevice = inputDevice;
lifecycle.addObserver(this);
}
@Override
public boolean isAvailable() {
return mInputDevice != null && mInputDevice.supportsSource(InputDevice.SOURCE_STYLUS);
}
@Nullable
private Preference createDefaultNotesPreference() {
RoleManager rm = mContext.getSystemService(RoleManager.class);
if (rm == null) {
return null;
}
// TODO(b/254834764): replace with notes role once merged
List<String> roleHolders = rm.getRoleHoldersAsUser(RoleManager.ROLE_ASSISTANT,
mContext.getUser());
if (roleHolders.isEmpty()) {
return null;
}
String packageName = roleHolders.get(0);
PackageManager pm = mContext.getPackageManager();
String appName = packageName;
try {
ApplicationInfo ai = pm.getApplicationInfo(packageName,
PackageManager.ApplicationInfoFlags.of(0));
appName = ai == null ? packageName : pm.getApplicationLabel(ai).toString();
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "Notes role package not found.");
}
Preference pref = new Preference(mContext);
pref.setKey(KEY_DEFAULT_NOTES);
pref.setTitle(mContext.getString(R.string.stylus_default_notes_app));
pref.setIcon(R.drawable.ic_article);
pref.setEnabled(true);
pref.setSummary(appName);
return pref;
}
private SwitchPreference createHandwritingPreference() {
SwitchPreference pref = new SwitchPreference(mContext);
pref.setKey(KEY_HANDWRITING);
pref.setTitle(mContext.getString(R.string.stylus_textfield_handwriting));
pref.setIcon(R.drawable.ic_text_fields_alt);
pref.setOnPreferenceClickListener(this);
pref.setChecked(Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.STYLUS_HANDWRITING_ENABLED, 0) == 1);
return pref;
}
private SwitchPreference createButtonPressPreference() {
SwitchPreference pref = new SwitchPreference(mContext);
pref.setKey(KEY_IGNORE_BUTTON);
pref.setTitle(mContext.getString(R.string.stylus_ignore_button));
pref.setIcon(R.drawable.ic_block);
pref.setOnPreferenceClickListener(this);
return pref;
}
@Override
public boolean onPreferenceClick(Preference preference) {
String key = preference.getKey();
switch (key) {
case KEY_DEFAULT_NOTES:
PackageManager pm = mContext.getPackageManager();
String packageName = pm.getPermissionControllerPackageName();
// TODO(b/254834764): replace with notes role once merged
Intent intent = new Intent(Intent.ACTION_MANAGE_DEFAULT_APP).setPackage(
packageName).putExtra(Intent.EXTRA_ROLE_NAME, RoleManager.ROLE_ASSISTANT);
mContext.startActivity(intent);
break;
case KEY_HANDWRITING:
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.STYLUS_HANDWRITING_ENABLED,
((SwitchPreference) preference).isChecked() ? 1 : 0);
break;
case KEY_IGNORE_BUTTON:
// TODO(b/251199452): to turn off stylus button presses
break;
}
return true;
}
@Override
public final void displayPreference(PreferenceScreen screen) {
mPreferencesContainer = (PreferenceCategory) screen.findPreference(getPreferenceKey());
super.displayPreference(screen);
refresh();
}
@Override
public String getPreferenceKey() {
return KEY_STYLUS;
}
@Override
public void onResume() {
refresh();
}
private void refresh() {
if (!isAvailable()) return;
if (mInputDevice.getBluetoothAddress() != null) {
Preference notesPref = mPreferencesContainer.findPreference(KEY_DEFAULT_NOTES);
if (notesPref == null) {
notesPref = createDefaultNotesPreference();
if (notesPref != null) {
mPreferencesContainer.addPreference(notesPref);
}
}
}
Preference handwritingPref = mPreferencesContainer.findPreference(KEY_HANDWRITING);
// TODO(b/255732419): add proper InputMethodInfo conditional to show or hide
// InputMethodManager imm = mContext.getSystemService(InputMethodManager.class);
if (handwritingPref == null) {
mPreferencesContainer.addPreference(createHandwritingPreference());
}
Preference buttonPref = mPreferencesContainer.findPreference(KEY_IGNORE_BUTTON);
if (buttonPref == null) {
mPreferencesContainer.addPreference(createButtonPressPreference());
}
}
}

View File

@@ -21,6 +21,7 @@ import android.os.SystemProperties;
import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
import com.android.settingslib.development.DevelopmentSettingsEnabler;
/**
* The controller (on the transcode settings screen) indicating that by default we assume that apps
@@ -47,7 +48,11 @@ public class TranscodeDefaultOptionPreferenceController extends TogglePreference
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
if (DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)) {
return AVAILABLE;
} else {
return CONDITIONALLY_UNAVAILABLE;
}
}
@Override

View File

@@ -22,6 +22,7 @@ import android.os.SystemProperties;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
import com.android.settingslib.development.DevelopmentSettingsEnabler;
/**
* The controller (in the Media transcoding settings) indicating the user's preference to disable
@@ -49,7 +50,11 @@ public class TranscodeDisableCachePreferenceController extends TogglePreferenceC
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
if (DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)) {
return AVAILABLE;
} else {
return CONDITIONALLY_UNAVAILABLE;
}
}
@Override

View File

@@ -21,6 +21,7 @@ import android.os.SystemProperties;
import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
import com.android.settingslib.development.DevelopmentSettingsEnabler;
/**
* The controller for the "Enabling transcoding for all apps" switch on the transcode settings
@@ -37,7 +38,11 @@ public class TranscodeGlobalTogglePreferenceController extends TogglePreferenceC
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
if (DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)) {
return AVAILABLE;
} else {
return CONDITIONALLY_UNAVAILABLE;
}
}
@Override

View File

@@ -22,6 +22,7 @@ import android.os.SystemProperties;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
import com.android.settingslib.development.DevelopmentSettingsEnabler;
/**
* The controller (in the Media transcoding settings) indicating the user's preference to show
@@ -49,7 +50,11 @@ public class TranscodeNotificationPreferenceController extends TogglePreferenceC
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
if (DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)) {
return AVAILABLE;
} else {
return CONDITIONALLY_UNAVAILABLE;
}
}
@Override

View File

@@ -21,6 +21,7 @@ import android.os.SystemProperties;
import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
import com.android.settingslib.development.DevelopmentSettingsEnabler;
/**
* The controller for the User's control (over other transcoding preferences) preference switch on
@@ -47,7 +48,11 @@ public class TranscodeUserControlPreferenceController extends TogglePreferenceCo
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
if (DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)) {
return AVAILABLE;
} else {
return CONDITIONALLY_UNAVAILABLE;
}
}
@Override

View File

@@ -103,7 +103,17 @@ public class MyDeviceInfoFragment extends DashboardFragment
private static List<AbstractPreferenceController> buildPreferenceControllers(
Context context, MyDeviceInfoFragment fragment, Lifecycle lifecycle) {
final List<AbstractPreferenceController> controllers = new ArrayList<>();
controllers.add(new SimStatusPreferenceController(context, fragment));
SimStatusPreferenceController defaultRecord =
new SimStatusPreferenceController(context, fragment);
for (int slotIndex = 0; slotIndex < defaultRecord.getSimSlotSize(); slotIndex ++) {
SimStatusPreferenceController slotRecord =
new SimStatusPreferenceController(context, fragment);
slotRecord.setSimSlotStatus(slotIndex);
controllers.add(slotRecord);
}
controllers.add(new IpAddressPreferenceController(context, lifecycle));
controllers.add(new WifiMacAddressPreferenceController(context, lifecycle));
controllers.add(new BluetoothAddressPreferenceController(context, lifecycle));

View File

@@ -46,6 +46,8 @@ public class SimStatusPreferenceController extends
private final Fragment mFragment;
private final List<Preference> mPreferenceList = new ArrayList<>();
private int mSlotIndex = SubscriptionManager.INVALID_SIM_SLOT_INDEX;
public SimStatusPreferenceController(Context context, Fragment fragment) {
super(context);
@@ -57,9 +59,36 @@ public class SimStatusPreferenceController extends
@Override
public String getPreferenceKey() {
if (mSlotIndex != SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
return KEY_SIM_STATUS + mSlotIndex;
}
return KEY_SIM_STATUS;
}
/**
* Update the index of slot for this subscription.
* @param slotIndex index of slot
*/
public void setSimSlotStatus(int slotIndex) {
mSlotIndex = slotIndex;
}
/**
* Get number of subscription slots.
* @return number of slots
*/
public int getSimSlotSize() {
return isAvailable() ? mTelephonyManager.getPhoneCount() : 0;
}
/**
* Get the index of slot for this subscription.
* @return index of slot
*/
public int getSimSlotIndex() {
return mSlotIndex;
}
@Override
public boolean isAvailable() {
return SubscriptionUtil.isSimHardwareVisible(mContext) &&
@@ -72,22 +101,23 @@ public class SimStatusPreferenceController extends
if (!SubscriptionUtil.isSimHardwareVisible(mContext)) {
return;
}
final Preference preference = screen.findPreference(getPreferenceKey());
final Preference preference = screen.findPreference(KEY_SIM_STATUS);
if (!isAvailable() || preference == null || !preference.isVisible()) {
return;
}
final PreferenceCategory category = screen.findPreference(KEY_PREFERENCE_CATEGORY);
mPreferenceList.add(preference);
final int simStatusOrder = preference.getOrder();
screen.removePreference(preference);
preference.setVisible(false);
// Add additional preferences for each sim in the device
for (int simSlotNumber = 1; simSlotNumber < mTelephonyManager.getPhoneCount();
for (int simSlotNumber = 0; simSlotNumber < mTelephonyManager.getPhoneCount();
simSlotNumber++) {
final Preference multiSimPreference = createNewPreference(screen.getContext());
multiSimPreference.setCopyingEnabled(true);
multiSimPreference.setOrder(simStatusOrder + simSlotNumber);
multiSimPreference.setKey(KEY_SIM_STATUS + simSlotNumber);
multiSimPreference.setOrder(simStatusOrder + simSlotNumber + 1);
multiSimPreference.setKey(KEY_SIM_STATUS + simSlotNumber + 1);
category.addPreference(multiSimPreference);
mPreferenceList.add(multiSimPreference);
}

View File

@@ -43,8 +43,8 @@ public interface BatteryStateDao {
/** Gets the {@link Cursor} of all recorded data since last full charge within 7 days. */
@Query("SELECT * FROM BatteryState WHERE timestamp >= :timestampSixDaysAgo AND timestamp >= "
+ "(SELECT MAX(timestamp) FROM BatteryState WHERE isFullChargeCycleStart = 1)"
+ " ORDER BY timestamp ASC")
+ "(SELECT IFNULL((SELECT MAX(timestamp) FROM BatteryState "
+ "WHERE isFullChargeCycleStart = 1), 0)) ORDER BY timestamp ASC")
Cursor getCursorSinceLastFullCharge(long timestampSixDaysAgo);
/** Get the count of distinct timestamp after a specific timestamp. */

View File

@@ -22,6 +22,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Looper;
import android.os.UserHandle;
import android.provider.Settings;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
@@ -344,20 +345,20 @@ public class SimSlotChangeHandler {
Intent intent = ChooseSimActivity.getIntent(mContext);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(ChooseSimActivity.KEY_HAS_PSIM, psimInserted);
mContext.startActivity(intent);
mContext.startActivityAsUser(intent, UserHandle.SYSTEM);
}
private void startSwitchSlotConfirmDialogActivity(SubscriptionInfo subscriptionInfo) {
Intent intent = new Intent(mContext, SwitchToEsimConfirmDialogActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(SwitchToEsimConfirmDialogActivity.KEY_SUB_TO_ENABLE, subscriptionInfo);
mContext.startActivity(intent);
mContext.startActivityAsUser(intent, UserHandle.SYSTEM);
}
private void startDsdsDialogActivity() {
Intent intent = new Intent(mContext, DsdsDialogActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
mContext.startActivityAsUser(intent, UserHandle.SYSTEM);
}
private void startSimConfirmDialogActivity(int subId) {
@@ -368,7 +369,7 @@ public class SimSlotChangeHandler {
Log.d(TAG, "Start ToggleSubscriptionDialogActivity with " + subId + " under DSDS+Mep.");
Intent intent = ToggleSubscriptionDialogActivity.getIntent(mContext, subId, true);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
mContext.startActivityAsUser(intent, UserHandle.SYSTEM);
}
private boolean isMultipleEnabledProfilesSupported() {

View File

@@ -19,14 +19,14 @@ package com.android.settings.spa
import android.content.Context
import android.content.Intent
import com.android.settingslib.spa.framework.BrowseActivity
import com.android.settingslib.spa.framework.util.appendSpaParams
class SpaActivity : BrowseActivity() {
companion object {
@JvmStatic
fun startSpaActivity(context: Context, destination: String) {
val intent = Intent(context, SpaActivity::class.java).apply {
putExtra(KEY_DESTINATION, destination)
}
val intent = Intent(context, SpaActivity::class.java)
.appendSpaParams(destination = destination)
context.startActivity(intent)
}
}

View File

@@ -27,7 +27,7 @@ import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
import com.android.settingslib.spa.framework.common.SettingsPage
import com.android.settingslib.spa.framework.common.SettingsPageProvider
import com.android.settingslib.spa.framework.compose.navigator
import com.android.settingslib.spa.framework.util.asyncMapItem
import com.android.settingslib.spa.framework.util.mapItem
import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spaprivileged.model.app.AppListModel
@@ -78,15 +78,7 @@ data class AppRecordWithSize(
private class AllAppListModel : AppListModel<AppRecordWithSize> {
override fun transform(userIdFlow: Flow<Int>, appListFlow: Flow<List<ApplicationInfo>>) =
appListFlow.asyncMapItem { app ->
AppRecordWithSize(app)
}
override fun filter(
userIdFlow: Flow<Int>,
option: Int,
recordListFlow: Flow<List<AppRecordWithSize>>,
) = recordListFlow
appListFlow.mapItem(::AppRecordWithSize)
@Composable
override fun getSummary(option: Int, record: AppRecordWithSize) = record.app.getStorageSize()

View File

@@ -91,7 +91,10 @@ public class FingerprintEnrollEnrollingTest {
private Resources.Theme mTheme;
private static final int TOTAL_ENROLL_STEPS = 25;
private final int[] mSfpsStageThresholds = new int[]{0, 9, 13, 19, 25};
private final int[] mUdfpsStageThresholds = new int[]{0, 13, 17, 22};
private FingerprintEnrollEnrolling mActivity;
private Context mContext;
@@ -190,19 +193,19 @@ public class FingerprintEnrollEnrollingTest {
public void fingerprintUdfpsOverlayEnrollment_PlaysAllAnimationsAssetsCorrectly() {
initializeActivityFor(TYPE_UDFPS_OPTICAL);
int totalEnrollSteps = 25;
int initStageSteps = -1, initStageRemaining = 0;
final int totalStages = mUdfpsStageThresholds.length;
when(mSidecar.getEnrollmentSteps()).thenReturn(initStageSteps);
when(mSidecar.getEnrollmentRemaining()).thenReturn(initStageRemaining);
mActivity.onEnrollmentProgressChange(initStageSteps, initStageRemaining);
when(mSidecar.getEnrollmentSteps()).thenReturn(totalEnrollSteps);
when(mSidecar.getEnrollmentSteps()).thenReturn(TOTAL_ENROLL_STEPS);
for (int remaining = totalEnrollSteps; remaining > 0; remaining--) {
for (int remaining = TOTAL_ENROLL_STEPS; remaining > 0; remaining--) {
when(mSidecar.getEnrollmentRemaining()).thenReturn(remaining);
mActivity.onEnrollmentProgressChange(totalEnrollSteps, remaining);
mActivity.onEnrollmentProgressChange(TOTAL_ENROLL_STEPS, remaining);
}
List<Integer> expectedLottieAssetOrder = List.of(
@@ -213,7 +216,7 @@ public class FingerprintEnrollEnrollingTest {
);
ArgumentCaptor<Integer> lottieAssetCaptor = ArgumentCaptor.forClass(Integer.class);
verify(mIllustrationLottie, times(4)).setAnimation(lottieAssetCaptor.capture());
verify(mIllustrationLottie, times(totalStages)).setAnimation(lottieAssetCaptor.capture());
List<Integer> observedLottieAssetOrder = lottieAssetCaptor.getAllValues();
assertThat(observedLottieAssetOrder).isEqualTo(expectedLottieAssetOrder);
}
@@ -222,7 +225,6 @@ public class FingerprintEnrollEnrollingTest {
public void fingerprintSfpsEnroll_PlaysAllAnimationsAssetsCorrectly() {
initializeActivityFor(TYPE_POWER_BUTTON);
int totalEnrollSteps = 25;
int initStageSteps = -1, initStageRemaining = 0;
when(mSidecar.getEnrollmentSteps()).thenReturn(initStageSteps);
@@ -230,11 +232,11 @@ public class FingerprintEnrollEnrollingTest {
mActivity.onEnrollmentProgressChange(initStageSteps, initStageRemaining);
when(mSidecar.getEnrollmentSteps()).thenReturn(totalEnrollSteps);
when(mSidecar.getEnrollmentSteps()).thenReturn(TOTAL_ENROLL_STEPS);
for (int remaining = totalEnrollSteps; remaining > 0; remaining--) {
for (int remaining = TOTAL_ENROLL_STEPS; remaining > 0; remaining--) {
when(mSidecar.getEnrollmentRemaining()).thenReturn(remaining);
mActivity.onEnrollmentProgressChange(totalEnrollSteps, remaining);
mActivity.onEnrollmentProgressChange(TOTAL_ENROLL_STEPS, remaining);
}
List<Integer> expectedLottieAssetOrder = List.of(
@@ -360,6 +362,16 @@ public class FingerprintEnrollEnrollingTest {
doReturn(true).when(mSidecar).isEnrolling();
}
if (sensorType == TYPE_UDFPS_OPTICAL) {
// UDFPS : STAGE_CENTER = 0, ... , STAGE_RIGHT_EDGE = 3
final int totalStages = mUdfpsStageThresholds.length - 1;
for (int stage = 0; stage <= totalStages; stage++) {
doReturn(mUdfpsStageThresholds[stage]).when(mActivity).getStageThresholdSteps(
stage);
}
doReturn(true).when(mSidecar).isEnrolling();
}
ActivityController.of(mActivity).create(savedInstanceState);
mTheme = mActivity.getTheme();
}

View File

@@ -25,16 +25,21 @@ import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
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.content.Context;
import android.hardware.input.InputManager;
import android.os.Bundle;
import android.os.UserManager;
import android.util.FeatureFlagUtils;
import android.view.InputDevice;
import android.view.MenuInflater;
import android.view.MenuItem;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.preference.PreferenceScreen;
@@ -51,6 +56,7 @@ import org.mockito.Answers;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@@ -68,6 +74,7 @@ public class BluetoothDeviceDetailsFragmentTest {
private RoboMenu mMenu;
private MenuInflater mInflater;
private FragmentTransaction mFragmentTransaction;
private FragmentActivity mActivity;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private CachedBluetoothDevice mCachedDevice;
@@ -77,29 +84,18 @@ public class BluetoothDeviceDetailsFragmentTest {
private PreferenceScreen mPreferenceScreen;
@Mock
private UserManager mUserManager;
@Mock
private InputManager mInputManager;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
doReturn(mInputManager).when(mContext).getSystemService(InputManager.class);
removeInputDeviceWithMatchingBluetoothAddress();
FakeFeatureFactory.setupForTest();
mFragment = spy(BluetoothDeviceDetailsFragment.newInstance(TEST_ADDRESS));
doReturn(mLocalManager).when(mFragment).getLocalBluetoothManager(any());
doReturn(mCachedDevice).when(mFragment).getCachedDevice(any());
doReturn(mPreferenceScreen).when(mFragment).getPreferenceScreen();
doReturn(mUserManager).when(mFragment).getUserManager();
FragmentManager fragmentManager = mock(FragmentManager.class);
when(mFragment.getFragmentManager()).thenReturn(fragmentManager);
mFragmentTransaction = mock(FragmentTransaction.class);
when(fragmentManager.beginTransaction()).thenReturn(mFragmentTransaction);
when(mCachedDevice.getAddress()).thenReturn(TEST_ADDRESS);
when(mCachedDevice.getIdentityAddress()).thenReturn(TEST_ADDRESS);
Bundle args = new Bundle();
args.putString(BluetoothDeviceDetailsFragment.KEY_DEVICE_ADDRESS, TEST_ADDRESS);
mFragment.setArguments(args);
mFragment = setupFragment();
mFragment.onAttach(mContext);
mMenu = new RoboMenu(mContext);
@@ -111,6 +107,43 @@ public class BluetoothDeviceDetailsFragmentTest {
assertThat(mFragment.mDeviceAddress).isEqualTo(TEST_ADDRESS);
assertThat(mFragment.mManager).isEqualTo(mLocalManager);
assertThat(mFragment.mCachedDevice).isEqualTo(mCachedDevice);
assertThat(mFragment.mInputDevice).isEqualTo(null);
}
@Test
public void verifyOnAttachResult_flagEnabledAndInputDeviceSet_returnsInputDevice() {
FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SETTINGS_SHOW_STYLUS_PREFERENCES,
true);
InputDevice inputDevice = createInputDeviceWithMatchingBluetoothAddress();
BluetoothDeviceDetailsFragment fragment = setupFragment();
FragmentActivity activity = mock(FragmentActivity.class);
doReturn(inputDevice).when(fragment).getInputDevice(any());
doReturn(activity).when(fragment).getActivity();
fragment.onAttach(mContext);
assertThat(fragment.mDeviceAddress).isEqualTo(TEST_ADDRESS);
assertThat(fragment.mManager).isEqualTo(mLocalManager);
assertThat(fragment.mCachedDevice).isEqualTo(mCachedDevice);
assertThat(fragment.mInputDevice).isEqualTo(inputDevice);
}
@Test
public void verifyOnAttachResult_flagDisabled_returnsNullInputDevice() {
FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SETTINGS_SHOW_STYLUS_PREFERENCES,
false);
InputDevice inputDevice = createInputDeviceWithMatchingBluetoothAddress();
BluetoothDeviceDetailsFragment fragment = setupFragment();
FragmentActivity activity = mock(FragmentActivity.class);
doReturn(inputDevice).when(fragment).getInputDevice(any());
doReturn(activity).when(fragment).getActivity();
fragment.onAttach(mContext);
assertThat(fragment.mDeviceAddress).isEqualTo(TEST_ADDRESS);
assertThat(fragment.mManager).isEqualTo(mLocalManager);
assertThat(fragment.mCachedDevice).isEqualTo(mCachedDevice);
assertThat(fragment.mInputDevice).isEqualTo(null);
}
@Test
@@ -122,6 +155,31 @@ public class BluetoothDeviceDetailsFragmentTest {
assertThat(item.getTitle()).isEqualTo(mContext.getString(R.string.bluetooth_rename_button));
}
@Test
public void getTitle_inputDeviceTitle() {
FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SETTINGS_SHOW_STYLUS_PREFERENCES,
true);
doReturn(mock(InputDevice.class)).when(mFragment).getInputDevice(mContext);
mFragment.onAttach(mContext);
mFragment.setTitleForInputDevice();
assertThat(mActivity.getTitle().toString()).isEqualTo(
mContext.getString(R.string.stylus_device_details_title));
}
@Test
public void getTitle_inputDeviceNull_doesNotSetTitle() {
FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SETTINGS_SHOW_STYLUS_PREFERENCES,
true);
doReturn(null).when(mFragment).getInputDevice(mContext);
mFragment.onAttach(mContext);
mFragment.setTitleForInputDevice();
verify(mActivity, times(0)).setTitle(any());
}
@Test
public void editMenu_clicked_showDialog() {
mFragment.onCreateOptionsMenu(mMenu, mInflater);
@@ -131,7 +189,7 @@ public class BluetoothDeviceDetailsFragmentTest {
mFragment.onOptionsItemSelected(item);
assertThat(item.getItemId())
.isEqualTo(BluetoothDeviceDetailsFragment.EDIT_DEVICE_NAME_ITEM_ID);
.isEqualTo(BluetoothDeviceDetailsFragment.EDIT_DEVICE_NAME_ITEM_ID);
verify(mFragmentTransaction).add(captor.capture(), eq(RemoteDeviceNameDialogFragment.TAG));
RemoteDeviceNameDialogFragment dialog = (RemoteDeviceNameDialogFragment) captor.getValue();
assertThat(dialog).isNotNull();
@@ -145,4 +203,44 @@ public class BluetoothDeviceDetailsFragmentTest {
verify(mFragment).finish();
}
private InputDevice createInputDeviceWithMatchingBluetoothAddress() {
doReturn(new int[]{0}).when(mInputManager).getInputDeviceIds();
InputDevice device = mock(InputDevice.class);
doReturn(TEST_ADDRESS).when(mInputManager).getInputDeviceBluetoothAddress(0);
doReturn(device).when(mInputManager).getInputDevice(0);
return device;
}
private InputDevice removeInputDeviceWithMatchingBluetoothAddress() {
doReturn(new int[]{0}).when(mInputManager).getInputDeviceIds();
doReturn(null).when(mInputManager).getInputDeviceBluetoothAddress(0);
return null;
}
private BluetoothDeviceDetailsFragment setupFragment() {
BluetoothDeviceDetailsFragment fragment = spy(
BluetoothDeviceDetailsFragment.newInstance(TEST_ADDRESS));
doReturn(mLocalManager).when(fragment).getLocalBluetoothManager(any());
doReturn(mCachedDevice).when(fragment).getCachedDevice(any());
doReturn(mPreferenceScreen).when(fragment).getPreferenceScreen();
doReturn(mUserManager).when(fragment).getUserManager();
mActivity = spy(Robolectric.setupActivity(FragmentActivity.class));
doReturn(mActivity).when(fragment).getActivity();
doReturn(mContext).when(fragment).getContext();
FragmentManager fragmentManager = mock(FragmentManager.class);
doReturn(fragmentManager).when(fragment).getFragmentManager();
mFragmentTransaction = mock(FragmentTransaction.class);
doReturn(mFragmentTransaction).when(fragmentManager).beginTransaction();
doReturn(TEST_ADDRESS).when(mCachedDevice).getAddress();
doReturn(TEST_ADDRESS).when(mCachedDevice).getIdentityAddress();
Bundle args = new Bundle();
args.putString(BluetoothDeviceDetailsFragment.KEY_DEVICE_ADDRESS, TEST_ADDRESS);
fragment.setArguments(args);
return fragment;
}
}

View File

@@ -0,0 +1,233 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.connecteddevice.stylus;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.role.RoleManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.UserHandle;
import android.provider.Settings;
import android.view.InputDevice;
import android.view.inputmethod.InputMethodManager;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import java.util.Collections;
@RunWith(RobolectricTestRunner.class)
public class StylusDevicesControllerTest {
private static final String NOTES_PACKAGE_NAME = "notes.package";
private static final CharSequence NOTES_APP_LABEL = "App Label";
private Context mContext;
private StylusDevicesController mController;
private PreferenceCategory mPreferenceContainer;
private PreferenceScreen mScreen;
private InputDevice mInputDevice;
@Mock
private InputMethodManager mImm;
@Mock
private PackageManager mPm;
@Mock
private RoleManager mRm;
@Mock
private Lifecycle mLifecycle;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mContext = spy(ApplicationProvider.getApplicationContext());
PreferenceManager preferenceManager = new PreferenceManager(mContext);
mScreen = preferenceManager.createPreferenceScreen(mContext);
mPreferenceContainer = new PreferenceCategory(mContext);
mPreferenceContainer.setKey(StylusDevicesController.KEY_STYLUS);
mScreen.addPreference(mPreferenceContainer);
when(mContext.getSystemService(InputMethodManager.class)).thenReturn(mImm);
when(mContext.getSystemService(RoleManager.class)).thenReturn(mRm);
doNothing().when(mContext).startActivity(any());
// TODO(b/254834764): notes role placeholder
when(mRm.getRoleHoldersAsUser(eq(RoleManager.ROLE_ASSISTANT), any(UserHandle.class)))
.thenReturn(Collections.singletonList(NOTES_PACKAGE_NAME));
when(mContext.getPackageManager()).thenReturn(mPm);
when(mPm.getApplicationInfo(eq(NOTES_PACKAGE_NAME),
any(PackageManager.ApplicationInfoFlags.class))).thenReturn(new ApplicationInfo());
when(mPm.getApplicationLabel(any(ApplicationInfo.class))).thenReturn(NOTES_APP_LABEL);
mInputDevice = spy(new InputDevice.Builder()
.setId(1)
.setSources(InputDevice.SOURCE_STYLUS)
.build());
when(mInputDevice.getBluetoothAddress()).thenReturn("SOME:ADDRESS");
mController = new StylusDevicesController(mContext, mInputDevice, mLifecycle);
}
@Test
public void noInputDevice_noPreference() {
StylusDevicesController controller = new StylusDevicesController(
mContext, null, mLifecycle
);
showScreen(controller);
assertThat(mPreferenceContainer.getPreferenceCount()).isEqualTo(0);
}
@Test
public void btStylusInputDevice_showsAllPreferences() {
showScreen(mController);
Preference defaultNotesPref = mPreferenceContainer.getPreference(0);
Preference handwritingPref = mPreferenceContainer.getPreference(1);
Preference buttonPref = mPreferenceContainer.getPreference(2);
assertThat(mPreferenceContainer.getPreferenceCount()).isEqualTo(3);
assertThat(defaultNotesPref.getTitle().toString()).isEqualTo(
mContext.getString(R.string.stylus_default_notes_app));
assertThat(handwritingPref.getTitle().toString()).isEqualTo(
mContext.getString(R.string.stylus_textfield_handwriting));
assertThat(buttonPref.getTitle().toString()).isEqualTo(
mContext.getString(R.string.stylus_ignore_button));
}
@Test
@Ignore // TODO(b/255732419): unignore when InputMethodInfo available
public void btStylusInputDevice_noHandwritingIme_showsSomePreferences() {
showScreen(mController);
Preference defaultNotesPref = mPreferenceContainer.getPreference(0);
Preference buttonPref = mPreferenceContainer.getPreference(1);
assertThat(mPreferenceContainer.getPreferenceCount()).isEqualTo(2);
assertThat(defaultNotesPref.getTitle().toString()).isEqualTo(
mContext.getString(R.string.stylus_default_notes_app));
assertThat(buttonPref.getTitle().toString()).isEqualTo(
mContext.getString(R.string.stylus_ignore_button));
}
@Test
public void defaultNotesPreference_showsNotesRoleApp() {
showScreen(mController);
Preference defaultNotesPref = mPreferenceContainer.getPreference(0);
assertThat(defaultNotesPref.getTitle().toString()).isEqualTo(
mContext.getString(R.string.stylus_default_notes_app));
assertThat(defaultNotesPref.getSummary().toString()).isEqualTo(NOTES_APP_LABEL.toString());
}
@Test
public void defaultNotesPreference_noRoleHolder_hidesNotesRoleApp() {
// TODO(b/254834764): replace with notes role once merged
when(mRm.getRoleHoldersAsUser(eq(RoleManager.ROLE_ASSISTANT), any(UserHandle.class)))
.thenReturn(Collections.emptyList());
showScreen(mController);
for (int i = 0; i < mPreferenceContainer.getPreferenceCount(); i++) {
Preference pref = mPreferenceContainer.getPreference(i);
assertThat(pref.getTitle().toString()).isNotEqualTo(
mContext.getString(R.string.stylus_default_notes_app));
}
}
@Test
public void defaultNotesPreferenceClick_sendsManageDefaultRoleIntent() {
final String permissionPackageName = "permissions.package";
when(mPm.getPermissionControllerPackageName()).thenReturn(permissionPackageName);
final ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
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);
// TODO(b/254834764): when notes role is merged
assertThat(intent.getStringExtra(Intent.EXTRA_ROLE_NAME)).isEqualTo(
RoleManager.ROLE_ASSISTANT);
}
@Test
public void handwritingPreference_checkedWhenFlagTrue() {
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.STYLUS_HANDWRITING_ENABLED, 1);
showScreen(mController);
SwitchPreference handwritingPref = (SwitchPreference) mPreferenceContainer.getPreference(1);
assertThat(handwritingPref.isChecked()).isEqualTo(true);
}
@Test
public void handwritingPreference_uncheckedWhenFlagFalse() {
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.STYLUS_HANDWRITING_ENABLED, 0);
showScreen(mController);
SwitchPreference handwritingPref = (SwitchPreference) mPreferenceContainer.getPreference(1);
assertThat(handwritingPref.isChecked()).isEqualTo(false);
}
@Test
public void handwritingPreference_updatesFlagOnClick() {
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.STYLUS_HANDWRITING_ENABLED, 0);
showScreen(mController);
SwitchPreference handwritingPref = (SwitchPreference) mPreferenceContainer.getPreference(1);
handwritingPref.performClick();
assertThat(handwritingPref.isChecked()).isEqualTo(true);
assertThat(Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.STYLUS_HANDWRITING_ENABLED, -1)).isEqualTo(1);
}
private void showScreen(StylusDevicesController controller) {
controller.displayPreference(mScreen);
}
}

View File

@@ -24,8 +24,8 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.os.UserManager;
import android.content.res.Resources;
import android.os.UserManager;
import android.telephony.TelephonyManager;
import androidx.fragment.app.Fragment;
@@ -36,6 +36,9 @@ import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -44,7 +47,6 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.util.ReflectionHelpers;
@RunWith(RobolectricTestRunner.class)
public class SimStatusPreferenceControllerTest {
@@ -52,6 +54,8 @@ public class SimStatusPreferenceControllerTest {
@Mock
private Preference mPreference;
@Mock
private Preference mFirstSimPreference;
@Mock
private Preference mSecondSimPreference;
@Mock
private PreferenceScreen mScreen;
@@ -77,18 +81,31 @@ public class SimStatusPreferenceControllerTest {
when(mContext.getResources()).thenReturn(mResources);
when(mResources.getBoolean(R.bool.config_show_sim_info)).thenReturn(true);
doReturn(mTelephonyManager).when(mContext)
.getSystemService(Context.TELEPHONY_SERVICE);
doReturn(mUserManager).when(mContext).getSystemService(UserManager.class);
mController = spy(new SimStatusPreferenceController(mContext, mFragment));
final List<Preference> preferencePool = new ArrayList<Preference>();
preferencePool.add(mFirstSimPreference);
preferencePool.add(mSecondSimPreference);
mController = spy(new SimStatusPreferenceController(mContext, mFragment) {
@Override
public Preference createNewPreference(Context context) {
return preferencePool.remove(0);
}
});
doReturn(true).when(mController).isAvailable();
when(mScreen.getContext()).thenReturn(mContext);
final String categoryKey = "device_detail_category";
when(mScreen.findPreference(categoryKey)).thenReturn(mCategory);
doReturn(mSecondSimPreference).when(mController).createNewPreference(mContext);
ReflectionHelpers.setField(mController, "mTelephonyManager", mTelephonyManager);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
final String baseEntryKey = "sim_status";
when(mScreen.findPreference(baseEntryKey)).thenReturn(mPreference);
final String prefKey = mController.getPreferenceKey();
when(mPreference.getKey()).thenReturn(prefKey);
when(mPreference.isVisible()).thenReturn(true);
mController.setSimSlotStatus(-1);
}
@Test
@@ -107,8 +124,8 @@ public class SimStatusPreferenceControllerTest {
mController.updateState(mPreference);
verify(mPreference).setTitle(mContext.getString(R.string.sim_status_title));
verify(mPreference).setSummary(anyString());
verify(mFirstSimPreference).setTitle(mContext.getString(R.string.sim_status_title));
verify(mFirstSimPreference).setSummary(anyString());
}
@Test
@@ -118,11 +135,11 @@ public class SimStatusPreferenceControllerTest {
mController.updateState(mPreference);
verify(mPreference).setTitle(
verify(mFirstSimPreference).setTitle(
mContext.getString(R.string.sim_status_title_sim_slot, 1 /* sim slot */));
verify(mSecondSimPreference).setTitle(
mContext.getString(R.string.sim_status_title_sim_slot, 2 /* sim slot */));
verify(mPreference).setSummary(anyString());
verify(mFirstSimPreference).setSummary(anyString());
verify(mSecondSimPreference).setSummary(anyString());
}
@@ -130,9 +147,10 @@ public class SimStatusPreferenceControllerTest {
public void handlePreferenceTreeClick_shouldStartDialogFragment() {
when(mFragment.getChildFragmentManager()).thenReturn(
mock(FragmentManager.class, Answers.RETURNS_DEEP_STUBS));
when(mTelephonyManager.getPhoneCount()).thenReturn(2);
mController.displayPreference(mScreen);
mController.handlePreferenceTreeClick(mPreference);
mController.handlePreferenceTreeClick(mFirstSimPreference);
verify(mFragment).getChildFragmentManager();
}

View File

@@ -53,10 +53,8 @@ public final class BatteryStateDaoTest {
mContext = ApplicationProvider.getApplicationContext();
mDatabase = BatteryTestUtils.setUpBatteryStateDatabase(mContext);
mBatteryStateDao = mDatabase.batteryStateDao();
BatteryTestUtils.insertDataToBatteryStateDatabase(
mContext, TIMESTAMP3, PACKAGE_NAME3);
BatteryTestUtils.insertDataToBatteryStateDatabase(
mContext, TIMESTAMP2, PACKAGE_NAME2);
BatteryTestUtils.insertDataToBatteryStateDatabase(mContext, TIMESTAMP3, PACKAGE_NAME3);
BatteryTestUtils.insertDataToBatteryStateDatabase(mContext, TIMESTAMP2, PACKAGE_NAME2);
BatteryTestUtils.insertDataToBatteryStateDatabase(
mContext, TIMESTAMP1, PACKAGE_NAME1, /*multiple=*/ true,
/*isFullChargeStart=*/ true);
@@ -100,6 +98,24 @@ public final class BatteryStateDaoTest {
assertThat(cursor2.getString(3 /*packageName*/)).isEqualTo(PACKAGE_NAME3);
}
@Test
public void batteryStateDao_getCursorSinceLastFullCharge_noFullChargeData_returnSevenDaysData()
throws Exception {
mBatteryStateDao.clearAll();
BatteryTestUtils.insertDataToBatteryStateDatabase(mContext, TIMESTAMP3, PACKAGE_NAME3);
BatteryTestUtils.insertDataToBatteryStateDatabase(mContext, TIMESTAMP2, PACKAGE_NAME2);
BatteryTestUtils.insertDataToBatteryStateDatabase(mContext, TIMESTAMP1, PACKAGE_NAME1);
final Cursor cursor = mBatteryStateDao.getCursorSinceLastFullCharge(TIMESTAMP2);
assertThat(cursor.getCount()).isEqualTo(2);
assertThat(cursor.getColumnCount()).isEqualTo(CURSOR_COLUMN_SIZE);
// Verifies the queried first battery state.
cursor.moveToFirst();
assertThat(cursor.getString(3 /*packageName*/)).isEqualTo(PACKAGE_NAME2);
// Verifies the queried third battery state.
cursor.moveToNext();
assertThat(cursor.getString(3 /*packageName*/)).isEqualTo(PACKAGE_NAME3);
}
@Test
public void batteryStateDao_clearAllBefore() throws Exception {
mBatteryStateDao.clearAllBefore(TIMESTAMP2);

View File

@@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.os.SystemProperties;
import android.provider.Settings;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -36,11 +37,14 @@ public class TranscodeDefaultOptionPreferenceControllerTest {
"persist.sys.fuse.transcode_default";
private TranscodeDefaultOptionPreferenceController mUnderTest;
private Context mContext;
@Before
public void setUp() {
Context context = ApplicationProvider.getApplicationContext();
mUnderTest = new TranscodeDefaultOptionPreferenceController(context, "some_key");
mContext = ApplicationProvider.getApplicationContext();
mUnderTest = new TranscodeDefaultOptionPreferenceController(mContext, "some_key");
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1);
}
@Test
@@ -74,4 +78,12 @@ public class TranscodeDefaultOptionPreferenceControllerTest {
assertThat(mUnderTest.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.AVAILABLE);
}
@Test
public void getAvailabilityStatus_developerOptionFalse_shouldReturnUNAVAILABLE() {
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0);
assertThat(mUnderTest.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
}
}

View File

@@ -22,6 +22,7 @@ import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.os.SystemProperties;
import android.provider.Settings;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -36,11 +37,14 @@ import org.junit.runner.RunWith;
public class TranscodeDisableCachePreferenceControllerTest {
private TranscodeDisableCachePreferenceController mUnderTest;
private Context mContext;
@Before
public void setUp() {
Context context = ApplicationProvider.getApplicationContext();
mUnderTest = new TranscodeDisableCachePreferenceController(context, "some_key");
mContext = ApplicationProvider.getApplicationContext();
mUnderTest = new TranscodeDisableCachePreferenceController(mContext, "some_key");
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1);
}
@Test
@@ -74,4 +78,12 @@ public class TranscodeDisableCachePreferenceControllerTest {
assertThat(mUnderTest.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.AVAILABLE);
}
@Test
public void getAvailabilityStatus_developerOptionFalse_shouldReturnUNAVAILABLE() {
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0);
assertThat(mUnderTest.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
}
}

View File

@@ -20,10 +20,13 @@ import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.os.SystemProperties;
import android.provider.Settings;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -34,11 +37,14 @@ public class TranscodeGlobalTogglePreferenceControllerTest {
private static final String TRANSCODE_ENABLED_PROP_KEY = "persist.sys.fuse.transcode_enabled";
private TranscodeGlobalTogglePreferenceController mController;
private Context mContext;
@Before
public void setUp() {
Context context = ApplicationProvider.getApplicationContext();
mController = new TranscodeGlobalTogglePreferenceController(context, "test_key");
mContext = ApplicationProvider.getApplicationContext();
mController = new TranscodeGlobalTogglePreferenceController(mContext, "test_key");
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1);
}
@Test
@@ -75,4 +81,12 @@ public class TranscodeGlobalTogglePreferenceControllerTest {
// Verify the system property was updated.
assertThat(SystemProperties.getBoolean(TRANSCODE_ENABLED_PROP_KEY, true)).isFalse();
}
@Test
public void getAvailabilityStatus_developerOptionFalse_shouldReturnUNAVAILABLE() {
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0);
assertThat(mController.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
}
}

View File

@@ -22,6 +22,7 @@ import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.os.SystemProperties;
import android.provider.Settings;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -36,10 +37,14 @@ import org.junit.runner.RunWith;
public class TranscodeNotificationPreferenceControllerTest {
private TranscodeNotificationPreferenceController mUnderTest;
private Context mContext;
@Before
public void setUp() {
Context context = ApplicationProvider.getApplicationContext();
mUnderTest = new TranscodeNotificationPreferenceController(context, "notification_key");
mContext = ApplicationProvider.getApplicationContext();
mUnderTest = new TranscodeNotificationPreferenceController(mContext, "notification_key");
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1);
}
@Test
@@ -73,4 +78,12 @@ public class TranscodeNotificationPreferenceControllerTest {
assertThat(mUnderTest.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.AVAILABLE);
}
@Test
public void getAvailabilityStatus_developerOptionFalse_shouldReturnUNAVAILABLE() {
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0);
assertThat(mUnderTest.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
}
}

View File

@@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.os.SystemProperties;
import android.provider.Settings;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -36,11 +37,14 @@ public class TranscodeUserControlPreferenceControllerTest {
"persist.sys.fuse.transcode_user_control";
private TranscodeUserControlPreferenceController mUnderTest;
private Context mContext;
@Before
public void setUp() {
Context context = ApplicationProvider.getApplicationContext();
mUnderTest = new TranscodeUserControlPreferenceController(context, "some_key");
mContext = ApplicationProvider.getApplicationContext();
mUnderTest = new TranscodeUserControlPreferenceController(mContext, "some_key");
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1);
}
@Test
@@ -74,4 +78,12 @@ public class TranscodeUserControlPreferenceControllerTest {
assertThat(mUnderTest.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.AVAILABLE);
}
@Test
public void getAvailabilityStatus_developerOptionFalse_shouldReturnUNAVAILABLE() {
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0);
assertThat(mUnderTest.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
}
}