Snap for 6549967 from 649e54d414 to mainline-release
Change-Id: Ieb3f025f4f9078c25c7508e207971601d3f16fe5
This commit is contained in:
@@ -25,7 +25,6 @@
|
||||
android:layout_width="56dip"
|
||||
android:layout_height="56dip"
|
||||
android:layout_gravity="bottom"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:contentDescription="@string/user_image_photo_selector"
|
||||
android:background="@*android:drawable/spinner_background_holo_dark"
|
||||
android:scaleType="fitCenter"/>
|
||||
|
||||
@@ -69,10 +69,10 @@
|
||||
<Button
|
||||
android:id="@+id/nfc_how_it_works_button"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:text="@string/nfc_how_it_works_got_it"
|
||||
android:textSize="14sp"
|
||||
android:textColor="#263238"
|
||||
|
||||
@@ -32,7 +32,8 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="@*android:dimen/status_bar_icon_size"
|
||||
android:paddingBottom="6dp">
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginBottom="6dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon"
|
||||
@@ -62,11 +63,10 @@
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/alerted_icon"
|
||||
android:layout_width="@*android:dimen/status_bar_icon_size"
|
||||
android:layout_height="@*android:dimen/status_bar_icon_size"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginStart="6dp"
|
||||
android:paddingTop="1dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:visibility="gone"
|
||||
android:tint="?android:attr/textColorSecondary"
|
||||
@@ -75,11 +75,9 @@
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/profile_badge"
|
||||
android:layout_width="@*android:dimen/status_bar_icon_size"
|
||||
android:layout_height="@*android:dimen/status_bar_icon_size"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:paddingTop="1dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:contentDescription="@*android:string/notification_work_profile_content_description"
|
||||
android:layout_toStartOf="@id/timestamp"
|
||||
@@ -89,11 +87,7 @@
|
||||
android:id="@+id/timestamp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="@*android:dimen/status_bar_icon_size"
|
||||
android:layout_alignBottom="@android:id/widget_frame"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignTop="@android:id/widget_frame"
|
||||
android:layout_centerVertical="true"
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@style/TextAppearance.NotificationHistory.AppName"
|
||||
|
||||
@@ -1,129 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2013 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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical"
|
||||
android:focusable="true"
|
||||
android:clickable="true" >
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:id="@+id/app_restrictions_pref"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
||||
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
|
||||
android:background="?android:attr/selectableItemBackground" >
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:minWidth="@*android:dimen/preference_icon_minWidth"
|
||||
android:orientation="horizontal">
|
||||
<ImageView
|
||||
android:id="@android:id/icon"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_gravity="center"
|
||||
android:minWidth="48dp"
|
||||
android:scaleType="centerInside"
|
||||
android:layout_marginEnd="@*android:dimen/preference_item_padding_inner"/>
|
||||
</LinearLayout>
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="6dip"
|
||||
android:layout_marginTop="6dip"
|
||||
android:layout_marginBottom="6dip"
|
||||
android:layout_weight="1">
|
||||
<TextView
|
||||
android:id="@android:id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
tools:text="Richard"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:ellipsize="marquee"
|
||||
android:fadingEdge="horizontal"/>
|
||||
<TextView
|
||||
android:id="@android:id/summary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@android:id/title"
|
||||
android:layout_alignStart="@android:id/title"
|
||||
android:paddingBottom="3dip"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textSize="13sp"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:focusable="false"
|
||||
android:text="@string/user_summary_restricted_profile"
|
||||
android:maxLines="4" />
|
||||
</RelativeLayout>
|
||||
<ImageView
|
||||
android:id="@+id/delete"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="fill_parent"
|
||||
android:paddingStart="16dip"
|
||||
android:paddingEnd="16dip"
|
||||
android:src="@drawable/ic_delete"
|
||||
android:contentDescription="@string/user_delete_user_description"
|
||||
android:layout_gravity="center"
|
||||
android:background="?android:attr/selectableItemBackground" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/switch_pref"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"
|
||||
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
||||
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
|
||||
android:background="?android:attr/selectableItemBackground" >
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/switchIcon"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_gravity="center"
|
||||
android:src="@drawable/ic_swap"
|
||||
android:minWidth="48dp"
|
||||
android:scaleType="centerInside"
|
||||
android:layout_marginEnd="@*android:dimen/preference_item_padding_inner"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/switchTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
tools:text="Switch to Richard"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:ellipsize="marquee"
|
||||
android:fadingEdge="horizontal"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View android:layout_width="match_parent"
|
||||
android:layout_height="2dp"
|
||||
android:background="@color/divider_color" />
|
||||
</LinearLayout>
|
||||
@@ -12046,6 +12046,9 @@
|
||||
<!-- Power menu setting privacy show controls [CHAR LIMIT=NONE] -->
|
||||
<string name="power_menu_privacy_show_controls">Show controls when locked</string>
|
||||
|
||||
<!-- Power menu setting privacy show cards [CHAR LIMIT=NONE] -->
|
||||
<string name="power_menu_privacy_show_cards">Show cards when locked</string>
|
||||
|
||||
<!-- Power menu setting privacy hide all [CHAR LIMIT=NONE] -->
|
||||
<string name="power_menu_privacy_hide">Hide cards and controls when locked</string>
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2006 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -344,11 +343,11 @@
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.NotificationHistory.Title">
|
||||
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
|
||||
<item name="android:fontFamily">@*android:string/config_headlineFontFamilyMedium</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.NotificationHistory.Text">
|
||||
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
|
||||
<item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
|
||||
<item name="android:textColor">?android:attr/textColorSecondary</item>
|
||||
</style>
|
||||
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
android:key="enable_calling"
|
||||
android:icon="@drawable/ic_phone"
|
||||
android:title="@string/user_enable_calling_sms" />
|
||||
<com.android.settingslib.RestrictedPreference
|
||||
android:key="app_and_content_access"
|
||||
android:icon="@drawable/ic_lock_closed"
|
||||
android:title="@string/user_restrictions_title" />
|
||||
<com.android.settingslib.RestrictedPreference
|
||||
android:key="remove_user"
|
||||
android:icon="@drawable/ic_delete"
|
||||
|
||||
@@ -30,7 +30,6 @@ import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.loader.app.LoaderManager;
|
||||
import androidx.loader.content.Loader;
|
||||
|
||||
import com.android.settings.users.RestrictedProfileSettings;
|
||||
import com.android.settingslib.license.LicenseHtmlLoaderCompat;
|
||||
|
||||
import java.io.File;
|
||||
@@ -78,7 +77,7 @@ public class SettingsLicenseActivity extends FragmentActivity implements
|
||||
|
||||
@VisibleForTesting
|
||||
Uri getUriFromGeneratedHtmlFile(File generatedHtmlFile) {
|
||||
return FileProvider.getUriForFile(this, RestrictedProfileSettings.FILE_PROVIDER_AUTHORITY,
|
||||
return FileProvider.getUriForFile(this, Utils.FILE_PROVIDER_AUTHORITY,
|
||||
generatedHtmlFile);
|
||||
}
|
||||
|
||||
|
||||
@@ -116,6 +116,8 @@ public final class Utils extends com.android.settingslib.Utils {
|
||||
|
||||
private static final String TAG = "Settings";
|
||||
|
||||
public static final String FILE_PROVIDER_AUTHORITY = "com.android.settings.files";
|
||||
|
||||
/**
|
||||
* Set the preference's title to the matching activity's label.
|
||||
*/
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.settings.gestures;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
|
||||
@@ -37,7 +38,9 @@ public class DeviceControlsPreferenceController extends GesturePreferenceControl
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return AVAILABLE;
|
||||
boolean available = mContext.getPackageManager().hasSystemFeature(
|
||||
PackageManager.FEATURE_CONTROLS);
|
||||
return available ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.settings.gestures;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.android.settings.R;
|
||||
@@ -37,15 +38,15 @@ public class PowerMenuPreferenceController extends BasePreferenceController {
|
||||
|
||||
@Override
|
||||
public CharSequence getSummary() {
|
||||
boolean controlsEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
|
||||
CONTROLS_ENABLED_SETTING, 1) == 1;
|
||||
boolean cardsEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
|
||||
CARDS_ENABLED_SETTING, 0) == 1;
|
||||
boolean cardsVisible = cardsEnabled && Settings.Secure.getInt(mContext.getContentResolver(),
|
||||
CARDS_AVAILABLE_SETTING, 0) == 1;
|
||||
if (controlsEnabled && cardsVisible) {
|
||||
boolean controlsVisible = isControlsAvailable()
|
||||
&& Settings.Secure.getInt(mContext.getContentResolver(),
|
||||
CONTROLS_ENABLED_SETTING, 1) == 1;
|
||||
boolean cardsVisible = isCardsAvailable()
|
||||
&& Settings.Secure.getInt(mContext.getContentResolver(),
|
||||
CARDS_ENABLED_SETTING, 0) == 1;
|
||||
if (controlsVisible && cardsVisible) {
|
||||
return mContext.getText(R.string.power_menu_cards_passes_device_controls);
|
||||
} else if (controlsEnabled) {
|
||||
} else if (controlsVisible) {
|
||||
return mContext.getText(R.string.power_menu_device_controls);
|
||||
} else if (cardsVisible) {
|
||||
return mContext.getText(R.string.power_menu_cards_passes);
|
||||
@@ -56,6 +57,15 @@ public class PowerMenuPreferenceController extends BasePreferenceController {
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return AVAILABLE;
|
||||
return isCardsAvailable() || isControlsAvailable() ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
|
||||
}
|
||||
|
||||
private boolean isControlsAvailable() {
|
||||
return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CONTROLS);
|
||||
}
|
||||
|
||||
private boolean isCardsAvailable() {
|
||||
return Settings.Secure.getInt(mContext.getContentResolver(),
|
||||
CARDS_AVAILABLE_SETTING, 0) == 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.settings.gestures;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
|
||||
@@ -57,13 +58,20 @@ public class PowerMenuPrivacyPreferenceController extends TogglePreferenceContro
|
||||
public CharSequence getSummary() {
|
||||
boolean cardsAvailable = Settings.Secure.getInt(mContext.getContentResolver(),
|
||||
CARDS_AVAILABLE_KEY, 0) != 0;
|
||||
boolean controlsAvailable = isControlsAvailable();
|
||||
final int res;
|
||||
if (!isSecure()) {
|
||||
res = R.string.power_menu_privacy_not_secure;
|
||||
} else if (cardsAvailable) {
|
||||
} else if (cardsAvailable && controlsAvailable) {
|
||||
res = R.string.power_menu_privacy_show;
|
||||
} else {
|
||||
} else if (!cardsAvailable && controlsAvailable) {
|
||||
res = R.string.power_menu_privacy_show_controls;
|
||||
} else if (cardsAvailable) {
|
||||
res = R.string.power_menu_privacy_show_cards;
|
||||
} else {
|
||||
// In this case, neither cards nor controls are available. This preference should not
|
||||
// be accessible as the power menu setting is not accessible
|
||||
return "";
|
||||
}
|
||||
return mContext.getText(res);
|
||||
}
|
||||
@@ -87,7 +95,7 @@ public class PowerMenuPrivacyPreferenceController extends TogglePreferenceContro
|
||||
boolean cardsAvailable = Settings.Secure.getInt(resolver, CARDS_AVAILABLE_KEY, 0) != 0;
|
||||
boolean cardsEnabled = Settings.Secure.getInt(resolver, CARDS_ENABLED_KEY, 0) != 0;
|
||||
boolean controlsEnabled = Settings.Secure.getInt(resolver, CONTROLS_ENABLED_KEY, 1) != 0;
|
||||
return (cardsAvailable && cardsEnabled) || controlsEnabled;
|
||||
return (cardsAvailable && cardsEnabled) || (isControlsAvailable() && controlsEnabled);
|
||||
}
|
||||
|
||||
private boolean isSecure() {
|
||||
@@ -97,4 +105,8 @@ public class PowerMenuPrivacyPreferenceController extends TogglePreferenceContro
|
||||
int userId = UserHandle.myUserId();
|
||||
return utils.isSecure(userId);
|
||||
}
|
||||
|
||||
private boolean isControlsAvailable() {
|
||||
return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CONTROLS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +73,8 @@ public class BatteryFixSlice implements CustomSliceable {
|
||||
UNIMPORTANT_BATTERY_TIPS = new ArrayMap<>();
|
||||
UNIMPORTANT_BATTERY_TIPS.put(BatteryTip.TipType.SUMMARY,
|
||||
Arrays.asList(BatteryTip.StateType.NEW, BatteryTip.StateType.HANDLED));
|
||||
UNIMPORTANT_BATTERY_TIPS.put(BatteryTip.TipType.HIGH_DEVICE_USAGE,
|
||||
Arrays.asList(BatteryTip.StateType.NEW, BatteryTip.StateType.HANDLED));
|
||||
UNIMPORTANT_BATTERY_TIPS.put(BatteryTip.TipType.BATTERY_SAVER,
|
||||
Arrays.asList(BatteryTip.StateType.HANDLED));
|
||||
}
|
||||
|
||||
@@ -106,7 +106,9 @@ public class MediaOutputSlice implements CustomSliceable {
|
||||
final MediaDevice connectedDevice = worker.getCurrentConnectedMediaDevice();
|
||||
if (devices.size() == 1) {
|
||||
// Zero state
|
||||
addRow(connectedDevice, connectedDevice, listBuilder);
|
||||
for (MediaDevice device : devices) {
|
||||
addRow(device, device, listBuilder);
|
||||
}
|
||||
listBuilder.addRow(getPairNewRow());
|
||||
} else {
|
||||
final boolean isTouched = worker.getIsTouched();
|
||||
|
||||
@@ -168,6 +168,7 @@ public class EnabledNetworkModePreferenceController extends
|
||||
private Context mContext;
|
||||
private TelephonyManager mTelephonyManager;
|
||||
|
||||
private boolean mAllowed5gNetworkType;
|
||||
private boolean mIsGlobalCdma;
|
||||
private boolean mIs5gEntryDisplayed;
|
||||
private boolean mShow4gForLTE;
|
||||
@@ -205,6 +206,9 @@ public class EnabledNetworkModePreferenceController extends
|
||||
final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
|
||||
final boolean isNrEnabledFromCarrierConfig = carrierConfig != null
|
||||
&& carrierConfig.getBoolean(CarrierConfigManager.KEY_NR_ENABLED_BOOL);
|
||||
mAllowed5gNetworkType = checkSupportedRadioBitmask(
|
||||
mTelephonyManager.getAllowedNetworkTypes(),
|
||||
TelephonyManager.NETWORK_TYPE_BITMASK_NR);
|
||||
mSupported5gRadioAccessFamily = isNrEnabledFromCarrierConfig
|
||||
&& checkSupportedRadioBitmask(mTelephonyManager.getSupportedRadioAccessFamily(),
|
||||
TelephonyManager.NETWORK_TYPE_BITMASK_NR);
|
||||
@@ -568,7 +572,7 @@ public class EnabledNetworkModePreferenceController extends
|
||||
}
|
||||
|
||||
/**
|
||||
* Add 5G option. Only show the UI when device supported 5G.
|
||||
* Add 5G option. Only show the UI when device supported 5G and allowed 5G.
|
||||
*/
|
||||
private void add5gEntry(int value) {
|
||||
boolean isNRValue = value >= TelephonyManagerConstants.NETWORK_MODE_NR_ONLY;
|
||||
@@ -581,13 +585,15 @@ public class EnabledNetworkModePreferenceController extends
|
||||
mIs5gEntryDisplayed = false;
|
||||
Log.d(LOG_TAG, "Hide 5G option. "
|
||||
+ " supported5GRadioAccessFamily: " + mSupported5gRadioAccessFamily
|
||||
+ " allowed5GNetworkType: " + mAllowed5gNetworkType
|
||||
+ " isNRValue: " + isNRValue);
|
||||
}
|
||||
}
|
||||
|
||||
private void addGlobalEntry() {
|
||||
Log.d(LOG_TAG, "addGlobalEntry. "
|
||||
+ " supported5GRadioAccessFamily: " + mSupported5gRadioAccessFamily);
|
||||
+ " supported5GRadioAccessFamily: " + mSupported5gRadioAccessFamily
|
||||
+ " allowed5GNetworkType: " + mAllowed5gNetworkType);
|
||||
mEntries.add(mContext.getString(R.string.network_global));
|
||||
if (showNrList()) {
|
||||
mEntriesValue.add(
|
||||
@@ -599,7 +605,7 @@ public class EnabledNetworkModePreferenceController extends
|
||||
}
|
||||
|
||||
private boolean showNrList() {
|
||||
return mSupported5gRadioAccessFamily;
|
||||
return mSupported5gRadioAccessFamily && mAllowed5gNetworkType;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -32,6 +32,7 @@ import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceCategory;
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
import com.android.settings.R;
|
||||
@@ -54,6 +55,13 @@ public class AppBubbleListPreferenceController extends AppConversationListPrefer
|
||||
super(context, backend);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
// loading convos is async; hide header until we know we have conversations to show
|
||||
preference.setVisible(false);
|
||||
super.updateState(preference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume(NotificationBackend.AppRow appRow,
|
||||
@Nullable NotificationChannel channel, @Nullable NotificationChannelGroup group,
|
||||
@@ -134,6 +142,15 @@ public class AppBubbleListPreferenceController extends AppConversationListPrefer
|
||||
return pref;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void populateList() {
|
||||
super.populateList();
|
||||
if (mPreference == null) {
|
||||
return;
|
||||
}
|
||||
mPreference.setVisible(mPreference.getPreferenceCount() > 0);
|
||||
}
|
||||
|
||||
/** Simple preference with a 'x' button at the end. */
|
||||
@VisibleForTesting
|
||||
public static class ConversationPreference extends Preference implements View.OnClickListener {
|
||||
|
||||
@@ -116,7 +116,7 @@ public class AppConversationListPreferenceController extends NotificationPrefere
|
||||
return R.string.conversations_category_title;
|
||||
}
|
||||
|
||||
private void populateList() {
|
||||
protected void populateList() {
|
||||
if (mPreference == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ public class NotificationHistoryViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
void setTitle(CharSequence title) {
|
||||
mTitle.setText(title);
|
||||
mTitle.setVisibility(title != null ? View.VISIBLE : View.GONE);
|
||||
mTitle.setVisibility(title != null ? View.VISIBLE : View.INVISIBLE);
|
||||
}
|
||||
|
||||
void setPostedTime(long postedTime) {
|
||||
|
||||
@@ -97,15 +97,8 @@ public class AppRestrictionsFragment extends SettingsPreferenceFragment implemen
|
||||
/** Key for extra passed in from calling fragment to indicate if this is a newly created user */
|
||||
public static final String EXTRA_NEW_USER = "new_user";
|
||||
|
||||
/**
|
||||
* Key for extra passed in from calling fragment to indicate if
|
||||
* switch to user should be shown
|
||||
*/
|
||||
public static final String EXTRA_SHOW_SWITCH_USER = "enable_switch";
|
||||
|
||||
private boolean mFirstTime = true;
|
||||
private boolean mNewUser;
|
||||
protected boolean mShowSwitchUser;
|
||||
private boolean mAppListChanged;
|
||||
protected boolean mRestrictedProfile;
|
||||
|
||||
@@ -216,6 +209,12 @@ public class AppRestrictionsFragment extends SettingsPreferenceFragment implemen
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
init(icicle);
|
||||
}
|
||||
|
||||
protected void init(Bundle icicle) {
|
||||
if (icicle != null) {
|
||||
mUser = new UserHandle(icicle.getInt(EXTRA_USER_ID));
|
||||
@@ -226,7 +225,6 @@ public class AppRestrictionsFragment extends SettingsPreferenceFragment implemen
|
||||
mUser = new UserHandle(args.getInt(EXTRA_USER_ID));
|
||||
}
|
||||
mNewUser = args.getBoolean(EXTRA_NEW_USER, false);
|
||||
mShowSwitchUser = args.getBoolean(EXTRA_SHOW_SWITCH_USER, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,10 @@ package com.android.settings.users;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
@@ -77,7 +79,9 @@ public class EditUserInfoController {
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
mEditUserPhotoController.removeNewUserPhotoBitmapFile();
|
||||
if (mEditUserPhotoController != null) {
|
||||
mEditUserPhotoController.removeNewUserPhotoBitmapFile();
|
||||
}
|
||||
mEditUserInfoDialog = null;
|
||||
mSavedPhoto = null;
|
||||
}
|
||||
@@ -116,7 +120,7 @@ public class EditUserInfoController {
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
mWaitingForActivityResult = false;
|
||||
|
||||
if (mEditUserInfoDialog != null) {
|
||||
if (mEditUserPhotoController != null && mEditUserInfoDialog != null) {
|
||||
mEditUserPhotoController.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
}
|
||||
@@ -137,6 +141,14 @@ public class EditUserInfoController {
|
||||
userNameView.setText(currentUserName);
|
||||
|
||||
final ImageView userPhotoView = (ImageView) content.findViewById(R.id.user_photo);
|
||||
|
||||
boolean canChangePhoto = mUserManager != null &&
|
||||
canChangePhoto(activity, mUserManager.getUserInfo(user.getIdentifier()));
|
||||
if (!canChangePhoto) {
|
||||
// some users can't change their photos so we need to remove suggestive
|
||||
// background from the photoView
|
||||
userPhotoView.setBackground(null);
|
||||
}
|
||||
Drawable drawable = null;
|
||||
if (mSavedPhoto != null) {
|
||||
drawable = CircleFramedDrawable.getInstance(activity, mSavedPhoto);
|
||||
@@ -144,7 +156,10 @@ public class EditUserInfoController {
|
||||
drawable = currentUserIcon;
|
||||
}
|
||||
userPhotoView.setImageDrawable(drawable);
|
||||
mEditUserPhotoController = createEditUserPhotoController(fragment, userPhotoView, drawable);
|
||||
if (canChangePhoto) {
|
||||
mEditUserPhotoController =
|
||||
createEditUserPhotoController(fragment, userPhotoView, drawable);
|
||||
}
|
||||
mEditUserInfoDialog = new AlertDialog.Builder(activity)
|
||||
.setTitle(title)
|
||||
.setView(content)
|
||||
@@ -158,21 +173,22 @@ public class EditUserInfoController {
|
||||
if (!TextUtils.isEmpty(userName)) {
|
||||
if (currentUserName == null
|
||||
|| !userName.toString().equals(
|
||||
currentUserName.toString())) {
|
||||
currentUserName.toString())) {
|
||||
if (callback != null) {
|
||||
callback.onLabelChanged(mUser, userName.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
// Update the photo if changed.
|
||||
Drawable drawable = mEditUserPhotoController.getNewUserPhotoDrawable();
|
||||
if (drawable != null && !drawable.equals(currentUserIcon)) {
|
||||
if (callback != null) {
|
||||
if (mEditUserPhotoController != null) {
|
||||
Drawable drawable =
|
||||
mEditUserPhotoController.getNewUserPhotoDrawable();
|
||||
if (drawable != null && !drawable.equals(currentUserIcon)) {
|
||||
if (callback != null) {
|
||||
callback.onPhotoChanged(mUser, drawable);
|
||||
}
|
||||
}
|
||||
}
|
||||
fragment.getActivity().removeDialog(
|
||||
RestrictedProfileSettings.DIALOG_ID_EDIT_USER_INFO);
|
||||
}
|
||||
clear();
|
||||
if (completeCallback != null) {
|
||||
@@ -207,6 +223,13 @@ public class EditUserInfoController {
|
||||
return mEditUserInfoDialog;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
boolean canChangePhoto(Context context, UserInfo user) {
|
||||
return PhotoCapabilityUtils.canCropPhoto(context) &&
|
||||
(PhotoCapabilityUtils.canChoosePhoto(context)
|
||||
|| PhotoCapabilityUtils.canTakePhoto(context));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
EditUserPhotoController createEditUserPhotoController(Fragment fragment,
|
||||
ImageView userPhotoView, Drawable drawable) {
|
||||
|
||||
@@ -21,7 +21,6 @@ import android.content.ClipData;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Bitmap.Config;
|
||||
@@ -52,6 +51,7 @@ import androidx.core.content.FileProvider;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.RestrictedLockUtilsInternal;
|
||||
import com.android.settingslib.drawable.CircleFramedDrawable;
|
||||
@@ -141,14 +141,14 @@ public class EditUserPhotoController {
|
||||
}
|
||||
|
||||
private void showUpdatePhotoPopup() {
|
||||
final boolean canTakePhoto = canTakePhoto();
|
||||
final boolean canChoosePhoto = canChoosePhoto();
|
||||
final Context context = mImageView.getContext();
|
||||
final boolean canTakePhoto = PhotoCapabilityUtils.canTakePhoto(context);
|
||||
final boolean canChoosePhoto = PhotoCapabilityUtils.canChoosePhoto(context);
|
||||
|
||||
if (!canTakePhoto && !canChoosePhoto) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Context context = mImageView.getContext();
|
||||
final List<EditUserPhotoController.RestrictedMenuItem> items = new ArrayList<>();
|
||||
|
||||
if (canTakePhoto) {
|
||||
@@ -200,19 +200,6 @@ public class EditUserPhotoController {
|
||||
listPopupWindow.show();
|
||||
}
|
||||
|
||||
private boolean canTakePhoto() {
|
||||
return mImageView.getContext().getPackageManager().queryIntentActivities(
|
||||
new Intent(MediaStore.ACTION_IMAGE_CAPTURE),
|
||||
PackageManager.MATCH_DEFAULT_ONLY).size() > 0;
|
||||
}
|
||||
|
||||
private boolean canChoosePhoto() {
|
||||
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
intent.setType("image/*");
|
||||
return mImageView.getContext().getPackageManager().queryIntentActivities(
|
||||
intent, 0).size() > 0;
|
||||
}
|
||||
|
||||
private void takePhoto() {
|
||||
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
|
||||
appendOutputExtra(intent, mTakePictureUri);
|
||||
@@ -369,8 +356,7 @@ public class EditUserPhotoController {
|
||||
if (purge) {
|
||||
fullPath.delete();
|
||||
}
|
||||
return FileProvider.getUriForFile(context,
|
||||
RestrictedProfileSettings.FILE_PROVIDER_AUTHORITY, fullPath);
|
||||
return FileProvider.getUriForFile(context, Utils.FILE_PROVIDER_AUTHORITY, fullPath);
|
||||
}
|
||||
|
||||
File saveNewUserPhotoBitmap() {
|
||||
|
||||
56
src/com/android/settings/users/PhotoCapabilityUtils.java
Normal file
56
src/com/android/settings/users/PhotoCapabilityUtils.java
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.users;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.provider.MediaStore;
|
||||
|
||||
class PhotoCapabilityUtils {
|
||||
|
||||
/**
|
||||
* Check if the current user can perform any activity for
|
||||
* android.media.action.IMAGE_CAPTURE action.
|
||||
*/
|
||||
static boolean canTakePhoto(Context context) {
|
||||
return context.getPackageManager().queryIntentActivities(
|
||||
new Intent(MediaStore.ACTION_IMAGE_CAPTURE),
|
||||
PackageManager.MATCH_DEFAULT_ONLY).size() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current user can perform any activity for
|
||||
* android.intent.action.GET_CONTENT action for images.
|
||||
*/
|
||||
static boolean canChoosePhoto(Context context) {
|
||||
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
intent.setType("image/*");
|
||||
return context.getPackageManager().queryIntentActivities(intent, 0).size() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current user can perform any activity for
|
||||
* com.android.camera.action.CROP action for images.
|
||||
*/
|
||||
static boolean canCropPhoto(Context context) {
|
||||
Intent intent = new Intent("com.android.camera.action.CROP");
|
||||
intent.setType("image/*");
|
||||
return context.getPackageManager().queryIntentActivities(intent, 0).size() > 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,208 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 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.users;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.app.Dialog;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.util.UserIcons;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
|
||||
public class RestrictedProfileSettings extends AppRestrictionsFragment
|
||||
implements EditUserInfoController.OnContentChangedCallback {
|
||||
|
||||
private static final String TAG = RestrictedProfileSettings.class.getSimpleName();
|
||||
public static final String FILE_PROVIDER_AUTHORITY = "com.android.settings.files";
|
||||
static final int DIALOG_ID_EDIT_USER_INFO = 1;
|
||||
private static final int DIALOG_CONFIRM_REMOVE = 2;
|
||||
|
||||
private View mHeaderView;
|
||||
private ImageView mUserIconView;
|
||||
private TextView mUserNameView;
|
||||
private ImageView mDeleteButton;
|
||||
private View mSwitchUserView;
|
||||
private TextView mSwitchTitle;
|
||||
|
||||
private EditUserInfoController mEditUserInfoController =
|
||||
new EditUserInfoController();
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
|
||||
if (icicle != null) {
|
||||
mEditUserInfoController.onRestoreInstanceState(icicle);
|
||||
}
|
||||
|
||||
init(icicle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
mHeaderView = setPinnedHeaderView(R.layout.user_info_header);
|
||||
mHeaderView.setOnClickListener(this);
|
||||
mUserIconView = (ImageView) mHeaderView.findViewById(android.R.id.icon);
|
||||
mUserNameView = (TextView) mHeaderView.findViewById(android.R.id.title);
|
||||
mDeleteButton = (ImageView) mHeaderView.findViewById(R.id.delete);
|
||||
mDeleteButton.setOnClickListener(this);
|
||||
|
||||
mSwitchTitle = mHeaderView.findViewById(R.id.switchTitle);
|
||||
mSwitchUserView = mHeaderView.findViewById(R.id.switch_pref);
|
||||
mSwitchUserView.setOnClickListener(v -> switchUser());
|
||||
|
||||
// This is going to bind the preferences.
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mEditUserInfoController.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
// Check if user still exists
|
||||
UserInfo info = Utils.getExistingUser(mUserManager, mUser);
|
||||
if (info == null) {
|
||||
finishFragment();
|
||||
} else {
|
||||
((TextView) mHeaderView.findViewById(android.R.id.title)).setText(info.name);
|
||||
((ImageView) mHeaderView.findViewById(android.R.id.icon)).setImageDrawable(
|
||||
com.android.settingslib.Utils.getUserIcon(getActivity(), mUserManager, info));
|
||||
|
||||
boolean canSwitchUser =
|
||||
mUserManager.getUserSwitchability() == UserManager.SWITCHABILITY_STATUS_OK;
|
||||
if (mShowSwitchUser && canSwitchUser) {
|
||||
mSwitchUserView.setVisibility(View.VISIBLE);
|
||||
mSwitchTitle.setText(getString(com.android.settingslib.R.string.user_switch_to_user,
|
||||
info.name));
|
||||
} else {
|
||||
mSwitchUserView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startActivityForResult(Intent intent, int requestCode) {
|
||||
mEditUserInfoController.startingActivityForResult();
|
||||
super.startActivityForResult(intent, requestCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
||||
mEditUserInfoController.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (view == mHeaderView) {
|
||||
showDialog(DIALOG_ID_EDIT_USER_INFO);
|
||||
} else if (view == mDeleteButton) {
|
||||
showDialog(DIALOG_CONFIRM_REMOVE);
|
||||
} else {
|
||||
super.onClick(view); // in AppRestrictionsFragment
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(int dialogId) {
|
||||
if (dialogId == DIALOG_ID_EDIT_USER_INFO) {
|
||||
return mEditUserInfoController.createDialog(this, mUserIconView.getDrawable(),
|
||||
mUserNameView.getText(), getString(R.string.profile_info_settings_title),
|
||||
this, mUser, null);
|
||||
} else if (dialogId == DIALOG_CONFIRM_REMOVE) {
|
||||
Dialog dlg =
|
||||
UserDialogs.createRemoveDialog(getActivity(), mUser.getIdentifier(),
|
||||
new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
removeUser();
|
||||
}
|
||||
}
|
||||
);
|
||||
return dlg;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDialogMetricsCategory(int dialogId) {
|
||||
switch (dialogId) {
|
||||
case DIALOG_ID_EDIT_USER_INFO:
|
||||
return SettingsEnums.DIALOG_USER_EDIT;
|
||||
case DIALOG_CONFIRM_REMOVE:
|
||||
return SettingsEnums.DIALOG_USER_REMOVE;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void removeUser() {
|
||||
getView().post(new Runnable() {
|
||||
public void run() {
|
||||
mUserManager.removeUser(mUser.getIdentifier());
|
||||
finishFragment();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void switchUser() {
|
||||
try {
|
||||
ActivityManager.getService().switchUser(mUser.getIdentifier());
|
||||
} catch (RemoteException re) {
|
||||
Log.e(TAG, "Error while switching to other user.");
|
||||
} finally {
|
||||
finishFragment();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPhotoChanged(UserHandle user, Drawable photo) {
|
||||
mUserIconView.setImageDrawable(photo);
|
||||
ThreadUtils.postOnBackgroundThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mUserManager.setUserIcon(user.getIdentifier(), UserIcons.convertToBitmap(photo));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLabelChanged(UserHandle user, CharSequence label) {
|
||||
mUserNameView.setText(label);
|
||||
mUserManager.setUserName(user.getIdentifier(), label.toString());
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,7 @@ import androidx.preference.SwitchPreference;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.RestrictedLockUtilsInternal;
|
||||
|
||||
@@ -56,6 +57,7 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
|
||||
private static final String KEY_SWITCH_USER = "switch_user";
|
||||
private static final String KEY_ENABLE_TELEPHONY = "enable_calling";
|
||||
private static final String KEY_REMOVE_USER = "remove_user";
|
||||
private static final String KEY_APP_AND_CONTENT_ACCESS = "app_and_content_access";
|
||||
|
||||
/** Integer extra containing the userId to manage */
|
||||
static final String EXTRA_USER_ID = "user_id";
|
||||
@@ -69,6 +71,8 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
|
||||
Preference mSwitchUserPref;
|
||||
private SwitchPreference mPhonePref;
|
||||
@VisibleForTesting
|
||||
Preference mAppAndContentAccessPref;
|
||||
@VisibleForTesting
|
||||
Preference mRemoveUserPref;
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -109,6 +113,8 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
|
||||
switchUser();
|
||||
}
|
||||
return true;
|
||||
} else if (preference == mAppAndContentAccessPref) {
|
||||
openAppAndContentAccessScreen(false);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -170,11 +176,14 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
|
||||
if (userId == USER_NULL) {
|
||||
throw new IllegalStateException("Arguments to this fragment must contain the user id");
|
||||
}
|
||||
boolean isNewUser =
|
||||
arguments.getBoolean(AppRestrictionsFragment.EXTRA_NEW_USER, false);
|
||||
mUserInfo = mUserManager.getUserInfo(userId);
|
||||
|
||||
mSwitchUserPref = findPreference(KEY_SWITCH_USER);
|
||||
mPhonePref = findPreference(KEY_ENABLE_TELEPHONY);
|
||||
mRemoveUserPref = findPreference(KEY_REMOVE_USER);
|
||||
mAppAndContentAccessPref = findPreference(KEY_APP_AND_CONTENT_ACCESS);
|
||||
|
||||
mSwitchUserPref.setTitle(
|
||||
context.getString(com.android.settingslib.R.string.user_switch_to_user,
|
||||
@@ -184,16 +193,24 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
|
||||
if (!mUserManager.isAdminUser()) { // non admin users can't remove users and allow calls
|
||||
removePreference(KEY_ENABLE_TELEPHONY);
|
||||
removePreference(KEY_REMOVE_USER);
|
||||
removePreference(KEY_APP_AND_CONTENT_ACCESS);
|
||||
} else {
|
||||
if (!Utils.isVoiceCapable(context)) { // no telephony
|
||||
removePreference(KEY_ENABLE_TELEPHONY);
|
||||
}
|
||||
|
||||
if (!mUserInfo.isGuest()) {
|
||||
mPhonePref.setChecked(!mUserManager.hasUserRestriction(
|
||||
UserManager.DISALLOW_OUTGOING_CALLS, new UserHandle(userId)));
|
||||
mRemoveUserPref.setTitle(R.string.user_remove_user);
|
||||
if (mUserInfo.isRestricted()) {
|
||||
removePreference(KEY_ENABLE_TELEPHONY);
|
||||
if (isNewUser) {
|
||||
// for newly created restricted users we should open the apps and content access
|
||||
// screen to initialize the default restrictions
|
||||
openAppAndContentAccessScreen(true);
|
||||
}
|
||||
} else {
|
||||
removePreference(KEY_APP_AND_CONTENT_ACCESS);
|
||||
}
|
||||
|
||||
if (mUserInfo.isGuest()) {
|
||||
// These are not for an existing user, just general Guest settings.
|
||||
// Default title is for calling and SMS. Change to calling-only here
|
||||
mPhonePref.setTitle(R.string.user_enable_calling);
|
||||
@@ -201,6 +218,10 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
|
||||
mPhonePref.setChecked(
|
||||
!mDefaultGuestRestrictions.getBoolean(UserManager.DISALLOW_OUTGOING_CALLS));
|
||||
mRemoveUserPref.setTitle(R.string.user_exit_guest_title);
|
||||
} else {
|
||||
mPhonePref.setChecked(!mUserManager.hasUserRestriction(
|
||||
UserManager.DISALLOW_OUTGOING_CALLS, new UserHandle(userId)));
|
||||
mRemoveUserPref.setTitle(R.string.user_remove_user);
|
||||
}
|
||||
if (RestrictedLockUtilsInternal.hasBaseUserRestriction(context,
|
||||
UserManager.DISALLOW_REMOVE_USER, UserHandle.myUserId())) {
|
||||
@@ -209,6 +230,7 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
|
||||
|
||||
mRemoveUserPref.setOnPreferenceClickListener(this);
|
||||
mPhonePref.setOnPreferenceChangeListener(this);
|
||||
mAppAndContentAccessPref.setOnPreferenceClickListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,4 +305,20 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
|
||||
mUserManager.removeUser(mUserInfo.id);
|
||||
finishFragment();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isNewUser indicates if a user was created recently, for new users
|
||||
* AppRestrictionsFragment should set the default restrictions
|
||||
*/
|
||||
private void openAppAndContentAccessScreen(boolean isNewUser) {
|
||||
Bundle extras = new Bundle();
|
||||
extras.putInt(AppRestrictionsFragment.EXTRA_USER_ID, mUserInfo.id);
|
||||
extras.putBoolean(AppRestrictionsFragment.EXTRA_NEW_USER, isNewUser);
|
||||
new SubSettingLauncher(getContext())
|
||||
.setDestination(AppRestrictionsFragment.class.getName())
|
||||
.setArguments(extras)
|
||||
.setTitleRes(R.string.user_restrictions_title)
|
||||
.setSourceMetricsCategory(getMetricsCategory())
|
||||
.launch();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -485,23 +485,13 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
private void onManageUserClicked(int userId, boolean newUser) {
|
||||
mAddingUser = false;
|
||||
UserInfo userInfo = mUserManager.getUserInfo(userId);
|
||||
if (userInfo.isRestricted() && mUserCaps.mIsAdmin) {
|
||||
Bundle extras = new Bundle();
|
||||
extras.putInt(RestrictedProfileSettings.EXTRA_USER_ID, userId);
|
||||
extras.putBoolean(RestrictedProfileSettings.EXTRA_NEW_USER, newUser);
|
||||
extras.putBoolean(RestrictedProfileSettings.EXTRA_SHOW_SWITCH_USER, canSwitchUserNow());
|
||||
new SubSettingLauncher(getContext())
|
||||
.setDestination(RestrictedProfileSettings.class.getName())
|
||||
.setArguments(extras)
|
||||
.setTitleRes(R.string.user_restrictions_title)
|
||||
.setSourceMetricsCategory(getMetricsCategory())
|
||||
.launch();
|
||||
} else if (userId == UserHandle.myUserId()) {
|
||||
if (userId == UserHandle.myUserId()) {
|
||||
// Jump to owner info panel
|
||||
OwnerInfoSettings.show(this);
|
||||
} else {
|
||||
Bundle extras = new Bundle();
|
||||
extras.putInt(UserDetailsSettings.EXTRA_USER_ID, userId);
|
||||
extras.putBoolean(AppRestrictionsFragment.EXTRA_NEW_USER, newUser);
|
||||
new SubSettingLauncher(getContext())
|
||||
.setDestination(UserDetailsSettings.class.getName())
|
||||
.setArguments(extras)
|
||||
@@ -963,10 +953,10 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
pref.setSummary(R.string.user_summary_restricted_not_set_up);
|
||||
} else {
|
||||
pref.setSummary(R.string.user_summary_not_set_up);
|
||||
// Disallow setting up user which results in user switching when the
|
||||
// restriction is set.
|
||||
pref.setEnabled(!mUserCaps.mDisallowSwitchUser && canSwitchUserNow());
|
||||
}
|
||||
// Disallow setting up user which results in user switching when the restriction is
|
||||
// set.
|
||||
pref.setEnabled(!mUserCaps.mDisallowSwitchUser && canSwitchUserNow());
|
||||
} else if (user.isRestricted()) {
|
||||
pref.setSummary(R.string.user_summary_restricted_profile);
|
||||
}
|
||||
@@ -1137,17 +1127,14 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
showDialog(DIALOG_CONFIRM_EXIT_GUEST);
|
||||
return true;
|
||||
}
|
||||
// If this is a limited user, launch the user info settings instead of profile editor
|
||||
if (mUserManager.isRestrictedProfile()) {
|
||||
onManageUserClicked(UserHandle.myUserId(), false);
|
||||
} else {
|
||||
showDialog(DIALOG_USER_PROFILE_EDITOR);
|
||||
}
|
||||
showDialog(DIALOG_USER_PROFILE_EDITOR);
|
||||
} else if (pref instanceof UserPreference) {
|
||||
int userId = ((UserPreference) pref).getUserId();
|
||||
// Get the latest status of the user
|
||||
UserInfo user = mUserManager.getUserInfo(userId);
|
||||
if (!user.isInitialized()) {
|
||||
if (!user.isInitialized() && isSecondaryUser(user)) {
|
||||
// for uninitialized secondary users we should show a prompt dialog before
|
||||
// starting the setup
|
||||
mHandler.sendMessage(mHandler.obtainMessage(
|
||||
MESSAGE_SETUP_USER, user.id, user.serialNumber));
|
||||
} else {
|
||||
@@ -1279,4 +1266,7 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
}
|
||||
};
|
||||
|
||||
private boolean isSecondaryUser(UserInfo user) {
|
||||
return UserManager.USER_TYPE_FULL_SECONDARY.equals(user.userType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.settings.gestures;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
@@ -28,12 +29,15 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.Shadows;
|
||||
import org.robolectric.shadows.ShadowPackageManager;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class DeviceControlsPreferenceControllerTest {
|
||||
|
||||
private Context mContext;
|
||||
private DeviceControlsPreferenceController mController;
|
||||
private ShadowPackageManager mShadowPackageManager;
|
||||
|
||||
private static final String KEY_GESTURE_PANEL = "gesture_device_controls";
|
||||
private static final String ENABLED_SETTING =
|
||||
@@ -42,6 +46,7 @@ public class DeviceControlsPreferenceControllerTest {
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mShadowPackageManager = Shadows.shadowOf(mContext.getPackageManager());
|
||||
mController = new DeviceControlsPreferenceController(mContext, KEY_GESTURE_PANEL);
|
||||
}
|
||||
|
||||
@@ -60,11 +65,21 @@ public class DeviceControlsPreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_panelAvailable() {
|
||||
public void getAvailabilityStatus_hasSystemFeature_panelAvailable() {
|
||||
mShadowPackageManager.setSystemFeature(PackageManager.FEATURE_CONTROLS, true);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus())
|
||||
.isEqualTo(BasePreferenceController.AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_hasntSystemFeature_panelUnsupported() {
|
||||
mShadowPackageManager.setSystemFeature(PackageManager.FEATURE_CONTROLS, false);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus())
|
||||
.isEqualTo(BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSliceable_correctKey() {
|
||||
final DeviceControlsPreferenceController controller =
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.gestures;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.annotation.StringRes;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.ParameterizedRobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.Shadows;
|
||||
import org.robolectric.shadows.ShadowPackageManager;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
@RunWith(ParameterizedRobolectricTestRunner.class)
|
||||
public class PowerMenuPreferenceControllerSummaryTest {
|
||||
|
||||
private static final String KEY_GESTURE_POWER_MENU = "gesture_power_menu";
|
||||
private static final String CONTROLS_ENABLED = Settings.Secure.CONTROLS_ENABLED;
|
||||
private static final String CONTROLS_FEATURE = PackageManager.FEATURE_CONTROLS;
|
||||
private static final String CARDS_ENABLED = Settings.Secure.GLOBAL_ACTIONS_PANEL_ENABLED;
|
||||
private static final String CARDS_AVAILABLE = Settings.Secure.GLOBAL_ACTIONS_PANEL_AVAILABLE;
|
||||
|
||||
@ParameterizedRobolectricTestRunner.Parameters(
|
||||
name = "ctrls available={0}, ctrls enabled={1}, cards available={2}, cards enabled={3}")
|
||||
public static Collection data() {
|
||||
return Arrays.asList(new Object[][]{
|
||||
// controls available, controls enabled, cards available, cards enabled, summary
|
||||
{false, false, false, false, R.string.power_menu_none},
|
||||
{false, false, false, true, R.string.power_menu_none},
|
||||
{false, false, true, false, R.string.power_menu_none},
|
||||
{false, false, true, true, R.string.power_menu_cards_passes},
|
||||
{false, true, false, false, R.string.power_menu_none},
|
||||
{false, true, false, true, R.string.power_menu_none},
|
||||
{false, true, true, false, R.string.power_menu_none},
|
||||
{false, true, true, true, R.string.power_menu_cards_passes},
|
||||
{true, false, false, false, R.string.power_menu_none},
|
||||
{true, false, false, true, R.string.power_menu_none},
|
||||
{true, false, true, false, R.string.power_menu_none},
|
||||
{true, false, true, true, R.string.power_menu_cards_passes},
|
||||
{true, true, false, false, R.string.power_menu_device_controls},
|
||||
{true, true, false, true, R.string.power_menu_device_controls},
|
||||
{true, true, true, false, R.string.power_menu_device_controls},
|
||||
{true, true, true, true, R.string.power_menu_cards_passes_device_controls}
|
||||
});
|
||||
}
|
||||
|
||||
private Context mContext;
|
||||
private PowerMenuPreferenceController mController;
|
||||
private ShadowPackageManager mShadowPackageManager;
|
||||
|
||||
private boolean mControlsAvailable;
|
||||
private boolean mControlsEnabled;
|
||||
private boolean mCardsAvailable;
|
||||
private boolean mCardsEnabled;
|
||||
private @StringRes int mSummaryRes;
|
||||
|
||||
public PowerMenuPreferenceControllerSummaryTest(
|
||||
boolean controlsAvailable,
|
||||
boolean controlsEnabled,
|
||||
boolean cardsAvailable,
|
||||
boolean cardsEnabled,
|
||||
@StringRes int summaryRes) {
|
||||
mControlsAvailable = controlsAvailable;
|
||||
mControlsEnabled = controlsEnabled;
|
||||
mCardsAvailable = cardsAvailable;
|
||||
mCardsEnabled = cardsEnabled;
|
||||
mSummaryRes = summaryRes;
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mShadowPackageManager = Shadows.shadowOf(mContext.getPackageManager());
|
||||
mController = new PowerMenuPreferenceController(mContext, KEY_GESTURE_POWER_MENU);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_possiblyAvailableAndEnabled() {
|
||||
mShadowPackageManager.setSystemFeature(CONTROLS_FEATURE, mControlsAvailable);
|
||||
ContentResolver cr = mContext.getContentResolver();
|
||||
Settings.Secure.putInt(cr, CONTROLS_ENABLED, mControlsEnabled ? 1 : 0);
|
||||
Settings.Secure.putInt(cr, CARDS_AVAILABLE, mCardsAvailable ? 1 : 0);
|
||||
Settings.Secure.putInt(cr, CARDS_ENABLED, mCardsEnabled ? 1 : 0);
|
||||
|
||||
assertThat(mController.getSummary()).isEqualTo(mContext.getText(mSummaryRes));
|
||||
}
|
||||
}
|
||||
@@ -19,118 +19,71 @@ package com.android.settings.gestures;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.Shadows;
|
||||
import org.robolectric.shadows.ShadowPackageManager;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class PowerMenuPreferenceControllerTest {
|
||||
private Context mContext;
|
||||
private PowerMenuPreferenceController mController;
|
||||
private ShadowPackageManager mShadowPackageManager;
|
||||
|
||||
private static final String KEY_GESTURE_POWER_MENU = "gesture_power_menu";
|
||||
private static final String CONTROLS_ENABLED = Settings.Secure.CONTROLS_ENABLED;
|
||||
private static final String CONTROLS_FEATURE = PackageManager.FEATURE_CONTROLS;
|
||||
private static final String CARDS_ENABLED = Settings.Secure.GLOBAL_ACTIONS_PANEL_ENABLED;
|
||||
private static final String CARDS_AVAILABLE = Settings.Secure.GLOBAL_ACTIONS_PANEL_AVAILABLE;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mShadowPackageManager = Shadows.shadowOf(mContext.getPackageManager());
|
||||
mController = new PowerMenuPreferenceController(mContext, KEY_GESTURE_POWER_MENU);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_available() {
|
||||
public void getAvailabilityStatus_bothAvailable_available() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), CARDS_AVAILABLE, 1);
|
||||
mShadowPackageManager.setSystemFeature(CONTROLS_FEATURE, true);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_allDisabled() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), CONTROLS_ENABLED, 0);
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), CARDS_ENABLED, 0);
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), CARDS_AVAILABLE, 0);
|
||||
|
||||
assertThat(mController.getSummary())
|
||||
.isEqualTo(mContext.getText(R.string.power_menu_none));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_onlyControlsEnabled() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), CONTROLS_ENABLED, 1);
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), CARDS_ENABLED, 0);
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), CARDS_AVAILABLE, 0);
|
||||
|
||||
assertThat(mController.getSummary())
|
||||
.isEqualTo(mContext.getText(R.string.power_menu_device_controls));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_onlyCardsEnabled_notAvailable() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), CONTROLS_ENABLED, 0);
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), CARDS_ENABLED, 1);
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), CARDS_AVAILABLE, 0);
|
||||
|
||||
assertThat(mController.getSummary())
|
||||
.isEqualTo(mContext.getText(R.string.power_menu_none));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_cardsAvailable_notEnabled() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), CONTROLS_ENABLED, 0);
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), CARDS_ENABLED, 0);
|
||||
public void getAvailabilityStatus_onlyCardsAvailable_available() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), CARDS_AVAILABLE, 1);
|
||||
mShadowPackageManager.setSystemFeature(CONTROLS_FEATURE, false);
|
||||
|
||||
assertThat(mController.getSummary())
|
||||
.isEqualTo(mContext.getText(R.string.power_menu_none));
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_allEnabled_cardsNotAvailable() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), CONTROLS_ENABLED, 1);
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), CARDS_ENABLED, 1);
|
||||
public void getAvailabilityStatus_onlyControlsAvailable_available() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), CARDS_AVAILABLE, 0);
|
||||
mShadowPackageManager.setSystemFeature(CONTROLS_FEATURE, true);
|
||||
|
||||
assertThat(mController.getSummary())
|
||||
.isEqualTo(mContext.getText(R.string.power_menu_device_controls));
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_controlsEnabled_cardsDisabledAvailable() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), CONTROLS_ENABLED, 1);
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), CARDS_ENABLED, 0);
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), CARDS_AVAILABLE, 1);
|
||||
public void getAvailabilityStatus_bothUnavailable_unavailable() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), CARDS_AVAILABLE, 0);
|
||||
mShadowPackageManager.setSystemFeature(CONTROLS_FEATURE, false);
|
||||
|
||||
assertThat(mController.getSummary())
|
||||
.isEqualTo(mContext.getText(R.string.power_menu_device_controls));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_controlsDisabled() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), CONTROLS_ENABLED, 0);
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), CARDS_ENABLED, 1);
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), CARDS_AVAILABLE, 1);
|
||||
|
||||
assertThat(mController.getSummary())
|
||||
.isEqualTo(mContext.getText(R.string.power_menu_cards_passes));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_allEnabled() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), CONTROLS_ENABLED, 1);
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), CARDS_ENABLED, 1);
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), CARDS_AVAILABLE, 1);
|
||||
|
||||
assertThat(mController.getSummary())
|
||||
.isEqualTo(mContext.getText(R.string.power_menu_cards_passes_device_controls));
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.gestures;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.ParameterizedRobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.Shadows;
|
||||
import org.robolectric.shadows.ShadowPackageManager;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
@RunWith(ParameterizedRobolectricTestRunner.class)
|
||||
public class PowerMenuPrivacyPreferenceControllerAvailabilityTest {
|
||||
|
||||
private static final String CONTROLS_ENABLED = Settings.Secure.CONTROLS_ENABLED;
|
||||
private static final String CONTROLS_FEATURE = PackageManager.FEATURE_CONTROLS;
|
||||
private static final String CARDS_ENABLED = Settings.Secure.GLOBAL_ACTIONS_PANEL_ENABLED;
|
||||
private static final String CARDS_AVAILABLE = Settings.Secure.GLOBAL_ACTIONS_PANEL_AVAILABLE;
|
||||
|
||||
@ParameterizedRobolectricTestRunner.Parameters(
|
||||
name = "ctrls available={0}, ctrls enabled={1}, cards available={2}, cards enabled={3}")
|
||||
public static Collection data() {
|
||||
return Arrays.asList(new Object[][]{
|
||||
// controls available, controls enabled, cards available, cards enabled, available
|
||||
{false, false, false, false, BasePreferenceController.DISABLED_DEPENDENT_SETTING},
|
||||
{false, false, false, true, BasePreferenceController.DISABLED_DEPENDENT_SETTING},
|
||||
{false, false, true, false, BasePreferenceController.DISABLED_DEPENDENT_SETTING},
|
||||
{false, false, true, true, BasePreferenceController.AVAILABLE},
|
||||
{false, true, false, false, BasePreferenceController.DISABLED_DEPENDENT_SETTING},
|
||||
{false, true, false, true, BasePreferenceController.DISABLED_DEPENDENT_SETTING},
|
||||
{false, true, true, false, BasePreferenceController.DISABLED_DEPENDENT_SETTING},
|
||||
{false, true, true, true, BasePreferenceController.AVAILABLE},
|
||||
{true, false, false, false, BasePreferenceController.DISABLED_DEPENDENT_SETTING},
|
||||
{true, false, false, true, BasePreferenceController.DISABLED_DEPENDENT_SETTING},
|
||||
{true, false, true, false, BasePreferenceController.DISABLED_DEPENDENT_SETTING},
|
||||
{true, false, true, true, BasePreferenceController.AVAILABLE},
|
||||
{true, true, false, false, BasePreferenceController.AVAILABLE},
|
||||
{true, true, false, true, BasePreferenceController.AVAILABLE},
|
||||
{true, true, true, false, BasePreferenceController.AVAILABLE},
|
||||
{true, true, true, true, BasePreferenceController.AVAILABLE}
|
||||
});
|
||||
}
|
||||
|
||||
private Context mContext;
|
||||
private PowerMenuPrivacyPreferenceController mController;
|
||||
private ShadowPackageManager mShadowPackageManager;
|
||||
|
||||
@Mock
|
||||
private LockPatternUtils mLockPatternUtils;
|
||||
|
||||
private boolean mControlsAvailable;
|
||||
private boolean mControlsEnabled;
|
||||
private boolean mCardsAvailable;
|
||||
private boolean mCardsEnabled;
|
||||
private int mAvailable;
|
||||
|
||||
public PowerMenuPrivacyPreferenceControllerAvailabilityTest(
|
||||
boolean controlsAvailable,
|
||||
boolean controlsEnabled,
|
||||
boolean cardsAvailable,
|
||||
boolean cardsEnabled,
|
||||
int available) {
|
||||
mControlsAvailable = controlsAvailable;
|
||||
mControlsEnabled = controlsEnabled;
|
||||
mCardsAvailable = cardsAvailable;
|
||||
mCardsEnabled = cardsEnabled;
|
||||
mAvailable = available;
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mShadowPackageManager = Shadows.shadowOf(mContext.getPackageManager());
|
||||
FakeFeatureFactory featureFactory = FakeFeatureFactory.setupForTest();
|
||||
|
||||
// For these tests we assume the device has a secure lock.
|
||||
when(featureFactory.securityFeatureProvider.getLockPatternUtils(mContext))
|
||||
.thenReturn(mLockPatternUtils);
|
||||
when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
|
||||
|
||||
mController = new PowerMenuPrivacyPreferenceController(mContext, "TEST_KEY");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_possiblyAvailableAndEnabled() {
|
||||
mShadowPackageManager.setSystemFeature(CONTROLS_FEATURE, mControlsAvailable);
|
||||
ContentResolver cr = mContext.getContentResolver();
|
||||
Settings.Secure.putInt(cr, CONTROLS_ENABLED, mControlsEnabled ? 1 : 0);
|
||||
Settings.Secure.putInt(cr, CARDS_AVAILABLE, mCardsAvailable ? 1 : 0);
|
||||
Settings.Secure.putInt(cr, CARDS_ENABLED, mCardsEnabled ? 1 : 0);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(mAvailable);
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,7 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
@@ -42,6 +43,8 @@ import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.Shadows;
|
||||
import org.robolectric.shadows.ShadowPackageManager;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class PowerMenuPrivacyPreferenceControllerTest {
|
||||
@@ -55,6 +58,7 @@ public class PowerMenuPrivacyPreferenceControllerTest {
|
||||
|
||||
private Context mContext;
|
||||
private ContentResolver mContentResolver;
|
||||
private ShadowPackageManager mShadowPackageManager;
|
||||
private PowerMenuPrivacyPreferenceController mController;
|
||||
|
||||
@Mock
|
||||
@@ -66,6 +70,8 @@ public class PowerMenuPrivacyPreferenceControllerTest {
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mShadowPackageManager = Shadows.shadowOf(mContext.getPackageManager());
|
||||
|
||||
mContentResolver = mContext.getContentResolver();
|
||||
FakeFeatureFactory featureFactory = FakeFeatureFactory.setupForTest();
|
||||
when(featureFactory.securityFeatureProvider.getLockPatternUtils(mContext))
|
||||
@@ -119,82 +125,50 @@ public class PowerMenuPrivacyPreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_cardsAvailable_isPower_menu_privacy_showString() {
|
||||
public void getSummary_cardsControlsAvailable_isPower_menu_privacy_showString() {
|
||||
Settings.Secure.putInt(mContentResolver, CARDS_AVAILABLE_KEY, 1);
|
||||
mShadowPackageManager.setSystemFeature(PackageManager.FEATURE_CONTROLS, true);
|
||||
|
||||
assertThat(mController.getSummary()).isEqualTo(
|
||||
mContext.getText(R.string.power_menu_privacy_show));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_cardsUnavailable_isPower_menu_privacy_show_controlsString() {
|
||||
public void
|
||||
getSummary_cardsUnavailableControlsAvailable_isPower_menu_privacy_show_controlsString() {
|
||||
Settings.Secure.putInt(mContentResolver, CARDS_AVAILABLE_KEY, 0);
|
||||
mShadowPackageManager.setSystemFeature(PackageManager.FEATURE_CONTROLS, true);
|
||||
|
||||
assertThat(mController.getSummary()).isEqualTo(
|
||||
mContext.getText(R.string.power_menu_privacy_show_controls));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void
|
||||
getSummary_cardsAvailableControlsUnavailable_isPower_menu_privacy_show_cardsString() {
|
||||
Settings.Secure.putInt(mContentResolver, CARDS_AVAILABLE_KEY, 1);
|
||||
mShadowPackageManager.setSystemFeature(PackageManager.FEATURE_CONTROLS, false);
|
||||
|
||||
assertThat(mController.getSummary()).isEqualTo(
|
||||
mContext.getText(R.string.power_menu_privacy_show_cards));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_onPreferenceRefreshed_preferenceEnabledAndSummaryChanged() {
|
||||
mShadowPackageManager.setSystemFeature(PackageManager.FEATURE_CONTROLS, true);
|
||||
Settings.Secure.putInt(mContentResolver, CARDS_AVAILABLE_KEY, 1);
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
verify(mPreference).setEnabled(anyBoolean());
|
||||
verify(mPreference, atLeastOnce()).setSummary(mController.getSummary());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_allOff_returnsDisabled() {
|
||||
Settings.Secure.putInt(mContentResolver, CARDS_AVAILABLE_KEY, 1);
|
||||
Settings.Secure.putInt(mContentResolver, CARDS_ENABLED_KEY, 0);
|
||||
Settings.Secure.putInt(mContentResolver, CONTROLS_ENABLED_KEY, 0);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.DISABLED_DEPENDENT_SETTING);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_cardsUnavailableControlsOff_returnsDisabled() {
|
||||
Settings.Secure.putInt(mContentResolver, CARDS_AVAILABLE_KEY, 0);
|
||||
Settings.Secure.putInt(mContentResolver, CONTROLS_ENABLED_KEY, 0);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.DISABLED_DEPENDENT_SETTING);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAvailabilityStatus_cardsOnControlsOff_returnsAvailable() {
|
||||
Settings.Secure.putInt(mContentResolver, CARDS_AVAILABLE_KEY, 1);
|
||||
Settings.Secure.putInt(mContentResolver, CARDS_ENABLED_KEY, 1);
|
||||
Settings.Secure.putInt(mContentResolver, CONTROLS_ENABLED_KEY, 0);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_cardsOffControlsOn_returnsAvailable() {
|
||||
Settings.Secure.putInt(mContentResolver, CARDS_AVAILABLE_KEY, 1);
|
||||
Settings.Secure.putInt(mContentResolver, CARDS_ENABLED_KEY, 0);
|
||||
Settings.Secure.putInt(mContentResolver, CONTROLS_ENABLED_KEY, 1);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_allOn_returnsAvailable() {
|
||||
Settings.Secure.putInt(mContentResolver, CARDS_AVAILABLE_KEY, 1);
|
||||
Settings.Secure.putInt(mContentResolver, CARDS_ENABLED_KEY, 1);
|
||||
Settings.Secure.putInt(mContentResolver, CONTROLS_ENABLED_KEY, 1);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_allOnNotSecure_returnsDisabled() {
|
||||
when(mLockPatternUtils.isSecure(anyInt())).thenReturn(false);
|
||||
|
||||
mShadowPackageManager.setSystemFeature(PackageManager.FEATURE_CONTROLS, true);
|
||||
Settings.Secure.putInt(mContentResolver, CARDS_AVAILABLE_KEY, 1);
|
||||
Settings.Secure.putInt(mContentResolver, CARDS_ENABLED_KEY, 1);
|
||||
Settings.Secure.putInt(mContentResolver, CONTROLS_ENABLED_KEY, 1);
|
||||
@@ -205,9 +179,8 @@ public class PowerMenuPrivacyPreferenceControllerTest {
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_controlsDeletedSecure_retursAvailable() {
|
||||
when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
|
||||
|
||||
Settings.Secure.putString(mContentResolver, CONTROLS_ENABLED_KEY, null);
|
||||
mShadowPackageManager.setSystemFeature(PackageManager.FEATURE_CONTROLS, true);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.AVAILABLE);
|
||||
|
||||
@@ -32,9 +32,11 @@ import androidx.slice.widget.SliceLiveData;
|
||||
import com.android.internal.os.BatteryStatsHelper;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.fuelgauge.BatteryStatsHelperLoader;
|
||||
import com.android.settings.fuelgauge.batterytip.AppInfo;
|
||||
import com.android.settings.fuelgauge.batterytip.BatteryTipLoader;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.EarlyWarningTip;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.HighUsageTip;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.LowBatteryTip;
|
||||
import com.android.settings.slices.SliceBackgroundWorker;
|
||||
|
||||
@@ -95,8 +97,14 @@ public class BatteryFixSliceTest {
|
||||
@Test
|
||||
public void getSlice_unimportantSlice_shouldSkip() {
|
||||
final List<BatteryTip> tips = new ArrayList<>();
|
||||
final List<AppInfo> appList = new ArrayList<>();
|
||||
appList.add(new AppInfo.Builder()
|
||||
.setPackageName("com.android.settings")
|
||||
.setScreenOnTimeMs(10000L)
|
||||
.build());
|
||||
tips.add(new LowBatteryTip(BatteryTip.StateType.INVISIBLE, false, ""));
|
||||
tips.add(new EarlyWarningTip(BatteryTip.StateType.HANDLED, false));
|
||||
tips.add(new HighUsageTip(1000L, appList));
|
||||
ShadowBatteryTipLoader.setBatteryTips(tips);
|
||||
|
||||
BatteryFixSlice.refreshBatteryTips(mContext);
|
||||
|
||||
@@ -60,6 +60,7 @@ public class EnabledNetworkModePreferenceControllerTest {
|
||||
private static final int SUB_ID = 2;
|
||||
public static final String KEY = "enabled_network";
|
||||
|
||||
private static final long ALLOWED_ALL_NETWORK_TYPE = -1;
|
||||
private static final long DISABLED_5G_NETWORK_TYPE = ~TelephonyManager.NETWORK_TYPE_BITMASK_NR;
|
||||
|
||||
@Mock
|
||||
@@ -97,6 +98,7 @@ public class EnabledNetworkModePreferenceControllerTest {
|
||||
doReturn(mPersistableBundle).when(mCarrierConfigManager).getConfigForSubId(SUB_ID);
|
||||
mPreference = new ListPreference(mContext);
|
||||
mController = new EnabledNetworkModePreferenceController(mContext, KEY);
|
||||
mockAllowedNetworkTypes(ALLOWED_ALL_NETWORK_TYPE);
|
||||
mockAccessFamily(TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA);
|
||||
mController.init(mLifecycle, SUB_ID);
|
||||
mPreference.setKey(mController.getPreferenceKey());
|
||||
@@ -182,6 +184,76 @@ public class EnabledNetworkModePreferenceControllerTest {
|
||||
TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_disAllowed5g_5gOptionHidden() {
|
||||
mockEnabledNetworkMode(TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA);
|
||||
mockAccessFamily(TelephonyManager.NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA);
|
||||
mockAllowedNetworkTypes(DISABLED_5G_NETWORK_TYPE);
|
||||
mController.init(mLifecycle, SUB_ID);
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.PREFERRED_NETWORK_MODE + SUB_ID,
|
||||
TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA);
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
assertThat(mPreference.getEntryValues())
|
||||
.asList()
|
||||
.doesNotContain(
|
||||
String.valueOf(TelephonyManager.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_disAllowed5g_selectOn4gOption() {
|
||||
mockEnabledNetworkMode(TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA);
|
||||
mockAccessFamily(TelephonyManager.NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA);
|
||||
mockAllowedNetworkTypes(DISABLED_5G_NETWORK_TYPE);
|
||||
mController.init(mLifecycle, SUB_ID);
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.PREFERRED_NETWORK_MODE + SUB_ID,
|
||||
TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA);
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
assertThat(mPreference.getValue()).isEqualTo(
|
||||
String.valueOf(
|
||||
TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_GlobalDisAllowed5g_GlobalWithoutNR() {
|
||||
mockAccessFamily(TelephonyManager.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA);
|
||||
mockAllowedNetworkTypes(DISABLED_5G_NETWORK_TYPE);
|
||||
mController.init(mLifecycle, SUB_ID);
|
||||
mPersistableBundle.putBoolean(CarrierConfigManager.KEY_WORLD_MODE_ENABLED_BOOL, true);
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.PREFERRED_NETWORK_MODE + SUB_ID,
|
||||
TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA);
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
assertThat(mPreference.getEntryValues())
|
||||
.asList()
|
||||
.doesNotContain(
|
||||
String.valueOf(TelephonyManager.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_GlobalDisAllowed5g_SelectOnGlobal() {
|
||||
mockAccessFamily(TelephonyManager.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA);
|
||||
mockAllowedNetworkTypes(DISABLED_5G_NETWORK_TYPE);
|
||||
mController.init(mLifecycle, SUB_ID);
|
||||
mPersistableBundle.putBoolean(CarrierConfigManager.KEY_WORLD_MODE_ENABLED_BOOL, true);
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.PREFERRED_NETWORK_MODE + SUB_ID,
|
||||
TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA);
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
assertThat(mPreference.getValue()).isEqualTo(
|
||||
String.valueOf(
|
||||
TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_updateByNetworkMode() {
|
||||
mockEnabledNetworkMode(TelephonyManagerConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA);
|
||||
@@ -279,6 +351,10 @@ public class EnabledNetworkModePreferenceControllerTest {
|
||||
}
|
||||
}
|
||||
|
||||
private void mockAllowedNetworkTypes(long allowedNetworkType) {
|
||||
doReturn(allowedNetworkType).when(mTelephonyManager).getAllowedNetworkTypes();
|
||||
}
|
||||
|
||||
private void mockAccessFamily(int networkMode) {
|
||||
doReturn(MobileNetworkUtils.getRafFromNetworkType(networkMode))
|
||||
.when(mTelephonyManager)
|
||||
|
||||
@@ -28,7 +28,9 @@ import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
@@ -62,6 +64,8 @@ public class EditUserInfoControllerTest {
|
||||
@Mock
|
||||
private Drawable mCurrentIcon;
|
||||
|
||||
private boolean mCanChangePhoto;
|
||||
|
||||
private FragmentActivity mActivity;
|
||||
private TestEditUserInfoController mController;
|
||||
|
||||
@@ -78,6 +82,11 @@ public class EditUserInfoControllerTest {
|
||||
mPhotoController = mock(EditUserPhotoController.class, Answers.RETURNS_DEEP_STUBS);
|
||||
return mPhotoController;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean canChangePhoto(Context context, UserInfo user) {
|
||||
return mCanChangePhoto;
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
@@ -86,6 +95,7 @@ public class EditUserInfoControllerTest {
|
||||
mActivity = spy(ActivityController.of(new FragmentActivity()).get());
|
||||
when(mFragment.getActivity()).thenReturn(mActivity);
|
||||
mController = new TestEditUserInfoController();
|
||||
mCanChangePhoto = true;
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -256,4 +266,17 @@ public class EditUserInfoControllerTest {
|
||||
verify(dialogCompleteCallback, times(1)).onPositive();
|
||||
verify(dialogCompleteCallback, times(0)).onNegativeOrCancel();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createDialog_canNotChangePhoto_nullPhotoController() {
|
||||
mCanChangePhoto = false;
|
||||
|
||||
mController.createDialog(
|
||||
mFragment, mCurrentIcon, "test",
|
||||
"title", null,
|
||||
android.os.Process.myUserHandle(),
|
||||
null);
|
||||
|
||||
assertThat(mController.mPhotoController).isNull();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,9 +32,11 @@ import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.robolectric.Shadows.shadowOf;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
@@ -47,6 +49,8 @@ import androidx.preference.PreferenceScreen;
|
||||
import androidx.preference.SwitchPreference;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.SubSettings;
|
||||
import com.android.settings.testutils.shadow.ShadowDevicePolicyManager;
|
||||
import com.android.settings.testutils.shadow.ShadowUserManager;
|
||||
|
||||
@@ -61,6 +65,7 @@ import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.android.controller.ActivityController;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadow.api.Shadow;
|
||||
import org.robolectric.shadows.ShadowIntent;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -76,6 +81,7 @@ public class UserDetailsSettingsTest {
|
||||
private static final String KEY_SWITCH_USER = "switch_user";
|
||||
private static final String KEY_ENABLE_TELEPHONY = "enable_calling";
|
||||
private static final String KEY_REMOVE_USER = "remove_user";
|
||||
private static final String KEY_APP_AND_CONTENT_ACCESS = "app_and_content_access";
|
||||
|
||||
private static final int DIALOG_CONFIRM_REMOVE = 1;
|
||||
|
||||
@@ -90,6 +96,8 @@ public class UserDetailsSettingsTest {
|
||||
private SwitchPreference mPhonePref;
|
||||
@Mock
|
||||
private Preference mRemoveUserPref;
|
||||
@Mock
|
||||
private Preference mAppAndContentAccessPref;
|
||||
|
||||
private FragmentActivity mActivity;
|
||||
private Context mContext;
|
||||
@@ -114,14 +122,15 @@ public class UserDetailsSettingsTest {
|
||||
|
||||
ReflectionHelpers.setField(mFragment, "mUserManager", userManager);
|
||||
doReturn(mActivity).when(mFragment).getActivity();
|
||||
doReturn(mContext).when(mFragment).getContext();
|
||||
doReturn(mActivity).when(mFragment).getContext();
|
||||
|
||||
doReturn(mock(PreferenceScreen.class)).when(mFragment).getPreferenceScreen();
|
||||
doReturn("").when(mActivity).getString(anyInt(), anyString());
|
||||
|
||||
doReturn(mSwitchUserPref).when(mFragment).findPreference(KEY_SWITCH_USER);
|
||||
doReturn(mPhonePref).when(mFragment).findPreference(KEY_ENABLE_TELEPHONY);
|
||||
doReturn(mRemoveUserPref).when(mFragment).findPreference(KEY_REMOVE_USER);
|
||||
doReturn(mAppAndContentAccessPref)
|
||||
.when(mFragment).findPreference(KEY_APP_AND_CONTENT_ACCESS);
|
||||
}
|
||||
|
||||
@After
|
||||
@@ -169,6 +178,24 @@ public class UserDetailsSettingsTest {
|
||||
verify(mFragment, never()).removePreference(KEY_SWITCH_USER);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_userSelected_shouldNotShowAppAndContentPref() {
|
||||
setupSelectedUser();
|
||||
|
||||
mFragment.initialize(mActivity, mArguments);
|
||||
|
||||
verify(mFragment).removePreference(KEY_APP_AND_CONTENT_ACCESS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_guestSelected_shouldNotShowAppAndContentPref() {
|
||||
setupSelectedGuest();
|
||||
|
||||
mFragment.initialize(mActivity, mArguments);
|
||||
|
||||
verify(mFragment).removePreference(KEY_APP_AND_CONTENT_ACCESS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onResume_canSwitch_shouldEnableSwitchPref() {
|
||||
mUserManager.setSwitchabilityStatus(SWITCHABILITY_STATUS_OK);
|
||||
@@ -248,6 +275,16 @@ public class UserDetailsSettingsTest {
|
||||
verify(mFragment).removePreference(KEY_ENABLE_TELEPHONY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_nonAdmin_shouldNotShowAppAndContentPref() {
|
||||
setupSelectedUser();
|
||||
mUserManager.setIsAdminUser(false);
|
||||
|
||||
mFragment.initialize(mActivity, mArguments);
|
||||
|
||||
verify(mFragment).removePreference(KEY_APP_AND_CONTENT_ACCESS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_adminSelectsSecondaryUser_shouldShowRemovePreference() {
|
||||
setupSelectedUser();
|
||||
@@ -260,6 +297,57 @@ public class UserDetailsSettingsTest {
|
||||
verify(mFragment, never()).removePreference(KEY_REMOVE_USER);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_adminSelectsNewRestrictedUser_shouldOpenAppContentScreen() {
|
||||
setupSelectedRestrictedUser();
|
||||
mUserManager.setIsAdminUser(true);
|
||||
mArguments.putBoolean(AppRestrictionsFragment.EXTRA_NEW_USER, true);
|
||||
|
||||
mFragment.initialize(mActivity, mArguments);
|
||||
|
||||
Intent startedIntent = shadowOf(mActivity).getNextStartedActivity();
|
||||
ShadowIntent shadowIntent = shadowOf(startedIntent);
|
||||
assertThat(shadowIntent.getIntentClass()).isEqualTo(SubSettings.class);
|
||||
assertThat(startedIntent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
|
||||
.isEqualTo(AppRestrictionsFragment.class.getName());
|
||||
Bundle arguments = startedIntent.getBundleExtra(
|
||||
SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS);
|
||||
assertThat(arguments).isNotNull();
|
||||
assertThat(arguments.getInt(AppRestrictionsFragment.EXTRA_USER_ID, 0))
|
||||
.isEqualTo(mUserInfo.id);
|
||||
assertThat(arguments.getBoolean(AppRestrictionsFragment.EXTRA_NEW_USER, false))
|
||||
.isEqualTo(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_adminSelectsRestrictedUser_shouldSetupPreferences() {
|
||||
setupSelectedRestrictedUser();
|
||||
mUserManager.setIsAdminUser(true);
|
||||
doReturn(true).when(mTelephonyManager).isVoiceCapable();
|
||||
|
||||
mFragment.initialize(mActivity, mArguments);
|
||||
|
||||
verify(mFragment, never()).removePreference(KEY_REMOVE_USER);
|
||||
verify(mFragment, never()).removePreference(KEY_SWITCH_USER);
|
||||
verify(mFragment, never()).removePreference(KEY_APP_AND_CONTENT_ACCESS);
|
||||
verify(mFragment).removePreference(KEY_ENABLE_TELEPHONY);
|
||||
verify(mSwitchUserPref).setTitle("Switch to " + mUserInfo.name);
|
||||
verify(mAppAndContentAccessPref).setOnPreferenceClickListener(mFragment);
|
||||
verify(mSwitchUserPref).setOnPreferenceClickListener(mFragment);
|
||||
verify(mRemoveUserPref).setOnPreferenceClickListener(mFragment);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_adminSelectsExistingRestrictedUser_shouldNotStartAppAndContentAccess() {
|
||||
setupSelectedRestrictedUser();
|
||||
mUserManager.setIsAdminUser(true);
|
||||
mArguments.putBoolean(AppRestrictionsFragment.EXTRA_NEW_USER, false);
|
||||
|
||||
mFragment.initialize(mActivity, mArguments);
|
||||
|
||||
verify(mActivity, never()).startActivity(any(Intent.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize_adminSelectsGuest_shouldShowRemovePreference() {
|
||||
setupSelectedGuest();
|
||||
@@ -344,6 +432,7 @@ public class UserDetailsSettingsTest {
|
||||
mUserManager.setSwitchabilityStatus(SWITCHABILITY_STATUS_OK);
|
||||
mFragment.mSwitchUserPref = mSwitchUserPref;
|
||||
mFragment.mRemoveUserPref = mRemoveUserPref;
|
||||
mFragment.mAppAndContentAccessPref = mAppAndContentAccessPref;
|
||||
mFragment.mUserInfo = mUserInfo;
|
||||
|
||||
mFragment.onPreferenceClick(mSwitchUserPref);
|
||||
@@ -357,6 +446,7 @@ public class UserDetailsSettingsTest {
|
||||
mUserManager.setSwitchabilityStatus(SWITCHABILITY_STATUS_USER_SWITCH_DISALLOWED);
|
||||
mFragment.mSwitchUserPref = mSwitchUserPref;
|
||||
mFragment.mRemoveUserPref = mRemoveUserPref;
|
||||
mFragment.mAppAndContentAccessPref = mAppAndContentAccessPref;
|
||||
mFragment.mUserInfo = mUserInfo;
|
||||
|
||||
mFragment.onPreferenceClick(mSwitchUserPref);
|
||||
@@ -371,6 +461,7 @@ public class UserDetailsSettingsTest {
|
||||
mUserManager.setIsAdminUser(true);
|
||||
mFragment.mSwitchUserPref = mSwitchUserPref;
|
||||
mFragment.mRemoveUserPref = mRemoveUserPref;
|
||||
mFragment.mAppAndContentAccessPref = mAppAndContentAccessPref;
|
||||
doNothing().when(mFragment).showDialog(anyInt());
|
||||
|
||||
mFragment.onPreferenceClick(mRemoveUserPref);
|
||||
@@ -386,6 +477,7 @@ public class UserDetailsSettingsTest {
|
||||
mUserManager.setIsAdminUser(false);
|
||||
mFragment.mSwitchUserPref = mSwitchUserPref;
|
||||
mFragment.mRemoveUserPref = mRemoveUserPref;
|
||||
mFragment.mAppAndContentAccessPref = mAppAndContentAccessPref;
|
||||
doNothing().when(mFragment).showDialog(anyInt());
|
||||
|
||||
mFragment.onPreferenceClick(mRemoveUserPref);
|
||||
@@ -394,12 +486,37 @@ public class UserDetailsSettingsTest {
|
||||
verify(mFragment, never()).showDialog(DIALOG_CONFIRM_REMOVE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceClick_selectRestrictedUser_appAndContentAccessClicked_startActivity() {
|
||||
setupSelectedRestrictedUser();
|
||||
mFragment.mUserInfo = mUserInfo;
|
||||
mUserManager.setIsAdminUser(true);
|
||||
mFragment.mSwitchUserPref = mSwitchUserPref;
|
||||
mFragment.mRemoveUserPref = mRemoveUserPref;
|
||||
mFragment.mAppAndContentAccessPref = mAppAndContentAccessPref;
|
||||
|
||||
mFragment.onPreferenceClick(mAppAndContentAccessPref);
|
||||
|
||||
Intent startedIntent = shadowOf(mActivity).getNextStartedActivity();
|
||||
ShadowIntent shadowIntent = shadowOf(startedIntent);
|
||||
assertThat(shadowIntent.getIntentClass()).isEqualTo(SubSettings.class);
|
||||
assertThat(startedIntent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
|
||||
.isEqualTo(AppRestrictionsFragment.class.getName());
|
||||
Bundle arguments = startedIntent.getBundleExtra(
|
||||
SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS);
|
||||
assertThat(arguments.getInt(AppRestrictionsFragment.EXTRA_USER_ID, 0))
|
||||
.isEqualTo(mUserInfo.id);
|
||||
assertThat(arguments.getBoolean(AppRestrictionsFragment.EXTRA_NEW_USER, true))
|
||||
.isEqualTo(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceClick_unknownPreferenceClicked_doNothing() {
|
||||
setupSelectedUser();
|
||||
mFragment.mUserInfo = mUserInfo;
|
||||
mFragment.mSwitchUserPref = mSwitchUserPref;
|
||||
mFragment.mRemoveUserPref = mRemoveUserPref;
|
||||
mFragment.mAppAndContentAccessPref = mAppAndContentAccessPref;
|
||||
|
||||
mFragment.onPreferenceClick(mock(UserPreference.class));
|
||||
|
||||
@@ -464,4 +581,13 @@ public class UserDetailsSettingsTest {
|
||||
|
||||
mUserManager.addProfile(mUserInfo);
|
||||
}
|
||||
|
||||
private void setupSelectedRestrictedUser() {
|
||||
mArguments.putInt("user_id", 21);
|
||||
mUserInfo = new UserInfo(21, "Bob", null,
|
||||
UserInfo.FLAG_FULL | UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_RESTRICTED,
|
||||
UserManager.USER_TYPE_FULL_RESTRICTED);
|
||||
|
||||
mUserManager.addProfile(mUserInfo);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user