Snap for 4834991 from f817b1e3a5 to qt-release
Change-Id: Ic7cb42ade00c98f09155918d610ecc15c298bdf9
This commit is contained in:
@@ -2365,26 +2365,6 @@
|
||||
android:enabled="false"
|
||||
android:taskAffinity="com.android.settings"
|
||||
android:parentActivityName="Settings">
|
||||
<!-- TODO(b/70950124): add shortcut intent-filter -->
|
||||
<intent-filter android:priority="1">
|
||||
<action android:name="android.settings.DATA_USAGE_SETTINGS" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
<intent-filter android:priority="10">
|
||||
<action android:name="com.android.settings.action.SETTINGS" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="com.android.settings.category"
|
||||
android:value="com.android.settings.category.ia.wireless" />
|
||||
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
|
||||
android:value="com.android.settings.datausage.DataUsageSummary" />
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="Settings$DataUsageSummaryLegacyActivity"
|
||||
android:label="@string/data_usage_summary_title"
|
||||
android:icon="@drawable/ic_settings_data_usage"
|
||||
android:taskAffinity="com.android.settings"
|
||||
android:parentActivityName="Settings">
|
||||
<intent-filter android:priority="1">
|
||||
<action android:name="android.settings.DATA_USAGE_SETTINGS" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
@@ -2398,11 +2378,10 @@
|
||||
<action android:name="com.android.settings.action.SETTINGS" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="com.android.settings.category"
|
||||
android:value="com.android.settings.category.ia.wireless" />
|
||||
android:value="com.android.settings.category.ia.wireless" />
|
||||
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
|
||||
android:value="com.android.settings.datausage.DataUsageSummaryLegacy" />
|
||||
android:value="com.android.settings.datausage.DataUsageSummary" />
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="Settings$MobileDataUsageListActivity"
|
||||
android:label="@string/cellular_data_usage"
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:textColor="?android:attr/textColorSecondary"/>
|
||||
|
||||
<com.android.settings.graph.UsageView
|
||||
<com.android.settings.widget.UsageView
|
||||
android:id="@+id/battery_usage"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="141dp"
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
android:textSize="36sp"
|
||||
android:textColor="?android:attr/colorAccent" />
|
||||
|
||||
<com.android.settings.graph.UsageView
|
||||
<com.android.settings.widget.UsageView
|
||||
android:id="@+id/battery_usage"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="141dp"
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.android.settings.graph.UsageView
|
||||
<com.android.settings.widget.UsageView
|
||||
android:id="@+id/data_usage"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/data_usage_chart_height"
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
|
||||
<!-- Based off frameworks/base/core/res/res/layout/preference_dropdown_material.xml
|
||||
except that icon space in this layout is always reserved -->
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spinner"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/preference_no_icon_padding_start"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<include layout="@layout/preference_material"/>
|
||||
|
||||
</FrameLayout>
|
||||
@@ -57,7 +57,7 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.android.settings.graph.UsageGraph
|
||||
<com.android.settings.widget.UsageGraph
|
||||
android:id="@+id/usage_graph"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
@@ -76,7 +76,7 @@
|
||||
android:id="@+id/bottom_label_space"
|
||||
android:layout_width="@dimen/usage_graph_labels_width"
|
||||
android:layout_height="wrap_content"/>
|
||||
<com.android.settings.graph.BottomLabelLayout
|
||||
<com.android.settings.widget.BottomLabelLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
@@ -93,7 +93,7 @@
|
||||
|
||||
<include android:id="@+id/label_end"
|
||||
layout="@layout/usage_side_label" />
|
||||
</com.android.settings.graph.BottomLabelLayout>
|
||||
</com.android.settings.widget.BottomLabelLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2011 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.
|
||||
-->
|
||||
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:id="@+id/data_usage_menu_cellular_networks"
|
||||
android:title="@string/data_usage_menu_cellular_networks" />
|
||||
</menu>
|
||||
@@ -6015,8 +6015,6 @@
|
||||
<string name="data_usage_menu_auto_sync">Auto-sync data</string>
|
||||
<!-- Title for menu option to show details for all SIM cards. [CHAR LIMIT=26] -->
|
||||
<string name="data_usage_menu_sim_cards">SIM cards</string>
|
||||
<!-- Title for menu option to show details for all cellular networks. [CHAR LIMIT=26] -->
|
||||
<string name="data_usage_menu_cellular_networks">Mobile networks</string>
|
||||
<!-- Summary String for Cellular data enable toggle. [CHAR LIMIT=33] -->
|
||||
<string name="data_usage_cellular_data_summary">Paused at limit</string>
|
||||
|
||||
@@ -9169,12 +9167,6 @@
|
||||
<!-- Format string for amount of ethernet data used [CHAR LIMIT=30] -->
|
||||
<string name="ethernet_data_template"><xliff:g id="amount" example="1 GB">^1</xliff:g> ethernet data</string>
|
||||
|
||||
<!-- Format for a summary describing the amount of data before the user is warned [CHAR LIMIT=NONE] -->
|
||||
<string name="cell_warning_only"><xliff:g name="amount" example="1 GB">%1$s</xliff:g> Data warning</string>
|
||||
|
||||
<!-- Format for a summary describing the amount of data before the user is warned or limited [CHAR LIMIT=NONE] -->
|
||||
<string name="cell_warning_and_limit"><xliff:g name="amount" example="1 GB">%1$s</xliff:g> Data warning / <xliff:g name="amount" example="2 GB">%2$s</xliff:g> Data limit</string>
|
||||
|
||||
<!-- Title of button and screen for billing cycle preferences [CHAR LIMIT=40] -->
|
||||
<string name="billing_cycle">Data warning & limit</string>
|
||||
|
||||
|
||||
@@ -20,27 +20,27 @@
|
||||
<resources>
|
||||
|
||||
<!-- Fragment style -->
|
||||
<style name="SettingsPreferenceFragmentStyle" parent="@style/PreferenceFragmentStyle.SettingsBase">
|
||||
<style name="SettingsPreferenceFragmentStyle" parent="@style/PreferenceFragment.Material">
|
||||
<item name="android:layout">@layout/preference_list_fragment</item>
|
||||
</style>
|
||||
|
||||
<style name="ApnPreference" parent="Preference.SettingsBase">
|
||||
<style name="ApnPreference" parent="@style/Preference.Material">
|
||||
<item name="android:layout">@layout/apn_preference_layout</item>
|
||||
</style>
|
||||
|
||||
<style name="SettingsSeekBarPreference" parent="Preference.SettingsBase">
|
||||
<style name="SettingsSeekBarPreference" parent="@style/Preference.Material">
|
||||
<item name="android:layout">@layout/preference_widget_seekbar_settings</item>
|
||||
</style>
|
||||
|
||||
<style name="SyncSwitchPreference" parent="Preference.SettingsBase">
|
||||
<style name="SyncSwitchPreference" parent="@style/Preference.Material">
|
||||
<item name="android:widgetLayout">@layout/preference_widget_sync_toggle</item>
|
||||
</style>
|
||||
|
||||
<style name="TwoStateButtonPreference" parent="Preference.SettingsBase">
|
||||
<style name="TwoStateButtonPreference" parent="@style/Preference.Material">
|
||||
<item name="android:layout">@layout/two_state_button</item>
|
||||
</style>
|
||||
|
||||
<style name="SettingsMultiSelectListPreference" parent="Preference.SettingsBase">
|
||||
<style name="SettingsMultiSelectListPreference" parent="@style/Preference.Material">
|
||||
<item name="android:positiveButtonText">@android:string/ok</item>
|
||||
<item name="android:negativeButtonText">@android:string/cancel</item>
|
||||
</style>
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:key="data_usage_screen"
|
||||
android:title="@string/data_usage_summary_title">
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="data_usage_category"
|
||||
android:title="@string/usage">
|
||||
|
||||
<com.android.settings.SummaryPreference
|
||||
android:key="status_header"
|
||||
android:selectable="false" />
|
||||
|
||||
<Preference
|
||||
android:key="limit_summary"
|
||||
android:selectable="false"
|
||||
settings:allowDividerBelow="true" />
|
||||
|
||||
<com.android.settings.datausage.DataSaverPreference
|
||||
android:key="restrict_background_legacy"
|
||||
android:title="@string/data_saver_title"
|
||||
android:fragment="com.android.settings.datausage.DataSaverSummary" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
</PreferenceScreen>
|
||||
@@ -31,7 +31,8 @@
|
||||
|
||||
<com.android.settingslib.RestrictedSwitchPreference
|
||||
android:key="security_lockscreen_add_users_when_locked"
|
||||
android:title="@string/user_add_on_lockscreen_menu" />
|
||||
android:title="@string/user_add_on_lockscreen_menu"
|
||||
settings:controller="com.android.settings.users.AddUserWhenLockedPreferenceController" />
|
||||
|
||||
<com.android.settingslib.RestrictedPreference
|
||||
android:key="owner_info_settings"
|
||||
|
||||
@@ -76,7 +76,6 @@ public class Settings extends SettingsActivity {
|
||||
public static class CryptKeeperSettingsActivity extends SettingsActivity { /* empty */ }
|
||||
public static class DeviceAdminSettingsActivity extends SettingsActivity { /* empty */ }
|
||||
public static class DataUsageSummaryActivity extends SettingsActivity { /* empty */ }
|
||||
public static class DataUsageSummaryLegacyActivity extends SettingsActivity { /* empty */ }
|
||||
public static class MobileDataUsageListActivity extends SettingsActivity { /* empty */ }
|
||||
public static class ConfigureWifiSettingsActivity extends SettingsActivity { /* empty */ }
|
||||
public static class SavedAccessPointsSettingsActivity extends SettingsActivity { /* empty */ }
|
||||
|
||||
@@ -664,17 +664,9 @@ public class SettingsActivity extends SettingsDrawerActivity
|
||||
Settings.PowerUsageSummaryActivity.class.getName()),
|
||||
mBatteryPresent, isAdmin) || somethingChanged;
|
||||
|
||||
final boolean isDataUsageSettingsV2Enabled =
|
||||
FeatureFlagUtils.isEnabled(this, FeatureFlags.DATA_USAGE_SETTINGS_V2);
|
||||
// Enable new data usage page if v2 enabled
|
||||
somethingChanged = setTileEnabled(changedList, new ComponentName(packageName,
|
||||
Settings.DataUsageSummaryActivity.class.getName()),
|
||||
Utils.isBandwidthControlEnabled() && isDataUsageSettingsV2Enabled, isAdmin)
|
||||
|| somethingChanged;
|
||||
// Enable legacy data usage page if v2 disabled
|
||||
somethingChanged = setTileEnabled(changedList, new ComponentName(packageName,
|
||||
Settings.DataUsageSummaryLegacyActivity.class.getName()),
|
||||
Utils.isBandwidthControlEnabled() && !isDataUsageSettingsV2Enabled, isAdmin)
|
||||
Utils.isBandwidthControlEnabled(), isAdmin)
|
||||
|| somethingChanged;
|
||||
|
||||
somethingChanged = setTileEnabled(changedList, new ComponentName(packageName,
|
||||
|
||||
@@ -15,9 +15,13 @@
|
||||
*/
|
||||
package com.android.settings.applications;
|
||||
|
||||
import android.app.usage.IUsageStatsManager;
|
||||
import android.app.usage.UsageEvents;
|
||||
import android.app.usage.UsageStatsManager;
|
||||
import android.content.Context;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.view.View;
|
||||
@@ -25,6 +29,7 @@ import android.view.ViewGroup;
|
||||
import android.widget.Switch;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
import com.android.settingslib.applications.ApplicationsState;
|
||||
import com.android.settingslib.applications.ApplicationsState.AppEntry;
|
||||
@@ -33,6 +38,7 @@ import com.android.settingslib.utils.StringUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -42,17 +48,24 @@ import java.util.Map;
|
||||
public class AppStateNotificationBridge extends AppStateBaseBridge {
|
||||
|
||||
private final Context mContext;
|
||||
private UsageStatsManager mUsageStatsManager;
|
||||
private IUsageStatsManager mUsageStatsManager;
|
||||
protected List<Integer> mUserIds;
|
||||
private NotificationBackend mBackend;
|
||||
private static final int DAYS_TO_CHECK = 7;
|
||||
|
||||
public AppStateNotificationBridge(Context context, ApplicationsState appState,
|
||||
Callback callback, UsageStatsManager usageStatsManager,
|
||||
NotificationBackend backend) {
|
||||
Callback callback, IUsageStatsManager usageStatsManager,
|
||||
UserManager userManager, NotificationBackend backend) {
|
||||
super(appState, callback);
|
||||
mContext = context;
|
||||
mUsageStatsManager = usageStatsManager;
|
||||
mBackend = backend;
|
||||
mUserIds = new ArrayList<>();
|
||||
mUserIds.add(mContext.getUserId());
|
||||
int workUserId = Utils.getManagedProfileId(userManager, mContext.getUserId());
|
||||
if (workUserId != UserHandle.USER_NULL) {
|
||||
mUserIds.add(workUserId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -62,7 +75,8 @@ public class AppStateNotificationBridge extends AppStateBaseBridge {
|
||||
|
||||
final Map<String, NotificationsSentState> map = getAggregatedUsageEvents();
|
||||
for (AppEntry entry : apps) {
|
||||
NotificationsSentState stats = map.get(entry.info.packageName);
|
||||
NotificationsSentState stats =
|
||||
map.get(getKey(UserHandle.getUserId(entry.info.uid), entry.info.packageName));
|
||||
calculateAvgSentCounts(stats);
|
||||
addBlockStatus(entry, stats);
|
||||
entry.extraInfo = stats;
|
||||
@@ -71,8 +85,8 @@ public class AppStateNotificationBridge extends AppStateBaseBridge {
|
||||
|
||||
@Override
|
||||
protected void updateExtraInfo(AppEntry entry, String pkg, int uid) {
|
||||
Map<String, NotificationsSentState> map = getAggregatedUsageEvents();
|
||||
NotificationsSentState stats = map.get(entry.info.packageName);
|
||||
NotificationsSentState stats = getAggregatedUsageEvents(
|
||||
UserHandle.getUserId(entry.info.uid), entry.info.packageName);
|
||||
calculateAvgSentCounts(stats);
|
||||
addBlockStatus(entry, stats);
|
||||
entry.extraInfo = stats;
|
||||
@@ -116,18 +130,59 @@ public class AppStateNotificationBridge extends AppStateBaseBridge {
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
long startTime = now - (DateUtils.DAY_IN_MILLIS * DAYS_TO_CHECK);
|
||||
UsageEvents events = mUsageStatsManager.queryEvents(startTime, now);
|
||||
for (int userId : mUserIds) {
|
||||
UsageEvents events = null;
|
||||
try {
|
||||
events = mUsageStatsManager.queryEventsForUser(
|
||||
startTime, now, userId, mContext.getPackageName());
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (events != null) {
|
||||
UsageEvents.Event event = new UsageEvents.Event();
|
||||
while (events.hasNextEvent()) {
|
||||
events.getNextEvent(event);
|
||||
NotificationsSentState stats =
|
||||
aggregatedStats.get(getKey(userId, event.getPackageName()));
|
||||
if (stats == null) {
|
||||
stats = new NotificationsSentState();
|
||||
aggregatedStats.put(getKey(userId, event.getPackageName()), stats);
|
||||
}
|
||||
|
||||
if (event.getEventType() == UsageEvents.Event.NOTIFICATION_INTERRUPTION) {
|
||||
if (event.getTimeStamp() > stats.lastSent) {
|
||||
stats.lastSent = event.getTimeStamp();
|
||||
}
|
||||
stats.sentCount++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return aggregatedStats;
|
||||
}
|
||||
|
||||
protected NotificationsSentState getAggregatedUsageEvents(int userId, String pkg) {
|
||||
NotificationsSentState stats = null;
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
long startTime = now - (DateUtils.DAY_IN_MILLIS * DAYS_TO_CHECK);
|
||||
UsageEvents events = null;
|
||||
try {
|
||||
events = mUsageStatsManager.queryEventsForPackageForUser(
|
||||
startTime, now, userId, pkg, mContext.getPackageName());
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (events != null) {
|
||||
UsageEvents.Event event = new UsageEvents.Event();
|
||||
while (events.hasNextEvent()) {
|
||||
events.getNextEvent(event);
|
||||
NotificationsSentState stats = aggregatedStats.get(event.getPackageName());
|
||||
if (stats == null) {
|
||||
stats = new NotificationsSentState();
|
||||
aggregatedStats.put(event.getPackageName(), stats);
|
||||
}
|
||||
|
||||
if (event.getEventType() == UsageEvents.Event.NOTIFICATION_INTERRUPTION) {
|
||||
if (stats == null) {
|
||||
stats = new NotificationsSentState();
|
||||
}
|
||||
if (event.getTimeStamp() > stats.lastSent) {
|
||||
stats.lastSent = event.getTimeStamp();
|
||||
}
|
||||
@@ -136,7 +191,7 @@ public class AppStateNotificationBridge extends AppStateBaseBridge {
|
||||
|
||||
}
|
||||
}
|
||||
return aggregatedStats;
|
||||
return stats;
|
||||
}
|
||||
|
||||
private static NotificationsSentState getNotificationsSentState(AppEntry entry) {
|
||||
@@ -149,6 +204,10 @@ public class AppStateNotificationBridge extends AppStateBaseBridge {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected static String getKey(int userId, String pkg) {
|
||||
return userId + "|" + pkg;
|
||||
}
|
||||
|
||||
public View.OnClickListener getSwitchOnClickListener(final AppEntry entry) {
|
||||
if (entry != null) {
|
||||
return v -> {
|
||||
|
||||
@@ -41,6 +41,7 @@ import static com.android.settings.applications.manageapplications.AppFilterRegi
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.StringRes;
|
||||
import android.app.Activity;
|
||||
import android.app.usage.IUsageStatsManager;
|
||||
import android.app.usage.UsageStatsManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@@ -48,6 +49,7 @@ import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageItemInfo;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.preference.PreferenceFrameLayout;
|
||||
@@ -224,7 +226,8 @@ public class ManageApplications extends InstrumentedFragment
|
||||
private View mSpinnerHeader;
|
||||
private Spinner mFilterSpinner;
|
||||
private FilterSpinnerAdapter mFilterAdapter;
|
||||
private UsageStatsManager mUsageStatsManager;
|
||||
private IUsageStatsManager mUsageStatsManager;
|
||||
private UserManager mUserManager;
|
||||
private NotificationBackend mNotificationBackend;
|
||||
private ResetAppsHelper mResetAppsHelper;
|
||||
private String mVolumeUuid;
|
||||
@@ -294,8 +297,9 @@ public class ManageApplications extends InstrumentedFragment
|
||||
screenTitle = R.string.change_wifi_state_title;
|
||||
} else if (className.equals(Settings.NotificationAppListActivity.class.getName())) {
|
||||
mListType = LIST_TYPE_NOTIFICATION;
|
||||
mUsageStatsManager =
|
||||
(UsageStatsManager) getContext().getSystemService(Context.USAGE_STATS_SERVICE);
|
||||
mUsageStatsManager = IUsageStatsManager.Stub.asInterface(
|
||||
ServiceManager.getService(Context.USAGE_STATS_SERVICE));
|
||||
mUserManager = UserManager.get(getContext());
|
||||
mNotificationBackend = new NotificationBackend();
|
||||
mSortOrder = R.id.sort_order_recent_notification;
|
||||
screenTitle = R.string.app_notifications_title;
|
||||
@@ -889,6 +893,7 @@ public class ManageApplications extends InstrumentedFragment
|
||||
if (mManageApplications.mListType == LIST_TYPE_NOTIFICATION) {
|
||||
mExtraInfoBridge = new AppStateNotificationBridge(mContext, mState, this,
|
||||
manageApplications.mUsageStatsManager,
|
||||
manageApplications.mUserManager,
|
||||
manageApplications.mNotificationBackend);
|
||||
} else if (mManageApplications.mListType == LIST_TYPE_USAGE_ACCESS) {
|
||||
mExtraInfoBridge = new AppStateUsageBridge(mContext, mState, this);
|
||||
|
||||
@@ -21,8 +21,6 @@ package com.android.settings.core;
|
||||
*/
|
||||
public class FeatureFlags {
|
||||
public static final String BATTERY_DISPLAY_APP_LIST = "settings_battery_display_app_list";
|
||||
public static final String ZONE_PICKER_V2 = "settings_zone_picker_v2";
|
||||
public static final String BLUETOOTH_WHILE_DRIVING = "settings_bluetooth_while_driving";
|
||||
public static final String DATA_USAGE_SETTINGS_V2 = "settings_data_usage_v2";
|
||||
public static final String AUDIO_SWITCHER_SETTINGS = "settings_audio_switcher";
|
||||
}
|
||||
|
||||
@@ -59,7 +59,6 @@ import com.android.settings.connecteddevice.PreviouslyConnectedDeviceDashboardFr
|
||||
import com.android.settings.connecteddevice.usb.UsbDetailsFragment;
|
||||
import com.android.settings.datausage.DataUsageList;
|
||||
import com.android.settings.datausage.DataUsageSummary;
|
||||
import com.android.settings.datausage.DataUsageSummaryLegacy;
|
||||
import com.android.settings.deletionhelper.AutomaticStorageManagerSettings;
|
||||
import com.android.settings.development.DevelopmentSettingsDashboardFragment;
|
||||
import com.android.settings.deviceinfo.PrivateVolumeForget;
|
||||
@@ -192,7 +191,6 @@ public class SettingsGateway {
|
||||
SwipeUpGestureSettings.class.getName(),
|
||||
CryptKeeperSettings.class.getName(),
|
||||
DataUsageSummary.class.getName(),
|
||||
DataUsageSummaryLegacy.class.getName(),
|
||||
DreamSettings.class.getName(),
|
||||
UserSettings.class.getName(),
|
||||
NotificationAccessSettings.class.getName(),
|
||||
|
||||
@@ -18,12 +18,10 @@ package com.android.settings.dashboard.conditional;
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.NetworkPolicyManager;
|
||||
import android.util.FeatureFlagUtils;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Settings;
|
||||
import com.android.settings.core.FeatureFlags;
|
||||
|
||||
public class BackgroundDataCondition extends Condition {
|
||||
|
||||
@@ -58,11 +56,8 @@ public class BackgroundDataCondition extends Condition {
|
||||
|
||||
@Override
|
||||
public void onPrimaryClick() {
|
||||
final Class activityClass = FeatureFlagUtils.isEnabled(mManager.getContext(),
|
||||
FeatureFlags.DATA_USAGE_SETTINGS_V2)
|
||||
? Settings.DataUsageSummaryActivity.class
|
||||
: Settings.DataUsageSummaryLegacyActivity.class;
|
||||
mManager.getContext().startActivity(new Intent(mManager.getContext(), activityClass)
|
||||
mManager.getContext().startActivity(new Intent(mManager.getContext(),
|
||||
Settings.DataUsageSummaryActivity.class)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
|
||||
}
|
||||
|
||||
|
||||
@@ -14,24 +14,20 @@
|
||||
|
||||
package com.android.settings.datausage;
|
||||
|
||||
import static android.net.NetworkPolicy.CYCLE_NONE;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.NetworkTemplate;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import androidx.preference.Preference;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.FeatureFlagUtils;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
|
||||
import com.android.settings.core.FeatureFlags;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settings.datausage.CellDataPreference.DataStateListener;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
|
||||
public class BillingCyclePreference extends Preference implements TemplatePreference {
|
||||
|
||||
private NetworkTemplate mTemplate;
|
||||
@@ -60,14 +56,8 @@ public class BillingCyclePreference extends Preference implements TemplatePrefer
|
||||
mTemplate = template;
|
||||
mSubId = subId;
|
||||
mServices = services;
|
||||
final int cycleDay = services.mPolicyEditor.getPolicyCycleDay(mTemplate);
|
||||
if (FeatureFlagUtils.isEnabled(getContext(), FeatureFlags.DATA_USAGE_SETTINGS_V2)) {
|
||||
setSummary(null);
|
||||
} else if (cycleDay != CYCLE_NONE) {
|
||||
setSummary(getContext().getString(R.string.billing_cycle_fragment_summary, cycleDay));
|
||||
} else {
|
||||
setSummary(null);
|
||||
}
|
||||
setSummary(null);
|
||||
|
||||
setIntent(getIntent());
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
package com.android.settings.datausage;
|
||||
|
||||
import static android.net.NetworkPolicy.CYCLE_NONE;
|
||||
import static android.net.NetworkPolicy.LIMIT_DISABLED;
|
||||
import static android.net.NetworkPolicy.WARNING_DISABLED;
|
||||
|
||||
@@ -27,10 +26,7 @@ import android.content.res.Resources;
|
||||
import android.net.NetworkPolicy;
|
||||
import android.net.NetworkTemplate;
|
||||
import android.os.Bundle;
|
||||
import androidx.preference.SwitchPreference;
|
||||
import androidx.preference.Preference;
|
||||
import android.text.format.Time;
|
||||
import android.util.FeatureFlagUtils;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@@ -41,11 +37,13 @@ import android.widget.Spinner;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.FeatureFlags;
|
||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||
import com.android.settingslib.NetworkPolicyEditor;
|
||||
import com.android.settingslib.net.DataUsageController;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.SwitchPreference;
|
||||
|
||||
public class BillingCycleSettings extends DataUsageBase implements
|
||||
Preference.OnPreferenceChangeListener, DataUsageEditController {
|
||||
|
||||
@@ -63,7 +61,8 @@ public class BillingCycleSettings extends DataUsageBase implements
|
||||
private static final String KEY_BILLING_CYCLE = "billing_cycle";
|
||||
private static final String KEY_SET_DATA_WARNING = "set_data_warning";
|
||||
private static final String KEY_DATA_WARNING = "data_warning";
|
||||
@VisibleForTesting static final String KEY_SET_DATA_LIMIT = "set_data_limit";
|
||||
@VisibleForTesting
|
||||
static final String KEY_SET_DATA_LIMIT = "set_data_limit";
|
||||
private static final String KEY_DATA_LIMIT = "data_limit";
|
||||
|
||||
private NetworkTemplate mNetworkTemplate;
|
||||
@@ -76,11 +75,11 @@ public class BillingCycleSettings extends DataUsageBase implements
|
||||
|
||||
@VisibleForTesting
|
||||
void setUpForTest(NetworkPolicyEditor policyEditor,
|
||||
Preference billingCycle,
|
||||
Preference dataLimit,
|
||||
Preference dataWarning,
|
||||
SwitchPreference enableLimit,
|
||||
SwitchPreference enableWarning) {
|
||||
Preference billingCycle,
|
||||
Preference dataLimit,
|
||||
Preference dataWarning,
|
||||
SwitchPreference enableLimit,
|
||||
SwitchPreference enableWarning) {
|
||||
services.mPolicyEditor = policyEditor;
|
||||
mBillingCycle = billingCycle;
|
||||
mDataLimit = dataLimit;
|
||||
@@ -118,14 +117,7 @@ public class BillingCycleSettings extends DataUsageBase implements
|
||||
|
||||
@VisibleForTesting
|
||||
void updatePrefs() {
|
||||
final int cycleDay = services.mPolicyEditor.getPolicyCycleDay(mNetworkTemplate);
|
||||
if (FeatureFlagUtils.isEnabled(getContext(), FeatureFlags.DATA_USAGE_SETTINGS_V2)) {
|
||||
mBillingCycle.setSummary(null);
|
||||
} else if (cycleDay != CYCLE_NONE) {
|
||||
mBillingCycle.setSummary(getString(R.string.billing_cycle_fragment_summary, cycleDay));
|
||||
} else {
|
||||
mBillingCycle.setSummary(null);
|
||||
}
|
||||
mBillingCycle.setSummary(null);
|
||||
final long warningBytes = services.mPolicyEditor.getPolicyWarningBytes(mNetworkTemplate);
|
||||
if (warningBytes != WARNING_DISABLED) {
|
||||
mDataWarning.setSummary(DataUsageUtils.formatDataUsage(getContext(), warningBytes));
|
||||
@@ -402,7 +394,8 @@ public class BillingCycleSettings extends DataUsageBase implements
|
||||
*/
|
||||
public static class ConfirmLimitFragment extends InstrumentedDialogFragment implements
|
||||
DialogInterface.OnClickListener {
|
||||
@VisibleForTesting static final String EXTRA_LIMIT_BYTES = "limitBytes";
|
||||
@VisibleForTesting
|
||||
static final String EXTRA_LIMIT_BYTES = "limitBytes";
|
||||
public static final float FLOAT = 1.2f;
|
||||
|
||||
public static void show(BillingCycleSettings parent) {
|
||||
|
||||
@@ -18,9 +18,6 @@ import android.content.Context;
|
||||
import android.net.NetworkPolicy;
|
||||
import android.net.NetworkStatsHistory;
|
||||
import android.net.TrafficStats;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.Formatter;
|
||||
@@ -30,7 +27,11 @@ import android.util.SparseIntArray;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.graph.UsageView;
|
||||
import com.android.settings.widget.UsageView;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
public class ChartDataUsagePreference extends Preference {
|
||||
|
||||
|
||||
@@ -14,25 +14,19 @@
|
||||
|
||||
package com.android.settings.datausage;
|
||||
|
||||
import static android.net.ConnectivityManager.TYPE_ETHERNET;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.INetworkStatsService;
|
||||
import android.net.INetworkStatsSession;
|
||||
import android.net.NetworkPolicy;
|
||||
import android.net.NetworkPolicyManager;
|
||||
import android.net.NetworkTemplate;
|
||||
import android.net.TrafficStats;
|
||||
import android.os.Bundle;
|
||||
import android.os.INetworkManagementService;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.SystemProperties;
|
||||
import android.os.UserManager;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settingslib.NetworkPolicyEditor;
|
||||
|
||||
@@ -99,34 +93,4 @@ public abstract class DataUsageBase extends SettingsPreferenceFragment {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if device has an ethernet network connection.
|
||||
*/
|
||||
public boolean hasEthernet(Context context) {
|
||||
if (DataUsageUtils.TEST_RADIOS) {
|
||||
return SystemProperties.get(DataUsageUtils.TEST_RADIOS_PROP).contains(ETHERNET);
|
||||
}
|
||||
|
||||
final ConnectivityManager conn = ConnectivityManager.from(context);
|
||||
final boolean hasEthernet = conn.isNetworkSupported(TYPE_ETHERNET);
|
||||
|
||||
final long ethernetBytes;
|
||||
try {
|
||||
INetworkStatsSession statsSession = services.mStatsService.openSession();
|
||||
if (statsSession != null) {
|
||||
ethernetBytes = statsSession.getSummaryForNetwork(
|
||||
NetworkTemplate.buildTemplateEthernet(), Long.MIN_VALUE, Long.MAX_VALUE)
|
||||
.getTotalBytes();
|
||||
TrafficStats.closeQuietly(statsSession);
|
||||
} else {
|
||||
ethernetBytes = 0;
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
// only show ethernet when both hardware present and traffic has occurred
|
||||
return hasEthernet && ethernetBytes > 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,27 +14,19 @@
|
||||
|
||||
package com.android.settings.datausage;
|
||||
|
||||
import static android.net.ConnectivityManager.TYPE_ETHERNET;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.INetworkStatsService;
|
||||
import android.net.INetworkStatsSession;
|
||||
import android.net.NetworkPolicy;
|
||||
import android.net.NetworkPolicyManager;
|
||||
import android.net.NetworkTemplate;
|
||||
import android.net.TrafficStats;
|
||||
import android.os.Bundle;
|
||||
import android.os.INetworkManagementService;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.SystemProperties;
|
||||
import android.os.UserManager;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settingslib.NetworkPolicyEditor;
|
||||
|
||||
@@ -54,7 +46,7 @@ public abstract class DataUsageBaseFragment extends DashboardFragment {
|
||||
ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE));
|
||||
services.mStatsService = INetworkStatsService.Stub.asInterface(
|
||||
ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
|
||||
services.mPolicyManager = (NetworkPolicyManager)context
|
||||
services.mPolicyManager = (NetworkPolicyManager) context
|
||||
.getSystemService(Context.NETWORK_POLICY_SERVICE);
|
||||
|
||||
services.mPolicyEditor = new NetworkPolicyEditor(services.mPolicyManager);
|
||||
@@ -98,35 +90,4 @@ public abstract class DataUsageBaseFragment extends DashboardFragment {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if device has an ethernet network connection.
|
||||
* TODO(b/77590489): Remove this method when DataUsageSummaryLegacy is deprecated.
|
||||
*/
|
||||
public boolean hasEthernet(Context context) {
|
||||
if (DataUsageUtils.TEST_RADIOS) {
|
||||
return SystemProperties.get(DataUsageUtils.TEST_RADIOS_PROP).contains(ETHERNET);
|
||||
}
|
||||
|
||||
final ConnectivityManager conn = ConnectivityManager.from(context);
|
||||
final boolean hasEthernet = conn.isNetworkSupported(TYPE_ETHERNET);
|
||||
|
||||
final long ethernetBytes;
|
||||
try {
|
||||
INetworkStatsSession statsSession = services.mStatsService.openSession();
|
||||
if (statsSession != null) {
|
||||
ethernetBytes = statsSession.getSummaryForNetwork(
|
||||
NetworkTemplate.buildTemplateEthernet(), Long.MIN_VALUE, Long.MAX_VALUE)
|
||||
.getTotalBytes();
|
||||
TrafficStats.closeQuietly(statsSession);
|
||||
} else {
|
||||
ethernetBytes = 0;
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
// only show ethernet when both hardware present and traffic has occurred
|
||||
return hasEthernet && ethernetBytes > 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,17 +19,16 @@ import android.content.Intent;
|
||||
import android.content.res.TypedArray;
|
||||
import android.net.NetworkTemplate;
|
||||
import android.os.Bundle;
|
||||
import androidx.core.content.res.TypedArrayUtils;
|
||||
import androidx.preference.Preference;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.FeatureFlagUtils;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.FeatureFlags;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settingslib.net.DataUsageController;
|
||||
|
||||
import androidx.core.content.res.TypedArrayUtils;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
public class DataUsagePreference extends Preference implements TemplatePreference {
|
||||
|
||||
private NetworkTemplate mTemplate;
|
||||
@@ -54,20 +53,13 @@ public class DataUsagePreference extends Preference implements TemplatePreferenc
|
||||
mSubId = subId;
|
||||
DataUsageController controller = new DataUsageController(getContext());
|
||||
DataUsageController.DataUsageInfo usageInfo = controller.getDataUsageInfo(mTemplate);
|
||||
if (FeatureFlagUtils.isEnabled(getContext(), FeatureFlags.DATA_USAGE_SETTINGS_V2)) {
|
||||
if (mTemplate.isMatchRuleMobile()) {
|
||||
setTitle(R.string.app_cellular_data_usage);
|
||||
} else {
|
||||
setTitle(mTitleRes);
|
||||
setSummary(getContext().getString(R.string.data_usage_template,
|
||||
DataUsageUtils.formatDataUsage(getContext(), usageInfo.usageLevel),
|
||||
usageInfo.period));
|
||||
}
|
||||
if (mTemplate.isMatchRuleMobile()) {
|
||||
setTitle(R.string.app_cellular_data_usage);
|
||||
} else {
|
||||
setTitle(mTitleRes);
|
||||
setSummary(getContext().getString(R.string.data_usage_template,
|
||||
DataUsageUtils.formatDataUsage(getContext(), usageInfo.usageLevel),
|
||||
usageInfo.period));
|
||||
usageInfo.period));
|
||||
}
|
||||
setIntent(getIntent());
|
||||
}
|
||||
@@ -81,18 +73,10 @@ public class DataUsagePreference extends Preference implements TemplatePreferenc
|
||||
.setArguments(args)
|
||||
.setDestination(DataUsageList.class.getName())
|
||||
.setSourceMetricsCategory(MetricsProto.MetricsEvent.VIEW_UNKNOWN);
|
||||
if (FeatureFlagUtils.isEnabled(getContext(), FeatureFlags.DATA_USAGE_SETTINGS_V2)) {
|
||||
if (mTemplate.isMatchRuleMobile()) {
|
||||
launcher.setTitleRes(R.string.app_cellular_data_usage);
|
||||
} else {
|
||||
launcher.setTitleRes(mTitleRes);
|
||||
}
|
||||
if (mTemplate.isMatchRuleMobile()) {
|
||||
launcher.setTitleRes(R.string.app_cellular_data_usage);
|
||||
} else {
|
||||
if (mTitleRes > 0) {
|
||||
launcher.setTitleRes(mTitleRes);
|
||||
} else {
|
||||
launcher.setTitleText(getTitle());
|
||||
}
|
||||
launcher.setTitleRes(mTitleRes);
|
||||
}
|
||||
return launcher.toIntent();
|
||||
}
|
||||
|
||||
@@ -15,15 +15,10 @@
|
||||
package com.android.settings.datausage;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.NetworkTemplate;
|
||||
import android.os.Bundle;
|
||||
import android.provider.SearchIndexableResource;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.SubscriptionPlan;
|
||||
@@ -33,7 +28,6 @@ import android.text.SpannableString;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.Formatter;
|
||||
import android.text.style.RelativeSizeSpan;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.R;
|
||||
@@ -49,6 +43,10 @@ import com.android.settingslib.search.SearchIndexable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
/**
|
||||
* Settings preference fragment that displays data usage summary.
|
||||
*/
|
||||
@@ -120,20 +118,6 @@ public class DataUsageSummary extends DataUsageBaseFragment implements Indexable
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.data_usage_menu_cellular_networks: {
|
||||
final Intent intent = new Intent(Intent.ACTION_MAIN);
|
||||
intent.setComponent(new ComponentName("com.android.phone",
|
||||
"com.android.phone.MobileNetworkSettings"));
|
||||
startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceTreeClick(Preference preference) {
|
||||
if (preference == findPreference(KEY_STATUS_HEADER)) {
|
||||
|
||||
@@ -1,359 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.datausage;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.NetworkPolicyManager;
|
||||
import android.net.NetworkTemplate;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserManager;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.text.BidiFormatter;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.Formatter;
|
||||
import android.text.style.RelativeSizeSpan;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SummaryPreference;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.dashboard.SummaryLoader;
|
||||
import com.android.settings.search.Indexable;
|
||||
import com.android.settingslib.NetworkPolicyEditor;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import com.android.settingslib.net.DataUsageController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
/**
|
||||
* Legacy {@link DataUsageSummary} fragment.
|
||||
*/
|
||||
public class DataUsageSummaryLegacy extends DataUsageBaseFragment implements Indexable,
|
||||
DataUsageEditController {
|
||||
|
||||
private static final String TAG = "DataUsageSummaryLegacy";
|
||||
|
||||
static final boolean LOGD = false;
|
||||
|
||||
public static final String KEY_RESTRICT_BACKGROUND = "restrict_background_legacy";
|
||||
|
||||
private static final String KEY_STATUS_HEADER = "status_header";
|
||||
private static final String KEY_LIMIT_SUMMARY = "limit_summary";
|
||||
|
||||
// Mobile data keys
|
||||
public static final String KEY_MOBILE_USAGE_TITLE = "mobile_category";
|
||||
public static final String KEY_MOBILE_DATA_USAGE_TOGGLE = "data_usage_enable";
|
||||
public static final String KEY_MOBILE_DATA_USAGE = "cellular_data_usage";
|
||||
public static final String KEY_MOBILE_BILLING_CYCLE = "billing_preference";
|
||||
|
||||
// Wifi keys
|
||||
public static final String KEY_WIFI_USAGE_TITLE = "wifi_category";
|
||||
public static final String KEY_WIFI_DATA_USAGE = "wifi_data_usage";
|
||||
|
||||
private DataUsageController mDataUsageController;
|
||||
private DataUsageInfoController mDataInfoController;
|
||||
private SummaryPreference mSummaryPreference;
|
||||
private Preference mLimitPreference;
|
||||
private NetworkTemplate mDefaultTemplate;
|
||||
private int mDataUsageTemplate;
|
||||
private NetworkPolicyEditor mPolicyEditor;
|
||||
|
||||
@Override
|
||||
public int getHelpResource() {
|
||||
return R.string.help_url_data_usage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
|
||||
final Context context = getContext();
|
||||
NetworkPolicyManager policyManager = NetworkPolicyManager.from(context);
|
||||
mPolicyEditor = new NetworkPolicyEditor(policyManager);
|
||||
|
||||
boolean hasMobileData = DataUsageUtils.hasMobileData(context);
|
||||
mDataUsageController = new DataUsageController(context);
|
||||
mDataInfoController = new DataUsageInfoController();
|
||||
|
||||
int defaultSubId = DataUsageUtils.getDefaultSubscriptionId(context);
|
||||
if (defaultSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
|
||||
hasMobileData = false;
|
||||
}
|
||||
mDefaultTemplate = DataUsageUtils.getDefaultTemplate(context, defaultSubId);
|
||||
mSummaryPreference = (SummaryPreference) findPreference(KEY_STATUS_HEADER);
|
||||
|
||||
if (!hasMobileData || !isAdmin()) {
|
||||
removePreference(KEY_RESTRICT_BACKGROUND);
|
||||
}
|
||||
if (hasMobileData) {
|
||||
mLimitPreference = findPreference(KEY_LIMIT_SUMMARY);
|
||||
List<SubscriptionInfo> subscriptions =
|
||||
services.mSubscriptionManager.getActiveSubscriptionInfoList();
|
||||
if (subscriptions == null || subscriptions.size() == 0) {
|
||||
addMobileSection(defaultSubId);
|
||||
}
|
||||
for (int i = 0; subscriptions != null && i < subscriptions.size(); i++) {
|
||||
SubscriptionInfo subInfo = subscriptions.get(i);
|
||||
if (subscriptions.size() > 1) {
|
||||
addMobileSection(subInfo.getSubscriptionId(), subInfo);
|
||||
} else {
|
||||
addMobileSection(subInfo.getSubscriptionId());
|
||||
}
|
||||
}
|
||||
mSummaryPreference.setSelectable(true);
|
||||
} else {
|
||||
removePreference(KEY_LIMIT_SUMMARY);
|
||||
mSummaryPreference.setSelectable(false);
|
||||
}
|
||||
boolean hasWifiRadio = DataUsageUtils.hasWifiRadio(context);
|
||||
if (hasWifiRadio) {
|
||||
addWifiSection();
|
||||
}
|
||||
if (hasEthernet(context)) {
|
||||
addEthernetSection();
|
||||
}
|
||||
mDataUsageTemplate = hasMobileData ? R.string.cell_data_template
|
||||
: hasWifiRadio ? R.string.wifi_data_template
|
||||
: R.string.ethernet_data_template;
|
||||
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
if (UserManager.get(getContext()).isAdminUser()) {
|
||||
inflater.inflate(R.menu.data_usage, menu);
|
||||
}
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.data_usage_menu_cellular_networks: {
|
||||
final Intent intent = new Intent(Intent.ACTION_MAIN);
|
||||
intent.setComponent(new ComponentName("com.android.phone",
|
||||
"com.android.phone.MobileNetworkSettings"));
|
||||
startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceTreeClick(Preference preference) {
|
||||
if (preference == findPreference(KEY_STATUS_HEADER)) {
|
||||
BillingCycleSettings.BytesEditorFragment.show(this, false);
|
||||
return false;
|
||||
}
|
||||
return super.onPreferenceTreeClick(preference);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPreferenceScreenResId() {
|
||||
return R.xml.data_usage_legacy;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getLogTag() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void addMobileSection(int subId) {
|
||||
addMobileSection(subId, null);
|
||||
}
|
||||
|
||||
private void addMobileSection(int subId, SubscriptionInfo subInfo) {
|
||||
TemplatePreferenceCategory category = (TemplatePreferenceCategory)
|
||||
inflatePreferences(R.xml.data_usage_cellular);
|
||||
category.setTemplate(getNetworkTemplate(subId), subId, services);
|
||||
category.pushTemplates(services);
|
||||
if (subInfo != null && !TextUtils.isEmpty(subInfo.getDisplayName())) {
|
||||
Preference title = category.findPreference(KEY_MOBILE_USAGE_TITLE);
|
||||
title.setTitle(subInfo.getDisplayName());
|
||||
}
|
||||
}
|
||||
|
||||
private void addWifiSection() {
|
||||
TemplatePreferenceCategory category = (TemplatePreferenceCategory)
|
||||
inflatePreferences(R.xml.data_usage_wifi);
|
||||
category.setTemplate(NetworkTemplate.buildTemplateWifiWildcard(), 0, services);
|
||||
}
|
||||
|
||||
private void addEthernetSection() {
|
||||
TemplatePreferenceCategory category = (TemplatePreferenceCategory)
|
||||
inflatePreferences(R.xml.data_usage_ethernet);
|
||||
category.setTemplate(NetworkTemplate.buildTemplateEthernet(), 0, services);
|
||||
}
|
||||
|
||||
private Preference inflatePreferences(int resId) {
|
||||
PreferenceScreen rootPreferences = getPreferenceManager().inflateFromResource(
|
||||
getPrefContext(), resId, null);
|
||||
Preference pref = rootPreferences.getPreference(0);
|
||||
rootPreferences.removeAll();
|
||||
|
||||
PreferenceScreen screen = getPreferenceScreen();
|
||||
pref.setOrder(screen.getPreferenceCount());
|
||||
screen.addPreference(pref);
|
||||
|
||||
return pref;
|
||||
}
|
||||
|
||||
private NetworkTemplate getNetworkTemplate(int subscriptionId) {
|
||||
NetworkTemplate mobileAll = NetworkTemplate.buildTemplateMobileAll(
|
||||
services.mTelephonyManager.getSubscriberId(subscriptionId));
|
||||
return NetworkTemplate.normalize(mobileAll,
|
||||
services.mTelephonyManager.getMergedSubscriberIds());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
updateState();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static CharSequence formatUsage(Context context, String template, long usageLevel) {
|
||||
final float LARGER_SIZE = 1.25f * 1.25f; // (1/0.8)^2
|
||||
final float SMALLER_SIZE = 1.0f / LARGER_SIZE; // 0.8^2
|
||||
final int FLAGS = Spannable.SPAN_INCLUSIVE_INCLUSIVE;
|
||||
|
||||
final Formatter.BytesResult usedResult = Formatter.formatBytes(context.getResources(),
|
||||
usageLevel, Formatter.FLAG_CALCULATE_ROUNDED);
|
||||
final SpannableString enlargedValue = new SpannableString(usedResult.value);
|
||||
enlargedValue.setSpan(new RelativeSizeSpan(LARGER_SIZE), 0, enlargedValue.length(), FLAGS);
|
||||
|
||||
final SpannableString amountTemplate = new SpannableString(
|
||||
context.getString(com.android.internal.R.string.fileSizeSuffix)
|
||||
.replace("%1$s", "^1").replace("%2$s", "^2"));
|
||||
final CharSequence formattedUsage = TextUtils.expandTemplate(amountTemplate,
|
||||
enlargedValue, usedResult.units);
|
||||
|
||||
final SpannableString fullTemplate = new SpannableString(template);
|
||||
fullTemplate.setSpan(new RelativeSizeSpan(SMALLER_SIZE), 0, fullTemplate.length(), FLAGS);
|
||||
return TextUtils.expandTemplate(fullTemplate,
|
||||
BidiFormatter.getInstance().unicodeWrap(formattedUsage.toString()));
|
||||
}
|
||||
|
||||
private void updateState() {
|
||||
DataUsageController.DataUsageInfo info = mDataUsageController.getDataUsageInfo(
|
||||
mDefaultTemplate);
|
||||
Context context = getContext();
|
||||
mDataInfoController.updateDataLimit(info,
|
||||
services.mPolicyEditor.getPolicy(mDefaultTemplate));
|
||||
|
||||
if (mSummaryPreference != null) {
|
||||
mSummaryPreference.setTitle(
|
||||
formatUsage(context, getString(mDataUsageTemplate), info.usageLevel));
|
||||
final long limit = mDataInfoController.getSummaryLimit(info);
|
||||
mSummaryPreference.setSummary(info.period);
|
||||
if (limit <= 0) {
|
||||
mSummaryPreference.setChartEnabled(false);
|
||||
} else {
|
||||
mSummaryPreference.setChartEnabled(true);
|
||||
mSummaryPreference.setLabels(Formatter.formatFileSize(context, 0),
|
||||
Formatter.formatFileSize(context, limit));
|
||||
mSummaryPreference.setRatios(info.usageLevel / (float) limit, 0,
|
||||
(limit - info.usageLevel) / (float) limit);
|
||||
}
|
||||
}
|
||||
if (mLimitPreference != null && (info.warningLevel > 0 || info.limitLevel > 0)) {
|
||||
String warning = Formatter.formatFileSize(context, info.warningLevel);
|
||||
String limit = Formatter.formatFileSize(context, info.limitLevel);
|
||||
mLimitPreference.setSummary(getString(info.limitLevel <= 0 ? R.string.cell_warning_only
|
||||
: R.string.cell_warning_and_limit, warning, limit));
|
||||
} else if (mLimitPreference != null) {
|
||||
mLimitPreference.setSummary(null);
|
||||
}
|
||||
|
||||
PreferenceScreen screen = getPreferenceScreen();
|
||||
for (int i = 1; i < screen.getPreferenceCount(); i++) {
|
||||
((TemplatePreferenceCategory) screen.getPreference(i)).pushTemplates(services);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return MetricsEvent.DATA_USAGE_SUMMARY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NetworkPolicyEditor getNetworkPolicyEditor() {
|
||||
return services.mPolicyEditor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NetworkTemplate getNetworkTemplate() {
|
||||
return mDefaultTemplate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDataUsage() {
|
||||
updateState();
|
||||
}
|
||||
|
||||
private static class SummaryProvider
|
||||
implements SummaryLoader.SummaryProvider {
|
||||
|
||||
private final Activity mActivity;
|
||||
private final SummaryLoader mSummaryLoader;
|
||||
private final DataUsageController mDataController;
|
||||
|
||||
public SummaryProvider(Activity activity, SummaryLoader summaryLoader) {
|
||||
mActivity = activity;
|
||||
mSummaryLoader = summaryLoader;
|
||||
mDataController = new DataUsageController(activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setListening(boolean listening) {
|
||||
if (listening) {
|
||||
DataUsageController.DataUsageInfo info = mDataController.getDataUsageInfo();
|
||||
String used;
|
||||
if (info == null) {
|
||||
used = Formatter.formatFileSize(mActivity, 0);
|
||||
} else if (info.limitLevel <= 0) {
|
||||
used = Formatter.formatFileSize(mActivity, info.usageLevel);
|
||||
} else {
|
||||
used = Utils.formatPercentage(info.usageLevel, info.limitLevel);
|
||||
}
|
||||
mSummaryLoader.setSummary(this,
|
||||
mActivity.getString(R.string.data_usage_summary_format, used));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY
|
||||
= SummaryProvider::new;
|
||||
}
|
||||
@@ -25,12 +25,13 @@ import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.internal.os.BatteryStatsHelper;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.fuelgauge.BatteryActiveView.BatteryActiveProvider;
|
||||
import com.android.settings.graph.UsageView;
|
||||
import com.android.settings.widget.UsageView;
|
||||
|
||||
public class BatteryHistoryDetail extends SettingsPreferenceFragment {
|
||||
public static final String EXTRA_STATS = "stats";
|
||||
@@ -76,7 +77,7 @@ public class BatteryHistoryDetail extends SettingsPreferenceFragment {
|
||||
mPhoneParser = new BatteryCellParser();
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
|
||||
@@ -17,15 +17,17 @@
|
||||
package com.android.settings.fuelgauge;
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.os.BatteryStatsHelper;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.graph.UsageView;
|
||||
import com.android.settings.widget.UsageView;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
/**
|
||||
* Custom preference for displaying power consumption as a bar and an icon on the left for the
|
||||
|
||||
@@ -24,18 +24,19 @@ import android.os.BatteryStats;
|
||||
import android.os.BatteryStats.HistoryItem;
|
||||
import android.os.Bundle;
|
||||
import android.os.SystemClock;
|
||||
import androidx.annotation.WorkerThread;
|
||||
import android.text.format.Formatter;
|
||||
import android.util.SparseIntArray;
|
||||
|
||||
import com.android.internal.os.BatteryStatsHelper;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.graph.UsageView;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.widget.UsageView;
|
||||
import com.android.settingslib.R;
|
||||
import com.android.settingslib.utils.PowerUtil;
|
||||
import com.android.settingslib.utils.StringUtil;
|
||||
|
||||
import androidx.annotation.WorkerThread;
|
||||
|
||||
public class BatteryInfo {
|
||||
|
||||
public CharSequence chargeLabel;
|
||||
@@ -129,7 +130,7 @@ public class BatteryInfo {
|
||||
remaining = context.getString(R.string.remaining_length_format,
|
||||
Formatter.formatShortElapsedTime(context, remainingTimeUs / 1000));
|
||||
}
|
||||
view.setBottomLabels(new CharSequence[]{timeString, remaining});
|
||||
view.setBottomLabels(new CharSequence[] {timeString, remaining});
|
||||
}
|
||||
|
||||
public static void getBatteryInfo(final Context context, final Callback callback) {
|
||||
@@ -173,7 +174,7 @@ public class BatteryInfo {
|
||||
if (discharging && provider != null
|
||||
&& provider.isEnhancedBatteryPredictionEnabled(context)) {
|
||||
Estimate estimate = provider.getEnhancedBatteryPrediction(context);
|
||||
if(estimate != null) {
|
||||
if (estimate != null) {
|
||||
BatteryUtils
|
||||
.logRuntime(LOG_TAG, "time for enhanced BatteryInfo", startTime);
|
||||
return BatteryInfo.getBatteryInfo(context, batteryBroadcast, stats,
|
||||
|
||||
@@ -16,12 +16,20 @@
|
||||
|
||||
package com.android.settings.gestures;
|
||||
|
||||
import android.content.Context;
|
||||
import static android.provider.Settings.Secure.VOLUME_HUSH_GESTURE;
|
||||
import static android.provider.Settings.Secure.VOLUME_HUSH_MUTE;
|
||||
import static android.provider.Settings.Secure.VOLUME_HUSH_VIBRATE;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
|
||||
public class PreventRingingParentPreferenceController extends BasePreferenceController {
|
||||
|
||||
final String SECURE_KEY = VOLUME_HUSH_GESTURE;
|
||||
|
||||
public PreventRingingParentPreferenceController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
}
|
||||
@@ -33,4 +41,21 @@ public class PreventRingingParentPreferenceController extends BasePreferenceCont
|
||||
? AVAILABLE_UNSEARCHABLE : UNSUPPORTED_ON_DEVICE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getSummary() {
|
||||
int value = Settings.Secure.getInt(
|
||||
mContext.getContentResolver(), SECURE_KEY, VOLUME_HUSH_VIBRATE);
|
||||
int summary;
|
||||
switch (value) {
|
||||
case VOLUME_HUSH_VIBRATE:
|
||||
summary = R.string.prevent_ringing_option_vibrate_summary;
|
||||
break;
|
||||
case VOLUME_HUSH_MUTE:
|
||||
summary = R.string.prevent_ringing_option_mute_summary;
|
||||
break;
|
||||
default:
|
||||
summary = R.string.prevent_ringing_option_none_summary;
|
||||
}
|
||||
return mContext.getText(summary);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,8 +50,6 @@ public class PreventRingingPreferenceController extends PreventRingingParentPref
|
||||
@VisibleForTesting
|
||||
boolean mVideoPaused;
|
||||
|
||||
private final String SECURE_KEY = VOLUME_HUSH_GESTURE;
|
||||
|
||||
public PreventRingingPreferenceController(Context context, String key) {
|
||||
super(context, key);
|
||||
}
|
||||
@@ -95,24 +93,6 @@ public class PreventRingingPreferenceController extends PreventRingingParentPref
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getSummary() {
|
||||
int value = Settings.Secure.getInt(
|
||||
mContext.getContentResolver(), SECURE_KEY, VOLUME_HUSH_VIBRATE);
|
||||
int summary;
|
||||
switch (value) {
|
||||
case VOLUME_HUSH_VIBRATE:
|
||||
summary = R.string.prevent_ringing_option_vibrate_summary;
|
||||
break;
|
||||
case VOLUME_HUSH_MUTE:
|
||||
summary = R.string.prevent_ringing_option_mute_summary;
|
||||
break;
|
||||
default:
|
||||
summary = R.string.prevent_ringing_option_none_summary;
|
||||
}
|
||||
return mContext.getString(summary);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
if (savedInstanceState != null) {
|
||||
|
||||
@@ -21,8 +21,7 @@ import android.content.Context;
|
||||
import android.location.SettingInjectorService;
|
||||
import android.os.Bundle;
|
||||
import android.provider.SearchIndexableResource;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceGroup;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
@@ -42,6 +41,9 @@ import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceGroup;
|
||||
|
||||
/**
|
||||
* System location settings (Settings > Location). The screen has three parts:
|
||||
* <ul>
|
||||
@@ -177,5 +179,12 @@ public class LocationSettings extends DashboardFragment {
|
||||
return buildPreferenceControllers(context, null /* fragment */,
|
||||
null /* lifecycle */);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getNonIndexableKeys(Context context) {
|
||||
final List<String> niks = super.getNonIndexableKeys(context);
|
||||
niks.add("recent_location_requests_see_all_button"); // 'See all' button
|
||||
return niks;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ import com.android.settings.gestures.DoubleTapScreenPreferenceController;
|
||||
import com.android.settings.gestures.PickupGesturePreferenceController;
|
||||
import com.android.settings.notification.LockScreenNotificationPreferenceController;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settings.users.AddUserWhenLockedPreferenceController;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.search.SearchIndexable;
|
||||
@@ -109,8 +108,6 @@ public class LockscreenDashboardFragment extends DashboardFragment
|
||||
KEY_LOCK_SCREEN_NOTIFICATON_WORK_PROFILE);
|
||||
lifecycle.addObserver(notificationController);
|
||||
controllers.add(notificationController);
|
||||
controllers.add(new AddUserWhenLockedPreferenceController(
|
||||
context, KEY_ADD_USER_FROM_LOCK_SCREEN, lifecycle));
|
||||
mOwnerInfoPreferenceController =
|
||||
new OwnerInfoPreferenceController(context, this, lifecycle);
|
||||
controllers.add(mOwnerInfoPreferenceController);
|
||||
@@ -147,8 +144,6 @@ public class LockscreenDashboardFragment extends DashboardFragment
|
||||
Context context) {
|
||||
final List<AbstractPreferenceController> controllers = new ArrayList<>();
|
||||
controllers.add(new LockScreenNotificationPreferenceController(context));
|
||||
controllers.add(new AddUserWhenLockedPreferenceController(context,
|
||||
KEY_ADD_USER_FROM_LOCK_SCREEN, null /* lifecycle */));
|
||||
controllers.add(new OwnerInfoPreferenceController(
|
||||
context, null /* fragment */, null /* lifecycle */));
|
||||
return controllers;
|
||||
|
||||
@@ -16,72 +16,53 @@
|
||||
package com.android.settings.users;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings.Global;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.android.settings.core.TogglePreferenceController;
|
||||
import com.android.settingslib.RestrictedSwitchPreference;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settingslib.RestrictedSwitchPreference;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settingslib.core.lifecycle.events.OnPause;
|
||||
import com.android.settingslib.core.lifecycle.events.OnResume;
|
||||
public class AddUserWhenLockedPreferenceController extends TogglePreferenceController {
|
||||
|
||||
public class AddUserWhenLockedPreferenceController extends AbstractPreferenceController
|
||||
implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener,
|
||||
LifecycleObserver, OnPause, OnResume {
|
||||
|
||||
private final String mPrefKey;
|
||||
private final UserCapabilities mUserCaps;
|
||||
private boolean mShouldUpdateUserList;
|
||||
|
||||
public AddUserWhenLockedPreferenceController(Context context, String key, Lifecycle lifecycle) {
|
||||
super(context);
|
||||
mPrefKey = key;
|
||||
public AddUserWhenLockedPreferenceController(Context context, String key) {
|
||||
super(context, key);
|
||||
mUserCaps = UserCapabilities.create(context);
|
||||
if (lifecycle != null) {
|
||||
lifecycle.addObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
RestrictedSwitchPreference restrictedSwitchPreference =
|
||||
super.updateState(preference);
|
||||
mUserCaps.updateAddUserCapabilities(mContext);
|
||||
final RestrictedSwitchPreference restrictedSwitchPreference =
|
||||
(RestrictedSwitchPreference) preference;
|
||||
int value = Global.getInt(mContext.getContentResolver(), Global.ADD_USERS_WHEN_LOCKED, 0);
|
||||
restrictedSwitchPreference.setChecked(value == 1);
|
||||
restrictedSwitchPreference.setDisabledByAdmin(
|
||||
mUserCaps.disallowAddUser() ? mUserCaps.getEnforcedAdmin() : null);
|
||||
restrictedSwitchPreference.setVisible(mUserCaps.mUserSwitcherEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
Boolean value = (Boolean) newValue;
|
||||
Global.putInt(mContext.getContentResolver(),
|
||||
Global.ADD_USERS_WHEN_LOCKED, value != null && value ? 1 : 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
mShouldUpdateUserList = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
if (mShouldUpdateUserList) {
|
||||
mUserCaps.updateAddUserCapabilities(mContext);
|
||||
public int getAvailabilityStatus() {
|
||||
if (!mUserCaps.isAdmin()) {
|
||||
return DISABLED_FOR_USER;
|
||||
} else if (mUserCaps.disallowAddUser() || mUserCaps.disallowAddUserSetByAdmin()) {
|
||||
return DISABLED_FOR_USER;
|
||||
} else {
|
||||
return mUserCaps.mUserSwitcherEnabled ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return mUserCaps.isAdmin() &&
|
||||
(!mUserCaps.disallowAddUser() || mUserCaps.disallowAddUserSetByAdmin());
|
||||
public boolean isChecked() {
|
||||
return Settings.Global.getInt(mContext.getContentResolver(),
|
||||
Settings.Global.ADD_USERS_WHEN_LOCKED, 0) == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return mPrefKey;
|
||||
public boolean setChecked(boolean isChecked) {
|
||||
return Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.ADD_USERS_WHEN_LOCKED, isChecked ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.users;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settingslib.widget.FooterPreference;
|
||||
import com.android.settingslib.widget.FooterPreferenceMixin;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
public class MultiUserFooterPreferenceController extends BasePreferenceController {
|
||||
|
||||
@VisibleForTesting
|
||||
final UserCapabilities mUserCaps;
|
||||
|
||||
private FooterPreferenceMixin mFooterMixin;
|
||||
|
||||
public MultiUserFooterPreferenceController(Context context) {
|
||||
super(context, "dummy_key");
|
||||
mUserCaps = UserCapabilities.create(context);
|
||||
}
|
||||
|
||||
public MultiUserFooterPreferenceController setFooterMixin(FooterPreferenceMixin footerMixin) {
|
||||
mFooterMixin = footerMixin;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return (mUserCaps.mEnabled && !mUserCaps.mUserSwitcherEnabled)
|
||||
? AVAILABLE_UNSEARCHABLE
|
||||
: DISABLED_FOR_USER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
mUserCaps.updateAddUserCapabilities(mContext);
|
||||
final FooterPreference pref = mFooterMixin.createFooterPreference();
|
||||
pref.setTitle(R.string.user_settings_footer_text);
|
||||
pref.setVisible(isAvailable());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.users;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.settings.widget.SwitchWidgetController;
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settingslib.core.lifecycle.events.OnStart;
|
||||
import com.android.settingslib.core.lifecycle.events.OnStop;
|
||||
|
||||
public class MultiUserSwitchBarController implements SwitchWidgetController.OnSwitchChangeListener,
|
||||
LifecycleObserver, OnStart, OnStop {
|
||||
|
||||
interface OnMultiUserSwitchChangedListener {
|
||||
void onMultiUserSwitchChanged(boolean newState);
|
||||
}
|
||||
|
||||
private static final String TAG = "MultiUserSwitchBarCtrl";
|
||||
private final Context mContext;
|
||||
private final SwitchWidgetController mSwitchBar;
|
||||
private final UserCapabilities mUserCapabilities;
|
||||
private final OnMultiUserSwitchChangedListener mListener;
|
||||
|
||||
MultiUserSwitchBarController(Context context, SwitchWidgetController switchBar,
|
||||
OnMultiUserSwitchChangedListener listener) {
|
||||
mContext = context;
|
||||
mSwitchBar = switchBar;
|
||||
mListener = listener;
|
||||
mUserCapabilities = UserCapabilities.create(context);
|
||||
mSwitchBar.setChecked(mUserCapabilities.mUserSwitcherEnabled);
|
||||
mSwitchBar.setEnabled(!mUserCapabilities.mDisallowSwitchUser
|
||||
&& !mUserCapabilities.mIsGuest && mUserCapabilities.isAdmin());
|
||||
mSwitchBar.setListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
mSwitchBar.startListening();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
mSwitchBar.stopListening();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSwitchToggled(boolean isChecked) {
|
||||
Log.d(TAG, "Toggling multi-user feature enabled state to: " + isChecked);
|
||||
final boolean success = Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.USER_SWITCHER_ENABLED, isChecked ? 1 : 0);
|
||||
if (success && mListener != null) {
|
||||
mListener.onMultiUserSwitchChanged(isChecked);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import android.content.pm.UserInfo;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
|
||||
@@ -31,13 +32,15 @@ public class UserCapabilities {
|
||||
boolean mCanAddRestrictedProfile = true;
|
||||
boolean mIsAdmin;
|
||||
boolean mIsGuest;
|
||||
boolean mUserSwitcherEnabled;
|
||||
boolean mCanAddGuest;
|
||||
boolean mDisallowAddUser;
|
||||
boolean mDisallowAddUserSetByAdmin;
|
||||
boolean mDisallowSwitchUser;
|
||||
RestrictedLockUtils.EnforcedAdmin mEnforcedAdmin;
|
||||
|
||||
private UserCapabilities() {}
|
||||
private UserCapabilities() {
|
||||
}
|
||||
|
||||
public static UserCapabilities create(Context context) {
|
||||
UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
|
||||
@@ -62,14 +65,15 @@ public class UserCapabilities {
|
||||
}
|
||||
|
||||
public void updateAddUserCapabilities(Context context) {
|
||||
final UserManager userManager =
|
||||
(UserManager) context.getSystemService(Context.USER_SERVICE);
|
||||
mEnforcedAdmin = RestrictedLockUtils.checkIfRestrictionEnforced(context,
|
||||
UserManager.DISALLOW_ADD_USER, UserHandle.myUserId());
|
||||
final boolean hasBaseUserRestriction = RestrictedLockUtils.hasBaseUserRestriction(
|
||||
context, UserManager.DISALLOW_ADD_USER, UserHandle.myUserId());
|
||||
mDisallowAddUserSetByAdmin =
|
||||
mEnforcedAdmin != null && !hasBaseUserRestriction;
|
||||
mDisallowAddUser =
|
||||
(mEnforcedAdmin != null || hasBaseUserRestriction);
|
||||
mDisallowAddUserSetByAdmin = mEnforcedAdmin != null && !hasBaseUserRestriction;
|
||||
mDisallowAddUser = (mEnforcedAdmin != null || hasBaseUserRestriction);
|
||||
mUserSwitcherEnabled = userManager.isUserSwitcherEnabled();
|
||||
mCanAddUser = true;
|
||||
if (!mIsAdmin || UserManager.getMaxSupportedUsers() < 2
|
||||
|| !UserManager.supportsMultipleUsers()
|
||||
@@ -81,7 +85,6 @@ public class UserCapabilities {
|
||||
context.getContentResolver(), Settings.Global.ADD_USERS_WHEN_LOCKED, 0) == 1;
|
||||
mCanAddGuest = !mIsGuest && !mDisallowAddUser && canAddUsersWhenLocked;
|
||||
|
||||
UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
|
||||
mDisallowSwitchUser = userManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH);
|
||||
}
|
||||
|
||||
|
||||
@@ -48,13 +48,13 @@ import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.SimpleAdapter;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.internal.util.UserIcons;
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
@@ -62,6 +62,8 @@ import com.android.settings.dashboard.SummaryLoader;
|
||||
import com.android.settings.password.ChooseLockGeneric;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settings.search.Indexable;
|
||||
import com.android.settings.widget.SwitchBar;
|
||||
import com.android.settings.widget.SwitchBarController;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||
import com.android.settingslib.RestrictedPreference;
|
||||
@@ -78,7 +80,6 @@ import java.util.List;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.annotation.WorkerThread;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.Preference.OnPreferenceClickListener;
|
||||
import androidx.preference.PreferenceGroup;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
@@ -92,7 +93,9 @@ import androidx.preference.PreferenceScreen;
|
||||
*/
|
||||
@SearchIndexable
|
||||
public class UserSettings extends SettingsPreferenceFragment
|
||||
implements OnPreferenceClickListener, OnClickListener, DialogInterface.OnDismissListener,
|
||||
implements Preference.OnPreferenceClickListener, View.OnClickListener,
|
||||
MultiUserSwitchBarController.OnMultiUserSwitchChangedListener,
|
||||
DialogInterface.OnDismissListener,
|
||||
EditUserInfoController.OnContentChangedCallback, Indexable {
|
||||
|
||||
private static final String TAG = "UserSettings";
|
||||
@@ -155,8 +158,10 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
private SparseArray<Bitmap> mUserIcons = new SparseArray<>();
|
||||
private static SparseArray<Bitmap> sDarkDefaultUserBitmapCache = new SparseArray<>();
|
||||
|
||||
private MultiUserSwitchBarController mSwitchBarController;
|
||||
private EditUserInfoController mEditUserInfoController = new EditUserInfoController();
|
||||
private AddUserWhenLockedPreferenceController mAddUserWhenLockedPreferenceController;
|
||||
private MultiUserFooterPreferenceController mMultiUserFooterPreferenceController;
|
||||
|
||||
// A place to cache the generated default avatar
|
||||
private Drawable mDefaultIconDrawable;
|
||||
@@ -198,20 +203,37 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
return MetricsEvent.USER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
// Assume we are in a SettingsActivity. This is only safe because we currently use
|
||||
// SettingsActivity as base for all preference fragments.
|
||||
final SettingsActivity activity = (SettingsActivity) getActivity();
|
||||
final SwitchBar switchBar = activity.getSwitchBar();
|
||||
mSwitchBarController = new MultiUserSwitchBarController(activity,
|
||||
new SwitchBarController(switchBar), this /* listener */);
|
||||
getLifecycle().addObserver(mSwitchBarController);
|
||||
switchBar.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
addPreferencesFromResource(R.xml.user_settings);
|
||||
final Activity activity = getActivity();
|
||||
if (!Utils.isDeviceProvisioned(getActivity())) {
|
||||
if (!Utils.isDeviceProvisioned(activity)) {
|
||||
activity.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
mAddUserWhenLockedPreferenceController = new AddUserWhenLockedPreferenceController(
|
||||
activity, KEY_ADD_USER_WHEN_LOCKED, getLifecycle());
|
||||
activity, KEY_ADD_USER_WHEN_LOCKED);
|
||||
mMultiUserFooterPreferenceController = new MultiUserFooterPreferenceController(activity)
|
||||
.setFooterMixin(mFooterPreferenceMixin);
|
||||
|
||||
final PreferenceScreen screen = getPreferenceScreen();
|
||||
mAddUserWhenLockedPreferenceController.displayPreference(screen);
|
||||
mMultiUserFooterPreferenceController.displayPreference(screen);
|
||||
|
||||
screen.findPreference(mAddUserWhenLockedPreferenceController.getPreferenceKey())
|
||||
.setOnPreferenceChangeListener(mAddUserWhenLockedPreferenceController);
|
||||
@@ -246,7 +268,7 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
mAddUser = (RestrictedPreference) findPreference(KEY_ADD_USER);
|
||||
mAddUser.useAdminDisabledSummary(false);
|
||||
// Determine if add user/profile button should be visible
|
||||
if (mUserCaps.mCanAddUser && Utils.isDeviceProvisioned(getActivity())) {
|
||||
if (mUserCaps.mCanAddUser && Utils.isDeviceProvisioned(activity)) {
|
||||
mAddUser.setVisible(true);
|
||||
mAddUser.setOnPreferenceClickListener(this);
|
||||
// change label to only mention user, if restricted profiles are not supported
|
||||
@@ -260,8 +282,7 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
activity.registerReceiverAsUser(
|
||||
mUserChangeReceiver, UserHandle.ALL, USER_REMOVED_INTENT_FILTER, null, mHandler);
|
||||
|
||||
loadProfile();
|
||||
updateUserList();
|
||||
updateUI();
|
||||
mShouldUpdateUserList = false;
|
||||
}
|
||||
|
||||
@@ -280,9 +301,7 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
}
|
||||
|
||||
if (mShouldUpdateUserList) {
|
||||
mUserCaps.updateAddUserCapabilities(getActivity());
|
||||
loadProfile();
|
||||
updateUserList();
|
||||
updateUI();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,6 +362,17 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMultiUserSwitchChanged(boolean newState) {
|
||||
updateUI();
|
||||
}
|
||||
|
||||
private void updateUI() {
|
||||
mUserCaps.updateAddUserCapabilities(getActivity());
|
||||
loadProfile();
|
||||
updateUserList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads profile information for the current user.
|
||||
*/
|
||||
@@ -909,8 +939,6 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
loadIconsAsync(missingIcons);
|
||||
}
|
||||
|
||||
// Remove everything from mUserListCategory and add new users.
|
||||
mUserListCategory.removeAll();
|
||||
// If profiles are supported, mUserListCategory will have a special title
|
||||
if (mUserCaps.mCanAddRestrictedProfile) {
|
||||
mUserListCategory.setTitle(R.string.user_list_title);
|
||||
@@ -918,6 +946,20 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
mUserListCategory.setTitle(null);
|
||||
}
|
||||
|
||||
// Remove everything from mUserListCategory and add new users.
|
||||
mUserListCategory.removeAll();
|
||||
|
||||
// If multi-user is disabled, just show footer and return.
|
||||
final Preference addUserOnLockScreen = getPreferenceScreen().findPreference(
|
||||
mAddUserWhenLockedPreferenceController.getPreferenceKey());
|
||||
mAddUserWhenLockedPreferenceController.updateState(addUserOnLockScreen);
|
||||
mMultiUserFooterPreferenceController.updateState(null /* preference */);
|
||||
mAddUser.setVisible(mUserCaps.mUserSwitcherEnabled);
|
||||
mUserListCategory.setVisible(mUserCaps.mUserSwitcherEnabled);
|
||||
if (!mUserCaps.mUserSwitcherEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (UserPreference userPreference : userPreferences) {
|
||||
userPreference.setOrder(Preference.DEFAULT_ORDER);
|
||||
mUserListCategory.addPreference(userPreference);
|
||||
@@ -925,7 +967,7 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
|
||||
// Append Add user to the end of the list
|
||||
if ((mUserCaps.mCanAddUser || mUserCaps.mDisallowAddUserSetByAdmin) &&
|
||||
Utils.isDeviceProvisioned(getActivity())) {
|
||||
Utils.isDeviceProvisioned(context)) {
|
||||
boolean moreUsers = mUserManager.canAddMoreUsers();
|
||||
mAddUser.setEnabled(moreUsers && !mAddingUser);
|
||||
if (!moreUsers) {
|
||||
@@ -938,7 +980,6 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
mUserCaps.mDisallowAddUser ? mUserCaps.mEnforcedAdmin : null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private int getMaxRealUsers() {
|
||||
@@ -1190,8 +1231,7 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
@Override
|
||||
public List<String> getNonIndexableKeysFromXml(Context context, int xmlResId) {
|
||||
final List<String> niks = super.getNonIndexableKeysFromXml(context, xmlResId);
|
||||
new AddUserWhenLockedPreferenceController(
|
||||
context, KEY_ADD_USER_WHEN_LOCKED, null /* lifecycle */)
|
||||
new AddUserWhenLockedPreferenceController(context, KEY_ADD_USER_WHEN_LOCKED)
|
||||
.updateNonIndexableKeys(niks);
|
||||
new AutoSyncDataPreferenceController(context, null /* parent */)
|
||||
.updateNonIndexableKeys(niks);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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
|
||||
@@ -11,11 +12,9 @@
|
||||
* 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.graph;
|
||||
package com.android.settings.widget;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
@@ -1,18 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of the License at
|
||||
* 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.
|
||||
* 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.graph;
|
||||
package com.android.settings.widget;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
@@ -1,18 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of the License at
|
||||
* 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.
|
||||
* 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.graph;
|
||||
package com.android.settings.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
@@ -24,6 +26,7 @@ import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.settingslib.R;
|
||||
|
||||
public class UsageView extends FrameLayout {
|
||||
@@ -7,7 +7,6 @@ com.android.settings.accounts.AccountDetailDashboardFragment
|
||||
com.android.settings.accounts.ManagedProfileSettings
|
||||
com.android.settings.fuelgauge.PowerUsageAnomalyDetails
|
||||
com.android.settings.fuelgauge.AdvancedPowerUsageDetail
|
||||
com.android.settings.datausage.DataUsageSummaryLegacy
|
||||
com.android.settings.development.featureflags.FeatureFlagsDashboard
|
||||
com.android.settings.development.qstile.DevelopmentTileConfigFragment
|
||||
com.android.settings.deviceinfo.StorageProfileFragment
|
||||
|
||||
@@ -36,17 +36,21 @@ import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.usage.IUsageStatsManager;
|
||||
import android.app.usage.UsageEvents;
|
||||
import android.app.usage.UsageEvents.Event;
|
||||
import android.app.usage.UsageStatsManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.os.Looper;
|
||||
import android.os.Parcel;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Switch;
|
||||
|
||||
@@ -79,7 +83,9 @@ public class AppStateNotificationBridgeTest {
|
||||
@Mock
|
||||
private ApplicationsState mState;
|
||||
@Mock
|
||||
private UsageStatsManager mUsageStats;
|
||||
private IUsageStatsManager mUsageStats;
|
||||
@Mock
|
||||
private UserManager mUserManager;
|
||||
@Mock
|
||||
private NotificationBackend mBackend;
|
||||
private Context mContext;
|
||||
@@ -92,10 +98,12 @@ public class AppStateNotificationBridgeTest {
|
||||
when(mState.getBackgroundLooper()).thenReturn(mock(Looper.class));
|
||||
when(mBackend.getNotificationsBanned(anyString(), anyInt())).thenReturn(true);
|
||||
when(mBackend.isSystemApp(any(), any())).thenReturn(true);
|
||||
// most tests assume no work profile
|
||||
when(mUserManager.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[]{});
|
||||
mContext = RuntimeEnvironment.application.getApplicationContext();
|
||||
|
||||
mBridge = new AppStateNotificationBridge(mContext, mState,
|
||||
mock(AppStateBaseBridge.Callback.class), mUsageStats, mBackend);
|
||||
mock(AppStateBaseBridge.Callback.class), mUsageStats, mUserManager, mBackend);
|
||||
}
|
||||
|
||||
private AppEntry getMockAppEntry(String pkg) {
|
||||
@@ -115,14 +123,15 @@ public class AppStateNotificationBridgeTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAggregatedUsageEvents_noEvents() {
|
||||
when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(mock(UsageEvents.class));
|
||||
public void testGetAggregatedUsageEvents_noEvents() throws Exception {
|
||||
when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString()))
|
||||
.thenReturn(mock(UsageEvents.class));
|
||||
|
||||
assertThat(mBridge.getAggregatedUsageEvents()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAggregatedUsageEvents_onlyNotificationEvents() {
|
||||
public void testGetAggregatedUsageEvents_onlyNotificationEvents() throws Exception {
|
||||
List<Event> events = new ArrayList<>();
|
||||
Event good = new Event();
|
||||
good.mEventType = Event.NOTIFICATION_INTERRUPTION;
|
||||
@@ -136,14 +145,15 @@ public class AppStateNotificationBridgeTest {
|
||||
events.add(bad);
|
||||
|
||||
UsageEvents usageEvents = getUsageEvents(events);
|
||||
when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(usageEvents);
|
||||
when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString()))
|
||||
.thenReturn(usageEvents);
|
||||
|
||||
Map<String, NotificationsSentState> map = mBridge.getAggregatedUsageEvents();
|
||||
assertThat(map.get(PKG1).sentCount).isEqualTo(1);
|
||||
assertThat(map.get(mBridge.getKey(0, PKG1)).sentCount).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAggregatedUsageEvents_multipleEventsAgg() {
|
||||
public void testGetAggregatedUsageEvents_multipleEventsAgg() throws Exception {
|
||||
List<Event> events = new ArrayList<>();
|
||||
Event good = new Event();
|
||||
good.mEventType = Event.NOTIFICATION_INTERRUPTION;
|
||||
@@ -157,15 +167,16 @@ public class AppStateNotificationBridgeTest {
|
||||
events.add(good1);
|
||||
|
||||
UsageEvents usageEvents = getUsageEvents(events);
|
||||
when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(usageEvents);
|
||||
when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString()))
|
||||
.thenReturn(usageEvents);
|
||||
|
||||
Map<String, NotificationsSentState> map = mBridge.getAggregatedUsageEvents();
|
||||
assertThat(map.get(PKG1).sentCount).isEqualTo(2);
|
||||
assertThat(map.get(PKG1).lastSent).isEqualTo(6);
|
||||
assertThat(map.get(mBridge.getKey(0, PKG1)).sentCount).isEqualTo(2);
|
||||
assertThat(map.get(mBridge.getKey(0, PKG1)).lastSent).isEqualTo(6);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAggregatedUsageEvents_multiplePkgs() {
|
||||
public void testGetAggregatedUsageEvents_multiplePkgs() throws Exception {
|
||||
List<Event> events = new ArrayList<>();
|
||||
Event good = new Event();
|
||||
good.mEventType = Event.NOTIFICATION_INTERRUPTION;
|
||||
@@ -179,19 +190,21 @@ public class AppStateNotificationBridgeTest {
|
||||
events.add(good1);
|
||||
|
||||
UsageEvents usageEvents = getUsageEvents(events);
|
||||
when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(usageEvents);
|
||||
when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString()))
|
||||
.thenReturn(usageEvents);
|
||||
|
||||
Map<String, NotificationsSentState> map
|
||||
= mBridge.getAggregatedUsageEvents();
|
||||
assertThat(map.get(PKG1).sentCount).isEqualTo(1);
|
||||
assertThat(map.get(PKG2).sentCount).isEqualTo(1);
|
||||
assertThat(map.get(PKG1).lastSent).isEqualTo(6);
|
||||
assertThat(map.get(PKG2).lastSent).isEqualTo(1);
|
||||
assertThat(map.get(mBridge.getKey(0, PKG1)).sentCount).isEqualTo(1);
|
||||
assertThat(map.get(mBridge.getKey(0, PKG2)).sentCount).isEqualTo(1);
|
||||
assertThat(map.get(mBridge.getKey(0, PKG1)).lastSent).isEqualTo(6);
|
||||
assertThat(map.get(mBridge.getKey(0, PKG2)).lastSent).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadAllExtraInfo_noEvents() {
|
||||
when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(mock(UsageEvents.class));
|
||||
public void testLoadAllExtraInfo_noEvents() throws RemoteException {
|
||||
when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString()))
|
||||
.thenReturn(mock(UsageEvents.class));
|
||||
ArrayList<AppEntry> apps = new ArrayList<>();
|
||||
apps.add(getMockAppEntry(PKG1));
|
||||
when(mSession.getAllApps()).thenReturn(apps);
|
||||
@@ -201,7 +214,7 @@ public class AppStateNotificationBridgeTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadAllExtraInfo_multipleEventsAgg() {
|
||||
public void testLoadAllExtraInfo_multipleEventsAgg() throws RemoteException {
|
||||
List<Event> events = new ArrayList<>();
|
||||
for (int i = 0; i < 7; i++) {
|
||||
Event good = new Event();
|
||||
@@ -212,7 +225,8 @@ public class AppStateNotificationBridgeTest {
|
||||
}
|
||||
|
||||
UsageEvents usageEvents = getUsageEvents(events);
|
||||
when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(usageEvents);
|
||||
when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString()))
|
||||
.thenReturn(usageEvents);
|
||||
|
||||
ArrayList<AppEntry> apps = new ArrayList<>();
|
||||
apps.add(getMockAppEntry(PKG1));
|
||||
@@ -229,7 +243,7 @@ public class AppStateNotificationBridgeTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadAllExtraInfo_multiplePkgs() {
|
||||
public void testLoadAllExtraInfo_multiplePkgs() throws RemoteException {
|
||||
List<Event> events = new ArrayList<>();
|
||||
for (int i = 0; i < 8; i++) {
|
||||
Event good = new Event();
|
||||
@@ -245,7 +259,8 @@ public class AppStateNotificationBridgeTest {
|
||||
events.add(good1);
|
||||
|
||||
UsageEvents usageEvents = getUsageEvents(events);
|
||||
when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(usageEvents);
|
||||
when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString()))
|
||||
.thenReturn(usageEvents);
|
||||
|
||||
ArrayList<AppEntry> apps = new ArrayList<>();
|
||||
apps.add(getMockAppEntry(PKG1));
|
||||
@@ -265,8 +280,66 @@ public class AppStateNotificationBridgeTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateExtraInfo_noEvents() {
|
||||
when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(mock(UsageEvents.class));
|
||||
public void testLoadAllExtraInfo_multipleUsers() throws RemoteException {
|
||||
// has work profile
|
||||
when(mUserManager.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[]{1});
|
||||
mBridge = new AppStateNotificationBridge(mContext, mState,
|
||||
mock(AppStateBaseBridge.Callback.class), mUsageStats, mUserManager, mBackend);
|
||||
|
||||
List<Event> eventsProfileOwner = new ArrayList<>();
|
||||
for (int i = 0; i < 8; i++) {
|
||||
Event good = new Event();
|
||||
good.mEventType = Event.NOTIFICATION_INTERRUPTION;
|
||||
good.mPackage = PKG1;
|
||||
good.mTimeStamp = i;
|
||||
eventsProfileOwner.add(good);
|
||||
}
|
||||
|
||||
List<Event> eventsProfile = new ArrayList<>();
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Event good = new Event();
|
||||
good.mEventType = Event.NOTIFICATION_INTERRUPTION;
|
||||
good.mPackage = PKG1;
|
||||
good.mTimeStamp = i;
|
||||
eventsProfile.add(good);
|
||||
}
|
||||
|
||||
UsageEvents usageEventsOwner = getUsageEvents(eventsProfileOwner);
|
||||
when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), eq(0), anyString()))
|
||||
.thenReturn(usageEventsOwner);
|
||||
|
||||
UsageEvents usageEventsProfile = getUsageEvents(eventsProfile);
|
||||
when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), eq(1), anyString()))
|
||||
.thenReturn(usageEventsProfile);
|
||||
|
||||
ArrayList<AppEntry> apps = new ArrayList<>();
|
||||
AppEntry owner = getMockAppEntry(PKG1);
|
||||
owner.info.uid = 1;
|
||||
apps.add(owner);
|
||||
|
||||
AppEntry profile = getMockAppEntry(PKG1);
|
||||
profile.info.uid = UserHandle.PER_USER_RANGE + 1;
|
||||
apps.add(profile);
|
||||
when(mSession.getAllApps()).thenReturn(apps);
|
||||
|
||||
mBridge.loadAllExtraInfo();
|
||||
|
||||
assertThat(((NotificationsSentState) apps.get(0).extraInfo).sentCount).isEqualTo(8);
|
||||
assertThat(((NotificationsSentState) apps.get(0).extraInfo).lastSent).isEqualTo(7);
|
||||
assertThat(((NotificationsSentState) apps.get(0).extraInfo).avgSentWeekly).isEqualTo(0);
|
||||
assertThat(((NotificationsSentState) apps.get(0).extraInfo).avgSentDaily).isEqualTo(1);
|
||||
|
||||
assertThat(((NotificationsSentState) apps.get(1).extraInfo).sentCount).isEqualTo(4);
|
||||
assertThat(((NotificationsSentState) apps.get(1).extraInfo).lastSent).isEqualTo(3);
|
||||
assertThat(((NotificationsSentState) apps.get(1).extraInfo).avgSentWeekly).isEqualTo(4);
|
||||
assertThat(((NotificationsSentState) apps.get(1).extraInfo).avgSentDaily).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateExtraInfo_noEvents() throws RemoteException {
|
||||
when(mUsageStats.queryEventsForPackageForUser(
|
||||
anyLong(), anyLong(), anyInt(), anyString(), anyString()))
|
||||
.thenReturn(mock(UsageEvents.class));
|
||||
AppEntry entry = getMockAppEntry(PKG1);
|
||||
|
||||
mBridge.updateExtraInfo(entry, "", 0);
|
||||
@@ -274,7 +347,7 @@ public class AppStateNotificationBridgeTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateExtraInfo_multipleEventsAgg() {
|
||||
public void testUpdateExtraInfo_multipleEventsAgg() throws RemoteException {
|
||||
List<Event> events = new ArrayList<>();
|
||||
for (int i = 0; i < 13; i++) {
|
||||
Event good = new Event();
|
||||
@@ -285,7 +358,8 @@ public class AppStateNotificationBridgeTest {
|
||||
}
|
||||
|
||||
UsageEvents usageEvents = getUsageEvents(events);
|
||||
when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(usageEvents);
|
||||
when(mUsageStats.queryEventsForPackageForUser(
|
||||
anyLong(), anyLong(), anyInt(), anyString(), anyString())).thenReturn(usageEvents);
|
||||
|
||||
AppEntry entry = getMockAppEntry(PKG1);
|
||||
mBridge.updateExtraInfo(entry, "", 0);
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
|
||||
package com.android.settings.applications.manageapplications;
|
||||
|
||||
import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_DRAGGING;
|
||||
import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE;
|
||||
import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_ALL;
|
||||
import static com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_MAIN;
|
||||
import static com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_NOTIFICATION;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static com.android.settings.applications.manageapplications.AppFilterRegistry
|
||||
.FILTER_APPS_ALL;
|
||||
import static com.android.settings.applications.manageapplications.ManageApplications
|
||||
.LIST_TYPE_MAIN;
|
||||
import static com.android.settings.applications.manageapplications.ManageApplications
|
||||
.LIST_TYPE_NOTIFICATION;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.Matchers.any;
|
||||
@@ -36,11 +36,14 @@ import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_DRAGGING;
|
||||
import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.os.Looper;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import android.os.UserManager;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
@@ -63,6 +66,8 @@ import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class ManageApplicationsTest {
|
||||
|
||||
@@ -272,6 +277,10 @@ public class ManageApplicationsTest {
|
||||
@Test
|
||||
public void applicationsAdapter_onBindViewHolder_updateSwitch_notifications() {
|
||||
ManageApplications manageApplications = mock(ManageApplications.class);
|
||||
when(manageApplications.getActivity()).thenReturn(mock(Activity.class));
|
||||
UserManager um = mock(UserManager.class);
|
||||
when(um.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[]{});
|
||||
ReflectionHelpers.setField(manageApplications, "mUserManager", um);
|
||||
manageApplications.mListType = LIST_TYPE_NOTIFICATION;
|
||||
ApplicationViewHolder holder = mock(ApplicationViewHolder.class);
|
||||
ReflectionHelpers.setField(holder, "itemView", mock(View.class));
|
||||
@@ -293,6 +302,9 @@ public class ManageApplicationsTest {
|
||||
manageApplications.mListType = LIST_TYPE_MAIN;
|
||||
ApplicationViewHolder holder = mock(ApplicationViewHolder.class);
|
||||
ReflectionHelpers.setField(holder, "itemView", mock(View.class));
|
||||
UserManager um = mock(UserManager.class);
|
||||
when(um.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[]{});
|
||||
ReflectionHelpers.setField(manageApplications, "mUserManager", um);
|
||||
ManageApplications.ApplicationsAdapter adapter =
|
||||
new ManageApplications.ApplicationsAdapter(mState,
|
||||
manageApplications, mock(AppFilterItem.class),
|
||||
@@ -308,6 +320,10 @@ public class ManageApplicationsTest {
|
||||
@Test
|
||||
public void sortOrderSavedOnRebuild() {
|
||||
ManageApplications manageApplications = mock(ManageApplications.class);
|
||||
when(manageApplications.getActivity()).thenReturn(mock(Activity.class));
|
||||
UserManager um = mock(UserManager.class);
|
||||
when(um.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[]{});
|
||||
ReflectionHelpers.setField(manageApplications, "mUserManager", um);
|
||||
manageApplications.mListType = LIST_TYPE_NOTIFICATION;
|
||||
manageApplications.mSortOrder = -1;
|
||||
ManageApplications.ApplicationsAdapter adapter =
|
||||
|
||||
@@ -22,10 +22,8 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.util.FeatureFlagUtils;
|
||||
|
||||
import com.android.settings.Settings;
|
||||
import com.android.settings.core.FeatureFlags;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -51,9 +49,7 @@ public class BackgroundDataConditionTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPrimaryClick_v2enabled_shouldReturn2SummaryActivity() {
|
||||
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.DATA_USAGE_SETTINGS_V2, true);
|
||||
|
||||
public void onPrimaryClick_shouldReturn2SummaryActivity() {
|
||||
final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class);
|
||||
BackgroundDataCondition backgroundDataCondition
|
||||
= new BackgroundDataCondition(mConditionManager);
|
||||
@@ -64,19 +60,4 @@ public class BackgroundDataConditionTest {
|
||||
assertThat(intent.getComponent().getClassName()).isEqualTo(
|
||||
Settings.DataUsageSummaryActivity.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPrimaryClick_v2disabled_shouldReturnLegacySummaryActivity() {
|
||||
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.DATA_USAGE_SETTINGS_V2, false);
|
||||
|
||||
final ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class);
|
||||
BackgroundDataCondition backgroundDataCondition
|
||||
= new BackgroundDataCondition(mConditionManager);
|
||||
backgroundDataCondition.onPrimaryClick();
|
||||
verify(mContext).startActivity(argumentCaptor.capture());
|
||||
Intent intent = argumentCaptor.getValue();
|
||||
|
||||
assertThat(intent.getComponent().getClassName()).isEqualTo(
|
||||
Settings.DataUsageSummaryLegacyActivity.class.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,12 +31,7 @@ import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.SwitchPreference;
|
||||
import android.util.FeatureFlagUtils;
|
||||
|
||||
import com.android.settings.core.FeatureFlags;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settingslib.NetworkPolicyEditor;
|
||||
|
||||
@@ -47,6 +42,10 @@ import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.SwitchPreference;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class BillingCycleSettingsTest {
|
||||
|
||||
@@ -108,14 +107,12 @@ public class BillingCycleSettingsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataUsageSummary_shouldBeNullWithV2() {
|
||||
public void testDataUsageSummary_shouldBeNull() {
|
||||
final BillingCycleSettings billingCycleSettings = spy(new BillingCycleSettings());
|
||||
when(billingCycleSettings.getContext()).thenReturn(mContext);
|
||||
billingCycleSettings.setUpForTest(mNetworkPolicyEditor, mBillingCycle,
|
||||
mDataLimit, mDataWarning, mEnableDataLimit, mEnableDataWarning);
|
||||
|
||||
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.DATA_USAGE_SETTINGS_V2, true);
|
||||
|
||||
doReturn("some-string").when(billingCycleSettings).getString(anyInt(), anyInt());
|
||||
when(mNetworkPolicyEditor.getPolicyCycleDay(anyObject())).thenReturn(CYCLE_NONE + 1);
|
||||
when(mNetworkPolicyEditor.getPolicyLimitBytes(anyObject())).thenReturn(2000L);
|
||||
|
||||
@@ -25,8 +25,10 @@ import android.content.Context;
|
||||
import android.net.NetworkStatsHistory;
|
||||
import android.net.NetworkStatsHistory.Entry;
|
||||
import android.util.SparseIntArray;
|
||||
import com.android.settings.graph.UsageView;
|
||||
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.widget.UsageView;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -65,7 +67,7 @@ public class ChartDataUsagePreferenceTest {
|
||||
when(mNetworkStatsHistory.getIndexAfter(end)).thenReturn(7);
|
||||
final UsageView usageView = mock(UsageView.class);
|
||||
final ArgumentCaptor<SparseIntArray> pointsCaptor =
|
||||
ArgumentCaptor.forClass(SparseIntArray.class);
|
||||
ArgumentCaptor.forClass(SparseIntArray.class);
|
||||
|
||||
mPreference.calcPoints(usageView);
|
||||
|
||||
@@ -84,7 +86,7 @@ public class ChartDataUsagePreferenceTest {
|
||||
when(mNetworkStatsHistory.getIndexAfter(end)).thenReturn(5);
|
||||
final UsageView usageView = mock(UsageView.class);
|
||||
final ArgumentCaptor<SparseIntArray> pointsCaptor =
|
||||
ArgumentCaptor.forClass(SparseIntArray.class);
|
||||
ArgumentCaptor.forClass(SparseIntArray.class);
|
||||
|
||||
mPreference.calcPoints(usageView);
|
||||
|
||||
@@ -113,9 +115,10 @@ public class ChartDataUsagePreferenceTest {
|
||||
* Create a network entry to be used to calculate the usage chart. In the calculation, we only
|
||||
* need bucketStart, total bytes (rx + tx), and bucketDuration (which is set when we create
|
||||
* the NetworkStatsHistory object). Other fields are ignored, so we don't initialize here.
|
||||
*
|
||||
* @param start the timestamp when this entry begins
|
||||
* @param rx the total number of received bytes
|
||||
* @param tx the total number of transmitted bytes
|
||||
* @param rx the total number of received bytes
|
||||
* @param tx the total number of transmitted bytes
|
||||
* @return the network entry with the corresponding start time and data usage
|
||||
*/
|
||||
private Entry createEntry(long start, long rx, long tx) {
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License
|
||||
*/
|
||||
|
||||
package com.android.settings.datausage;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.text.format.Formatter;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.testutils.shadow.SettingsShadowResources;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.shadows.ShadowApplication;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class DataUsageSummaryLegacyTest {
|
||||
|
||||
@Mock
|
||||
private ConnectivityManager mManager;
|
||||
private Context mContext;
|
||||
|
||||
/**
|
||||
* This set up is contrived to get a passing test so that the build doesn't block without tests.
|
||||
* These tests should be updated as code gets refactored to improve testability.
|
||||
*/
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
ShadowApplication shadowContext = ShadowApplication.getInstance();
|
||||
shadowContext.setSystemService(Context.CONNECTIVITY_SERVICE, mManager);
|
||||
mContext = shadowContext.getApplicationContext();
|
||||
when(mManager.isNetworkSupported(anyInt())).thenReturn(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void formatUsage_shouldLookLikeFormatFileSize() {
|
||||
SettingsShadowResources
|
||||
.overrideResource(com.android.internal.R.string.fileSizeSuffix, "%1$s %2$s");
|
||||
final long usage = 2147483648L; // 2GB
|
||||
final String formattedUsage =
|
||||
DataUsageSummaryLegacy.formatUsage(mContext, "^1", usage).toString();
|
||||
final String formattedAsFileSize = Formatter.formatFileSize(mContext, usage);
|
||||
assertThat(formattedUsage).isEqualTo(formattedAsFileSize);
|
||||
}
|
||||
}
|
||||
@@ -23,15 +23,14 @@ import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.graph.UsageView;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.testutils.shadow.SettingsShadowResources;
|
||||
import com.android.settings.widget.UsageView;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -41,6 +40,8 @@ import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(shadows = SettingsShadowResources.SettingsShadowTheme.class)
|
||||
public class BatteryHistoryPreferenceTest {
|
||||
@@ -63,7 +64,7 @@ public class BatteryHistoryPreferenceTest {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
final Context context = RuntimeEnvironment.application;
|
||||
final View itemView =
|
||||
LayoutInflater.from(context).inflate(R.layout.battery_usage_graph, null);
|
||||
LayoutInflater.from(context).inflate(R.layout.battery_usage_graph, null);
|
||||
|
||||
mBatteryHistoryPreference = new BatteryHistoryPreference(context, null);
|
||||
mBatteryHistoryPreference.mBatteryInfo = mBatteryInfo;
|
||||
|
||||
@@ -36,12 +36,11 @@ import android.os.BatteryStats;
|
||||
import android.os.SystemClock;
|
||||
import android.util.SparseIntArray;
|
||||
|
||||
import com.android.settings.graph.UsageView;
|
||||
import com.android.settings.testutils.BatteryTestUtils;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.widget.UsageView;
|
||||
import com.android.settingslib.R;
|
||||
import com.android.settingslib.utils.PowerUtil;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -172,7 +171,8 @@ public class BatteryInfoTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetBatteryInfo_basedOnUsageTrueBetweenSevenAndFifteenMinutes_usesCorrectString() {
|
||||
public void
|
||||
testGetBatteryInfo_basedOnUsageTrueBetweenSevenAndFifteenMinutes_usesCorrectString() {
|
||||
Estimate estimate = new Estimate(Duration.ofMinutes(10).toMillis(),
|
||||
true /* isBasedOnUsage */,
|
||||
1000 /* averageDischargeTime */);
|
||||
|
||||
@@ -16,14 +16,25 @@
|
||||
|
||||
package com.android.settings.gestures;
|
||||
|
||||
import static android.provider.Settings.Secure.VOLUME_HUSH_GESTURE;
|
||||
import static android.provider.Settings.Secure.VOLUME_HUSH_MUTE;
|
||||
import static android.provider.Settings.Secure.VOLUME_HUSH_OFF;
|
||||
import static android.provider.Settings.Secure.VOLUME_HUSH_VIBRATE;
|
||||
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -41,18 +52,20 @@ public class PreventRingingParentPreferenceControllerTest {
|
||||
|
||||
private Context mContext;
|
||||
private PreventRingingParentPreferenceController mController;
|
||||
private final String VIBRATE_SUMMARY = "On (vibrate)";
|
||||
private final String MUTE_SUMMARY = "On (mute)";
|
||||
private final String NONE_SUMMARY = "Off";
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
when(mContext.getResources()).thenReturn(mResources);
|
||||
|
||||
mContext = spy(RuntimeEnvironment.application.getApplicationContext());
|
||||
mController = new PreventRingingParentPreferenceController(mContext, "test_key");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAvailable_configIsTrue_shouldAvailableUnSearchable() {
|
||||
when(mContext.getResources()).thenReturn(mResources);
|
||||
when(mResources.getBoolean(
|
||||
com.android.internal.R.bool.config_volumeHushGestureEnabled)).thenReturn(true);
|
||||
|
||||
@@ -61,9 +74,28 @@ public class PreventRingingParentPreferenceControllerTest {
|
||||
|
||||
@Test
|
||||
public void testIsAvailable_configIsFalse_shouldReturnFalse() {
|
||||
when(mContext.getResources()).thenReturn(mResources);
|
||||
when(mResources.getBoolean(
|
||||
com.android.internal.R.bool.config_volumeHushGestureEnabled)).thenReturn(false);
|
||||
|
||||
assertThat(mController.isAvailable()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_summaryUpdated() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), VOLUME_HUSH_GESTURE,
|
||||
VOLUME_HUSH_MUTE);
|
||||
assertThat(mController.getSummary()).isEqualTo(mContext.getResources().getText(
|
||||
R.string.prevent_ringing_option_mute_summary));
|
||||
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), VOLUME_HUSH_GESTURE,
|
||||
VOLUME_HUSH_VIBRATE);
|
||||
assertThat(mController.getSummary()).isEqualTo(mContext.getResources().getText(
|
||||
R.string.prevent_ringing_option_vibrate_summary));
|
||||
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), VOLUME_HUSH_GESTURE,
|
||||
VOLUME_HUSH_OFF);
|
||||
assertThat(mController.getSummary()).isEqualTo(mContext.getResources().getText(
|
||||
R.string.prevent_ringing_option_none_summary));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,29 +87,6 @@ public class PreventRingingPreferenceControllerTest {
|
||||
assertThat(mController.isAvailable()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSummary_mute() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.VOLUME_HUSH_GESTURE,
|
||||
Settings.Secure.VOLUME_HUSH_MUTE);
|
||||
assertEquals(mContext.getString(R.string.prevent_ringing_option_mute_summary),
|
||||
mController.getSummary());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSummary_vibrate() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.VOLUME_HUSH_GESTURE,
|
||||
Settings.Secure.VOLUME_HUSH_VIBRATE);
|
||||
assertEquals(mContext.getString(R.string.prevent_ringing_option_vibrate_summary),
|
||||
mController.getSummary());
|
||||
}
|
||||
@Test
|
||||
public void testGetSummary_other() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.VOLUME_HUSH_GESTURE,
|
||||
7);
|
||||
assertEquals(mContext.getString(R.string.prevent_ringing_option_none_summary),
|
||||
mController.getSummary());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateState_mute() {
|
||||
ListPreference pref = mock(ListPreference.class);
|
||||
|
||||
@@ -47,6 +47,8 @@ public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager
|
||||
private final Set<Integer> mManagedProfiles = new HashSet<>();
|
||||
private boolean mIsQuietModeEnabled = false;
|
||||
private int[] profileIdsForUser;
|
||||
private boolean mUserSwitchEnabled;
|
||||
|
||||
|
||||
@Resetter
|
||||
public void reset() {
|
||||
@@ -56,6 +58,7 @@ public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager
|
||||
mRestrictionSources.clear();
|
||||
mManagedProfiles.clear();
|
||||
mIsQuietModeEnabled = false;
|
||||
mUserSwitchEnabled = false;
|
||||
}
|
||||
|
||||
public void setUserInfo(int userHandle, UserInfo userInfo) {
|
||||
@@ -136,4 +139,13 @@ public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager
|
||||
public void setProfileIdsWithDisabled(int[] profileIds) {
|
||||
profileIdsForUser = profileIds;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public boolean isUserSwitcherEnabled() {
|
||||
return mUserSwitchEnabled;
|
||||
}
|
||||
|
||||
public void setUserSwitcherEnabled(boolean userSwitchEnabled) {
|
||||
mUserSwitchEnabled = userSwitchEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,58 +17,59 @@ package com.android.settings.users;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Answers.RETURNS_DEEP_STUBS;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import android.content.Context;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.os.UserManager;
|
||||
import android.provider.Settings.Global;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.testutils.shadow.ShadowUserManager;
|
||||
import com.android.settingslib.RestrictedSwitchPreference;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowApplication;
|
||||
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(shadows = {ShadowUserManager.class})
|
||||
public class AddUserWhenLockedPreferenceControllerTest {
|
||||
|
||||
@Mock(answer = RETURNS_DEEP_STUBS)
|
||||
private PreferenceScreen mScreen;
|
||||
@Mock(answer = RETURNS_DEEP_STUBS)
|
||||
private UserInfo mUserInfo;
|
||||
@Mock(answer = RETURNS_DEEP_STUBS)
|
||||
private UserManager mUserManager;
|
||||
|
||||
private LifecycleOwner mLifecycleOwner;
|
||||
private Lifecycle mLifecycle;
|
||||
private Context mContext;
|
||||
private ShadowUserManager mUserManager;
|
||||
private AddUserWhenLockedPreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
ShadowApplication shadowContext = ShadowApplication.getInstance();
|
||||
shadowContext.setSystemService(Context.USER_SERVICE, mUserManager);
|
||||
mUserManager = ShadowUserManager.getShadow();
|
||||
mContext = shadowContext.getApplicationContext();
|
||||
mLifecycleOwner = () -> mLifecycle;
|
||||
mLifecycle = new Lifecycle(mLifecycleOwner);
|
||||
mController = new AddUserWhenLockedPreferenceController(mContext, "fake_key", mLifecycle);
|
||||
mController = new AddUserWhenLockedPreferenceController(mContext, "fake_key");
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
mUserManager.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPref_NotAdmin_shouldNotDisplay() {
|
||||
when(mUserManager.getUserInfo(anyInt())).thenReturn(mUserInfo);
|
||||
mUserManager.setUserInfo(0, mUserInfo);
|
||||
when(mUserInfo.isAdmin()).thenReturn(false);
|
||||
final RestrictedSwitchPreference preference = mock(RestrictedSwitchPreference.class);
|
||||
when(preference.getKey()).thenReturn(mController.getPreferenceKey());
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.users;
|
||||
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
|
||||
import static com.android.settings.core.BasePreferenceController.DISABLED_FOR_USER;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class MultiUserFooterPreferenceControllerTest {
|
||||
|
||||
private Context mContext;
|
||||
private MultiUserFooterPreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mController = new MultiUserFooterPreferenceController(mContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_multiUserOff_shouldReturnEnabled() {
|
||||
mController.mUserCaps.mEnabled = true;
|
||||
mController.mUserCaps.mUserSwitcherEnabled = false;
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_multiUserOn_shouldReturnDisabled() {
|
||||
mController.mUserCaps.mEnabled = true;
|
||||
mController.mUserCaps.mUserSwitcherEnabled = true;
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_FOR_USER);
|
||||
}
|
||||
}
|
||||
@@ -17,36 +17,43 @@
|
||||
package com.android.settings.users;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.testutils.shadow.ShadowUserManager;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(shadows = {ShadowUserManager.class})
|
||||
public class UserCapabilitiesTest {
|
||||
|
||||
@Mock
|
||||
private Context mContext;
|
||||
@Mock
|
||||
private UserManager mUserManager;
|
||||
private ShadowUserManager mUserManager;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mUserManager = ShadowUserManager.getShadow();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
mUserManager.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void disallowUserSwitchWhenRestrictionIsSet() {
|
||||
when(mUserManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH)).thenReturn(true);
|
||||
public void disallowUserSwitch_restrictionIsSet_true() {
|
||||
mUserManager.setUserRestriction(UserHandle.of(UserHandle.myUserId()),
|
||||
UserManager.DISALLOW_USER_SWITCH, true);
|
||||
|
||||
UserCapabilities userCapabilities = UserCapabilities.create(mContext);
|
||||
userCapabilities.updateAddUserCapabilities(mContext);
|
||||
@@ -55,12 +62,33 @@ public class UserCapabilitiesTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void allowUserSwitchWhenRestrictionIsNotSet() {
|
||||
when(mUserManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH)).thenReturn(false);
|
||||
public void disallowUserSwitch_restrictionIsNotSet_false() {
|
||||
mUserManager.setUserRestriction(UserHandle.of(UserHandle.myUserId()),
|
||||
UserManager.DISALLOW_USER_SWITCH, false);
|
||||
|
||||
UserCapabilities userCapabilities = UserCapabilities.create(mContext);
|
||||
userCapabilities.updateAddUserCapabilities(mContext);
|
||||
|
||||
assertThat(userCapabilities.mDisallowSwitchUser).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void userSwitchEnabled_off() {
|
||||
mUserManager.setUserSwitcherEnabled(false);
|
||||
|
||||
final UserCapabilities userCapabilities = UserCapabilities.create(mContext);
|
||||
userCapabilities.updateAddUserCapabilities(mContext);
|
||||
|
||||
assertThat(userCapabilities.mUserSwitcherEnabled).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void userSwitchEnabled_on() {
|
||||
mUserManager.setUserSwitcherEnabled(true);
|
||||
|
||||
final UserCapabilities userCapabilities = UserCapabilities.create(mContext);
|
||||
userCapabilities.updateAddUserCapabilities(mContext);
|
||||
|
||||
assertThat(userCapabilities.mUserSwitcherEnabled).isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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
|
||||
@@ -11,11 +12,9 @@
|
||||
* 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.graph;
|
||||
package com.android.settings.widget;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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
|
||||
@@ -11,11 +12,9 @@
|
||||
* 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.graph;
|
||||
package com.android.settings.widget;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
@@ -44,7 +44,7 @@ public class DataSaverSummaryUITest {
|
||||
mInstrumentation = InstrumentationRegistry.getInstrumentation();
|
||||
mUiDevice = UiDevice.getInstance(mInstrumentation);
|
||||
mIntent = new Intent().setClassName("com.android.settings",
|
||||
"com.android.settings.Settings$DataUsageSummaryLegacyActivity")
|
||||
"com.android.settings.Settings$DataUsageSummaryActivity")
|
||||
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user