Snap for 4834991 from f817b1e3a5 to qt-release

Change-Id: Ic7cb42ade00c98f09155918d610ecc15c298bdf9
This commit is contained in:
android-build-team Robot
2018-06-12 09:36:42 +00:00
59 changed files with 745 additions and 1025 deletions

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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 &amp; limit</string>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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"

View File

@@ -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 */ }

View File

@@ -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,

View File

@@ -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 -> {

View File

@@ -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);

View File

@@ -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";
}

View File

@@ -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(),

View File

@@ -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));
}

View File

@@ -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());
}

View File

@@ -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) {

View File

@@ -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 {

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}

View File

@@ -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)) {

View File

@@ -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;
}

View File

@@ -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) {

View File

@@ -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

View File

@@ -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,

View File

@@ -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);
}
}

View File

@@ -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) {

View File

@@ -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 &gt; 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;
}
};
}

View File

@@ -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;

View File

@@ -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);
}
}

View File

@@ -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());
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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

View File

@@ -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);

View File

@@ -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 =

View File

@@ -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());
}
}

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -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 */);

View File

@@ -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));
}
}

View File

@@ -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);

View File

@@ -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;
}
}

View File

@@ -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());

View File

@@ -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);
}
}

View File

@@ -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();
}
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);
}