diff --git a/res/drawable/ic_delete_accent.xml b/res/drawable/ic_delete_accent.xml
new file mode 100644
index 00000000000..86a9ccacd40
--- /dev/null
+++ b/res/drawable/ic_delete_accent.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
diff --git a/res/layout/master_clear.xml b/res/layout/master_clear.xml
index 921347e655e..247eedc407f 100644
--- a/res/layout/master_clear.xml
+++ b/res/layout/master_clear.xml
@@ -14,122 +14,125 @@
limitations under the License.
-->
-
+ android:orientation="vertical"
+ android:theme="@style/SuwThemeGlifV3.Light"
+ android:icon="@drawable/ic_delete_accent"
+ app:suwHeaderText="@string/master_clear_title">
+ android:id="@+id/master_clear_scrollview"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginStart="@dimen/reset_master_clear_margin_start"
+ android:layout_marginEnd="@dimen/reset_master_clear_margin_end">
+
+
-
+
-
+
-
+
-
+ android:text="@string/master_clear_accounts"/>
+
-
-
+
-
+
-
+
+
+
-
-
+ android:layout_gravity="center_vertical"
+ android:orientation="vertical">
+ android:text="@string/erase_external_storage"/>
+ android:text="@string/erase_external_storage_description"/>
-
+
-
-
-
+
diff --git a/res/layout/master_clear_account.xml b/res/layout/master_clear_account.xml
index 4a0552de873..0b522f24274 100644
--- a/res/layout/master_clear_account.xml
+++ b/res/layout/master_clear_account.xml
@@ -20,8 +20,7 @@
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
- android:paddingStart="16dp"
- android:paddingEnd="16dp">
+ style="@style/SuwDescription.Glif" >
+ style="@style/TextAppearance.SuwGlifItemSummary"/>
diff --git a/res/layout/master_clear_confirm.xml b/res/layout/master_clear_confirm.xml
index 4ab3a0fb72c..146fb770b8d 100644
--- a/res/layout/master_clear_confirm.xml
+++ b/res/layout/master_clear_confirm.xml
@@ -4,37 +4,37 @@
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.
-->
-
+ android:theme="@style/SuwThemeGlifV3.Light"
+ android:id="@+id/setup_wizard_layout"
+ android:icon="@drawable/ic_delete_accent"
+ app:suwHeaderText="@string/master_clear_confirm_title">
-
+ android:orientation="vertical">
-
-
-
+
+
+
diff --git a/res/layout/reset_esim_checkbox.xml b/res/layout/reset_esim_checkbox.xml
index fb15fe66766..e2ae4bbd5ed 100644
--- a/res/layout/reset_esim_checkbox.xml
+++ b/res/layout/reset_esim_checkbox.xml
@@ -15,6 +15,7 @@
-->
+ android:duplicateParentState="true"/>
+ android:layout_height="wrap_content"/>
+ android:text="@string/reset_esim_desc"/>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 4d168518897..a11dd5fd947 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -301,7 +301,7 @@
72dp
12dp
- 72dp
+ 32dp
12dp
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 90a46aebab5..d78b7b01af6 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -414,6 +414,9 @@
Bluetooth turned on
+
+ See all
+
Date & time
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 88ff2bb56be..b096cf8821d 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -458,9 +458,4 @@
- 24dp
-
-
diff --git a/res/xml/connected_devices.xml b/res/xml/connected_devices.xml
index 424ca750f9b..29c9e01183f 100644
--- a/res/xml/connected_devices.xml
+++ b/res/xml/connected_devices.xml
@@ -41,18 +41,24 @@
settings:useAdminDisabledSummary="true"
settings:controller="com.android.settings.connecteddevice.AddDevicePreferenceController"/>
-
+ settings:controller="com.android.settings.connecteddevice.PreviouslyConnectedDevicePreferenceController">
+
+
+
diff --git a/res/xml/top_level_settings.xml b/res/xml/top_level_settings.xml
index 6c91aeae70b..dbb106ec03d 100644
--- a/res/xml/top_level_settings.xml
+++ b/res/xml/top_level_settings.xml
@@ -120,6 +120,7 @@
android:summary="@string/support_summary"
android:title="@string/page_tab_title_support"
android:icon="@drawable/ic_homepage_support"
- android:order="100"/>
+ android:order="100"
+ settings:controller="com.android.settings.support.SupportPreferenceController"/>
\ No newline at end of file
diff --git a/src/com/android/settings/MasterClear.java b/src/com/android/settings/MasterClear.java
index c8ec448594b..97942fec63e 100644
--- a/src/com/android/settings/MasterClear.java
+++ b/src/com/android/settings/MasterClear.java
@@ -21,7 +21,7 @@ import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AuthenticatorDescription;
-import android.annotation.Nullable;
+import android.app.ActionBar;
import android.app.Activity;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -31,6 +31,7 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.UserInfo;
import android.content.res.Resources;
+import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Environment;
@@ -61,8 +62,9 @@ import com.android.settings.core.SubSettingLauncher;
import com.android.settings.enterprise.ActionDisabledByAdminDialogHelper;
import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settings.password.ConfirmLockPattern;
-import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtilsInternal;
+import com.android.setupwizardlib.TemplateLayout;
+import com.android.setupwizardlib.template.ButtonFooterMixin;
import java.util.List;
@@ -79,8 +81,10 @@ import java.util.List;
public class MasterClear extends InstrumentedFragment implements OnGlobalLayoutListener {
private static final String TAG = "MasterClear";
- @VisibleForTesting static final int KEYGUARD_REQUEST = 55;
- @VisibleForTesting static final int CREDENTIAL_CONFIRM_REQUEST = 56;
+ @VisibleForTesting
+ static final int KEYGUARD_REQUEST = 55;
+ @VisibleForTesting
+ static final int CREDENTIAL_CONFIRM_REQUEST = 56;
private static final String KEY_SHOW_ESIM_RESET_CHECKBOX
= "masterclear.allow_retain_esim_profiles_after_fdr";
@@ -89,27 +93,41 @@ public class MasterClear extends InstrumentedFragment implements OnGlobalLayoutL
static final String ERASE_ESIMS_EXTRA = "erase_esim";
private View mContentView;
- @VisibleForTesting Button mInitiateButton;
+ @VisibleForTesting
+ Button mInitiateButton;
private View mExternalStorageContainer;
- @VisibleForTesting CheckBox mExternalStorage;
+ @VisibleForTesting
+ CheckBox mExternalStorage;
private View mEsimStorageContainer;
- @VisibleForTesting CheckBox mEsimStorage;
- @VisibleForTesting ScrollView mScrollView;
+ @VisibleForTesting
+ CheckBox mEsimStorage;
+ @VisibleForTesting
+ ScrollView mScrollView;
@Override
public void onGlobalLayout() {
mInitiateButton.setEnabled(hasReachedBottom(mScrollView));
}
- @Override
- public void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- getActivity().setTitle(R.string.master_clear_short_title);
+ private void setUpActionBarAndTitle() {
+ final Activity activity = getActivity();
+ if (activity == null) {
+ Log.e(TAG, "No activity attached, skipping setUpActionBarAndTitle");
+ return;
+ }
+ final ActionBar actionBar = activity.getActionBar();
+ if (actionBar == null) {
+ Log.e(TAG, "No actionbar, skipping setUpActionBarAndTitle");
+ return;
+ }
+ actionBar.hide();
+ activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
}
/**
* Keyguard validation is run using the standard {@link ConfirmLockPattern}
* component as a subactivity
+ *
* @param request the request code to be returned once confirmation finishes
* @return true if confirmation launched
*/
@@ -189,8 +207,8 @@ public class MasterClear extends InstrumentedFragment implements OnGlobalLayoutL
Account[] accounts = am.getAccountsByType(accountType);
if (accounts != null && accounts.length > 0) {
final Intent requestAccountConfirmation = new Intent()
- .setPackage(packageName)
- .setComponent(new ComponentName(packageName, className));
+ .setPackage(packageName)
+ .setComponent(new ComponentName(packageName, className));
// Check to make sure that the intent is supported.
final PackageManager pm = context.getPackageManager();
final ResolveInfo resolution = pm.resolveActivity(requestAccountConfirmation, 0);
@@ -259,8 +277,9 @@ public class MasterClear extends InstrumentedFragment implements OnGlobalLayoutL
*/
@VisibleForTesting
void establishInitialState() {
- mInitiateButton = mContentView.findViewById(R.id.initiate_master_clear);
- mInitiateButton.setOnClickListener(mInitiateListener);
+ setUpActionBarAndTitle();
+ setUpInitiateButton();
+
mExternalStorageContainer = mContentView.findViewById(R.id.erase_external_container);
mExternalStorage = mContentView.findViewById(R.id.erase_external);
mEsimStorageContainer = mContentView.findViewById(R.id.erase_esim_container);
@@ -334,7 +353,7 @@ public class MasterClear extends InstrumentedFragment implements OnGlobalLayoutL
mScrollView.setOnScrollChangeListener(new OnScrollChangeListener() {
@Override
public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX,
- int oldScrollY) {
+ int oldScrollY) {
if (v instanceof ScrollView && hasReachedBottom((ScrollView) v)) {
mInitiateButton.setEnabled(true);
mScrollView.setOnScrollChangeListener(null);
@@ -360,8 +379,8 @@ public class MasterClear extends InstrumentedFragment implements OnGlobalLayoutL
}
ContentResolver cr = context.getContentResolver();
return Settings.Global.getInt(cr, Settings.Global.EUICC_PROVISIONED, 0) != 0
- || Settings.Global.getInt(
- cr, Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
+ || Settings.Global.getInt(
+ cr, Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
}
@VisibleForTesting
@@ -388,21 +407,36 @@ public class MasterClear extends InstrumentedFragment implements OnGlobalLayoutL
return diff <= 0;
}
+ private void setUpInitiateButton() {
+ if (mInitiateButton != null) {
+ return;
+ }
+
+ final TemplateLayout layout = mContentView.findViewById(R.id.setup_wizard_layout);
+ final ButtonFooterMixin buttonFooterMixin = layout.getMixin(ButtonFooterMixin.class);
+ buttonFooterMixin.removeAllViews();
+ buttonFooterMixin.addSpace();
+ buttonFooterMixin.addSpace();
+ mInitiateButton = buttonFooterMixin.addButton(R.string.master_clear_button_text,
+ R.style.SuwGlifButton_Primary);
+ mInitiateButton.setOnClickListener(mInitiateListener);
+ }
+
private void getContentDescription(View v, StringBuffer description) {
- if (v.getVisibility() != View.VISIBLE) {
- return;
- }
- if (v instanceof ViewGroup) {
- ViewGroup vGroup = (ViewGroup) v;
- for (int i = 0; i < vGroup.getChildCount(); i++) {
- View nextChild = vGroup.getChildAt(i);
- getContentDescription(nextChild, description);
- }
- } else if (v instanceof TextView) {
- TextView vText = (TextView) v;
- description.append(vText.getText());
- description.append(","); // Allow Talkback to pause between sections.
- }
+ if (v.getVisibility() != View.VISIBLE) {
+ return;
+ }
+ if (v instanceof ViewGroup) {
+ ViewGroup vGroup = (ViewGroup) v;
+ for (int i = 0; i < vGroup.getChildCount(); i++) {
+ View nextChild = vGroup.getChildAt(i);
+ getContentDescription(nextChild, description);
+ }
+ } else if (v instanceof TextView) {
+ TextView vText = (TextView) v;
+ description.append(vText.getText());
+ description.append(","); // Allow Talkback to pause between sections.
+ }
}
private boolean isExtStorageEncrypted() {
@@ -412,7 +446,7 @@ public class MasterClear extends InstrumentedFragment implements OnGlobalLayoutL
private void loadAccountList(final UserManager um) {
View accountsLabel = mContentView.findViewById(R.id.accounts_label);
- LinearLayout contents = (LinearLayout)mContentView.findViewById(R.id.accounts);
+ LinearLayout contents = (LinearLayout) mContentView.findViewById(R.id.accounts);
contents.removeAllViews();
Context context = getActivity();
@@ -421,7 +455,7 @@ public class MasterClear extends InstrumentedFragment implements OnGlobalLayoutL
AccountManager mgr = AccountManager.get(context);
- LayoutInflater inflater = (LayoutInflater)context.getSystemService(
+ LayoutInflater inflater = (LayoutInflater) context.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
int accountsCount = 0;
diff --git a/src/com/android/settings/MasterClearConfirm.java b/src/com/android/settings/MasterClearConfirm.java
index cfd20ebf03d..8ebb71054b3 100644
--- a/src/com/android/settings/MasterClearConfirm.java
+++ b/src/com/android/settings/MasterClearConfirm.java
@@ -16,18 +16,23 @@
package com.android.settings;
+
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import android.app.ActionBar;
+import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
+import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
import android.service.oemlock.OemLockManager;
import android.service.persistentdata.PersistentDataBlockManager;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -37,8 +42,9 @@ import android.widget.TextView;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.core.InstrumentedFragment;
import com.android.settings.enterprise.ActionDisabledByAdminDialogHelper;
-import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtilsInternal;
+import com.android.setupwizardlib.TemplateLayout;
+import com.android.setupwizardlib.template.ButtonFooterMixin;
/**
* Confirm and execute a reset of the device to a clean "just out of the box"
@@ -51,6 +57,7 @@ import com.android.settingslib.RestrictedLockUtilsInternal;
* This is the confirmation screen.
*/
public class MasterClearConfirm extends InstrumentedFragment {
+ private final static String TAG = "MasterClearConfirm";
private View mContentView;
private boolean mEraseSdCard;
@@ -103,9 +110,11 @@ public class MasterClearConfirm extends InstrumentedFragment {
mProgressDialog.show();
// need to prevent orientation changes as we're about to go into
- // a long IO request, so we won't be able to access inflate resources on flash
+ // a long IO request, so we won't be able to access inflate resources on
+ // flash
mOldOrientation = getActivity().getRequestedOrientation();
- getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
+ getActivity().setRequestedOrientation(
+ ActivityInfo.SCREEN_ORIENTATION_LOCKED);
}
}.execute();
} else {
@@ -140,8 +149,29 @@ public class MasterClearConfirm extends InstrumentedFragment {
* Configure the UI for the final confirmation interaction
*/
private void establishFinalConfirmationState() {
- mContentView.findViewById(R.id.execute_master_clear)
- .setOnClickListener(mFinalClickListener);
+ final TemplateLayout layout = mContentView.findViewById(R.id.setup_wizard_layout);
+
+ final ButtonFooterMixin buttonFooterMixin = layout.getMixin(ButtonFooterMixin.class);
+ buttonFooterMixin.removeAllViews();
+ buttonFooterMixin.addSpace();
+ buttonFooterMixin.addSpace();
+ buttonFooterMixin.addButton(R.string.master_clear_button_text,
+ R.style.SuwGlifButton_Primary).setOnClickListener(mFinalClickListener);
+ }
+
+ private void setUpActionBarAndTitle() {
+ final Activity activity = getActivity();
+ if (activity == null) {
+ Log.e(TAG, "No activity attached, skipping setUpActionBarAndTitle");
+ return;
+ }
+ final ActionBar actionBar = activity.getActionBar();
+ if (actionBar == null) {
+ Log.e(TAG, "No actionbar, skipping setUpActionBarAndTitle");
+ return;
+ }
+ actionBar.hide();
+ activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
}
@Override
@@ -160,6 +190,7 @@ public class MasterClearConfirm extends InstrumentedFragment {
return new View(getActivity());
}
mContentView = inflater.inflate(R.layout.master_clear_confirm, null);
+ setUpActionBarAndTitle();
establishFinalConfirmationState();
setAccessibilityTitle();
return mContentView;
@@ -167,8 +198,7 @@ public class MasterClearConfirm extends InstrumentedFragment {
private void setAccessibilityTitle() {
CharSequence currentTitle = getActivity().getTitle();
- TextView confirmationMessage =
- (TextView) mContentView.findViewById(R.id.master_clear_confirm);
+ TextView confirmationMessage = mContentView.findViewById(R.id.master_clear_confirm);
if (confirmationMessage != null) {
String accessibleText = new StringBuilder(currentTitle).append(",").append(
confirmationMessage.getText()).toString();
diff --git a/src/com/android/settings/bluetooth/BluetoothDeviceUpdater.java b/src/com/android/settings/bluetooth/BluetoothDeviceUpdater.java
index 297c90b2904..cac4565bddb 100644
--- a/src/com/android/settings/bluetooth/BluetoothDeviceUpdater.java
+++ b/src/com/android/settings/bluetooth/BluetoothDeviceUpdater.java
@@ -269,8 +269,9 @@ public abstract class BluetoothDeviceUpdater implements BluetoothCallback,
final BluetoothDevice device = cachedDevice.getDevice();
if (DBG) {
Log.d(TAG, "isDeviceConnected() device name : " + cachedDevice.getName() +
- ", is connected : " + device.isConnected());
+ ", is connected : " + device.isConnected() + " , is profile connected : "
+ + cachedDevice.isConnected());
}
- return device.getBondState() == BluetoothDevice.BOND_BONDED && device.isConnected();
+ return device.getBondState() == BluetoothDevice.BOND_BONDED && cachedDevice.isConnected();
}
}
diff --git a/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdater.java b/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdater.java
index 8c6d3f26704..127cb03e18f 100644
--- a/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdater.java
+++ b/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdater.java
@@ -43,9 +43,10 @@ public class SavedBluetoothDeviceUpdater extends BluetoothDeviceUpdater
final BluetoothDevice device = cachedDevice.getDevice();
if (DBG) {
Log.d(TAG, "isFilterMatched() device name : " + cachedDevice.getName() +
- ", is connected : " + device.isConnected());
+ ", is connected : " + device.isConnected() + ", is profile connected : "
+ + cachedDevice.isConnected());
}
- return device.getBondState() == BluetoothDevice.BOND_BONDED && !device.isConnected();
+ return device.getBondState() == BluetoothDevice.BOND_BONDED && !cachedDevice.isConnected();
}
@Override
diff --git a/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceController.java b/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceController.java
index 5f6ffb24eec..ffcd1fc4faa 100644
--- a/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceController.java
+++ b/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceController.java
@@ -20,6 +20,7 @@ import android.content.pm.PackageManager;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
+import androidx.preference.PreferenceGroup;
import androidx.preference.PreferenceScreen;
import com.android.settings.bluetooth.BluetoothDeviceUpdater;
@@ -35,7 +36,9 @@ import com.android.settingslib.core.lifecycle.events.OnStop;
public class PreviouslyConnectedDevicePreferenceController extends BasePreferenceController
implements LifecycleObserver, OnStart, OnStop, DevicePreferenceCallback {
- private Preference mPreference;
+ private static final int MAX_DEVICE_NUM = 3;
+
+ private PreferenceGroup mPreferenceGroup;
private BluetoothDeviceUpdater mBluetoothDeviceUpdater;
private DockUpdater mSavedDockUpdater;
private int mPreferenceSize;
@@ -57,8 +60,10 @@ public class PreviouslyConnectedDevicePreferenceController extends BasePreferenc
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
+ mPreferenceGroup = (PreferenceGroup) screen.findPreference(getPreferenceKey());
+ mPreferenceGroup.setVisible(false);
+
if (isAvailable()) {
- mPreference = screen.findPreference(getPreferenceKey());
final Context context = screen.getContext();
mBluetoothDeviceUpdater.setPrefContext(context);
mSavedDockUpdater.setPreferenceContext(context);
@@ -69,7 +74,6 @@ public class PreviouslyConnectedDevicePreferenceController extends BasePreferenc
public void onStart() {
mBluetoothDeviceUpdater.registerCallback();
mSavedDockUpdater.registerCallback();
- updatePreferenceOnSizeChanged();
}
@Override
@@ -86,13 +90,17 @@ public class PreviouslyConnectedDevicePreferenceController extends BasePreferenc
@Override
public void onDeviceAdded(Preference preference) {
mPreferenceSize++;
- updatePreferenceOnSizeChanged();
+ if (mPreferenceSize <= MAX_DEVICE_NUM) {
+ mPreferenceGroup.addPreference(preference);
+ }
+ updatePreferenceVisiblity();
}
@Override
public void onDeviceRemoved(Preference preference) {
mPreferenceSize--;
- updatePreferenceOnSizeChanged();
+ mPreferenceGroup.removePreference(preference);
+ updatePreferenceVisiblity();
}
@VisibleForTesting
@@ -106,18 +114,12 @@ public class PreviouslyConnectedDevicePreferenceController extends BasePreferenc
}
@VisibleForTesting
- void setPreferenceSize(int size) {
- mPreferenceSize = size;
+ void setPreferenceGroup(PreferenceGroup preferenceGroup) {
+ mPreferenceGroup = preferenceGroup;
}
@VisibleForTesting
- void setPreference(Preference preference) {
- mPreference = preference;
- }
-
- private void updatePreferenceOnSizeChanged() {
- if (isAvailable()) {
- mPreference.setEnabled(mPreferenceSize != 0);
- }
+ void updatePreferenceVisiblity() {
+ mPreferenceGroup.setVisible(mPreferenceSize > 0);
}
}
diff --git a/src/com/android/settings/datausage/AppDataUsageV2.java b/src/com/android/settings/datausage/AppDataUsageV2.java
index 6d6089e3620..4e8325b27c8 100644
--- a/src/com/android/settings/datausage/AppDataUsageV2.java
+++ b/src/com/android/settings/datausage/AppDataUsageV2.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * 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
@@ -22,13 +22,8 @@ import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
-import android.net.INetworkStatsSession;
-import android.net.NetworkPolicy;
-import android.net.NetworkStatsHistory;
import android.net.NetworkTemplate;
-import android.net.TrafficStats;
import android.os.Bundle;
-import android.os.RemoteException;
import android.os.UserHandle;
import android.util.ArraySet;
import android.util.IconDrawableFactory;
@@ -51,11 +46,13 @@ import com.android.settingslib.AppItem;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedSwitchPreference;
-import com.android.settingslib.net.ChartData;
-import com.android.settingslib.net.ChartDataLoaderCompat;
+import com.android.settingslib.net.NetworkCycleDataForUid;
+import com.android.settingslib.net.NetworkCycleDataForUidLoader;
import com.android.settingslib.net.UidDetail;
import com.android.settingslib.net.UidDetailProvider;
+import java.util.List;
+
public class AppDataUsageV2 extends DataUsageBaseFragment implements OnPreferenceChangeListener,
DataSaverBackend.Listener {
@@ -73,7 +70,7 @@ public class AppDataUsageV2 extends DataUsageBaseFragment implements OnPreferenc
private static final String KEY_CYCLE = "cycle";
private static final String KEY_UNRESTRICTED_DATA = "unrestricted_data_saver";
- private static final int LOADER_CHART_DATA = 2;
+ private static final int LOADER_APP_USAGE_DATA = 2;
private static final int LOADER_APP_PREF = 3;
private PackageManager mPackageManager;
@@ -88,14 +85,10 @@ public class AppDataUsageV2 extends DataUsageBaseFragment implements OnPreferenc
private Drawable mIcon;
private CharSequence mLabel;
private String mPackageName;
- private INetworkStatsSession mStatsSession;
private CycleAdapter mCycleAdapter;
- private long mStart;
- private long mEnd;
- private ChartData mChartData;
+ private List mUsageData;
private NetworkTemplate mTemplate;
- private NetworkPolicy mPolicy;
private AppItem mAppItem;
private Intent mAppSettingsIntent;
private SpinnerPreference mCycle;
@@ -108,12 +101,6 @@ public class AppDataUsageV2 extends DataUsageBaseFragment implements OnPreferenc
mPackageManager = getPackageManager();
final Bundle args = getArguments();
- try {
- mStatsSession = services.mStatsService.openSession();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
-
mAppItem = (args != null) ? (AppItem) args.getParcelable(ARG_APP_ITEM) : null;
mTemplate = (args != null) ? (NetworkTemplate) args.getParcelable(ARG_NETWORK_TEMPLATE)
: null;
@@ -208,21 +195,13 @@ public class AppDataUsageV2 extends DataUsageBaseFragment implements OnPreferenc
}
}
- @Override
- public void onDestroy() {
- TrafficStats.closeQuietly(mStatsSession);
- super.onDestroy();
- }
-
@Override
public void onResume() {
super.onResume();
if (mDataSaverBackend != null) {
mDataSaverBackend.addListener(this);
}
- mPolicy = services.mPolicyEditor.getPolicy(mTemplate);
- getLoaderManager().restartLoader(LOADER_CHART_DATA,
- ChartDataLoaderCompat.buildArgs(mTemplate, mAppItem), mChartDataCallbacks);
+ getLoaderManager().restartLoader(LOADER_APP_USAGE_DATA, null /* args */, mUidDataCallbacks);
updatePrefs();
}
@@ -300,19 +279,17 @@ public class AppDataUsageV2 extends DataUsageBaseFragment implements OnPreferenc
}
}
- private void bindData() {
+ @VisibleForTesting
+ void bindData(int position) {
final long backgroundBytes, foregroundBytes;
- if (mChartData == null || mStart == 0) {
+ if (mUsageData == null || position >= mUsageData.size()) {
backgroundBytes = foregroundBytes = 0;
mCycle.setVisible(false);
} else {
mCycle.setVisible(true);
- final long now = System.currentTimeMillis();
- NetworkStatsHistory.Entry entry = null;
- entry = mChartData.detailDefault.getValues(mStart, mEnd, now, entry);
- backgroundBytes = entry.rxBytes + entry.txBytes;
- entry = mChartData.detailForeground.getValues(mStart, mEnd, now, entry);
- foregroundBytes = entry.rxBytes + entry.txBytes;
+ final NetworkCycleDataForUid data = mUsageData.get(position);
+ backgroundBytes = data.getBackgroudUsage();
+ foregroundBytes = data.getForegroudUsage();
}
final long totalBytes = backgroundBytes + foregroundBytes;
final Context context = getContext();
@@ -376,11 +353,7 @@ public class AppDataUsageV2 extends DataUsageBaseFragment implements OnPreferenc
new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView> parent, View view, int position, long id) {
- final CycleAdapter.CycleItem cycle = (CycleAdapter.CycleItem) mCycle.getSelectedItem();
-
- mStart = cycle.start;
- mEnd = cycle.end;
- bindData();
+ bindData(position);
}
@Override
@@ -389,24 +362,30 @@ public class AppDataUsageV2 extends DataUsageBaseFragment implements OnPreferenc
}
};
- private final LoaderManager.LoaderCallbacks mChartDataCallbacks =
- new LoaderManager.LoaderCallbacks() {
- @Override
- public Loader onCreateLoader(int id, Bundle args) {
- return new ChartDataLoaderCompat(getActivity(), mStatsSession, args);
- }
+ private final LoaderManager.LoaderCallbacks> mUidDataCallbacks =
+ new LoaderManager.LoaderCallbacks>() {
+ @Override
+ public Loader> onCreateLoader(int id, Bundle args) {
+ return NetworkCycleDataForUidLoader.builder(getContext())
+ .setUid(mAppItem.key)
+ .setRetrieveDetail(true)
+ .setNetworkTemplate(mTemplate)
+ .setSubscriberId(mTemplate.getSubscriberId())
+ .build();
+ }
- @Override
- public void onLoadFinished(Loader loader, ChartData data) {
- mChartData = data;
- mCycleAdapter.updateCycleList(mPolicy, mChartData);
- bindData();
- }
+ @Override
+ public void onLoadFinished(Loader> loader,
+ List data) {
+ mUsageData = data;
+ mCycleAdapter.updateCycleList(data);
+ bindData(0 /* position */);
+ }
- @Override
- public void onLoaderReset(Loader loader) {
- }
- };
+ @Override
+ public void onLoaderReset(Loader> loader) {
+ }
+ };
private final LoaderManager.LoaderCallbacks> mAppPrefCallbacks =
new LoaderManager.LoaderCallbacks>() {
diff --git a/src/com/android/settings/homepage/CardContentProvider.java b/src/com/android/settings/homepage/CardContentProvider.java
index 7b087568ca1..99894459adf 100644
--- a/src/com/android/settings/homepage/CardContentProvider.java
+++ b/src/com/android/settings/homepage/CardContentProvider.java
@@ -77,8 +77,11 @@ public class CardContentProvider extends ContentProvider {
final String table = getTableFromMatch(uri);
database.beginTransaction();
+
+ // Here deletion first is avoiding redundant insertion. According to cl/215350754
+ database.delete(table, null /* whereClause */, null /* whereArgs */);
for (ContentValues value : values) {
- long ret = database.insert(table, null, value);
+ long ret = database.insert(table, null /* nullColumnHack */, value);
if (ret != -1L) {
numInserted++;
} else {
@@ -87,7 +90,7 @@ public class CardContentProvider extends ContentProvider {
}
}
database.setTransactionSuccessful();
- getContext().getContentResolver().notifyChange(uri, null);
+ getContext().getContentResolver().notifyChange(uri, null /* observer */);
} finally {
database.endTransaction();
StrictMode.setThreadPolicy(oldPolicy);
@@ -103,7 +106,7 @@ public class CardContentProvider extends ContentProvider {
final SQLiteDatabase database = mDBHelper.getWritableDatabase();
final String table = getTableFromMatch(uri);
final int rowsDeleted = database.delete(table, selection, selectionArgs);
- getContext().getContentResolver().notifyChange(uri, null);
+ getContext().getContentResolver().notifyChange(uri, null /* observer */);
return rowsDeleted;
} finally {
StrictMode.setThreadPolicy(oldPolicy);
@@ -127,7 +130,8 @@ public class CardContentProvider extends ContentProvider {
queryBuilder.setTables(table);
final SQLiteDatabase database = mDBHelper.getReadableDatabase();
final Cursor cursor = queryBuilder.query(database,
- projection, selection, selectionArgs, null, null, sortOrder);
+ projection, selection, selectionArgs, null /* groupBy */, null /* having */,
+ sortOrder);
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
@@ -145,7 +149,7 @@ public class CardContentProvider extends ContentProvider {
final SQLiteDatabase database = mDBHelper.getWritableDatabase();
final String table = getTableFromMatch(uri);
final int rowsUpdated = database.update(table, values, selection, selectionArgs);
- getContext().getContentResolver().notifyChange(uri, null);
+ getContext().getContentResolver().notifyChange(uri, null /* observer */);
return rowsUpdated;
} finally {
StrictMode.setThreadPolicy(oldPolicy);
diff --git a/src/com/android/settings/homepage/TopLevelSettings.java b/src/com/android/settings/homepage/TopLevelSettings.java
index c450157d254..8f70b2b3ed6 100644
--- a/src/com/android/settings/homepage/TopLevelSettings.java
+++ b/src/com/android/settings/homepage/TopLevelSettings.java
@@ -33,6 +33,7 @@ import com.android.settings.R;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.support.SupportPreferenceController;
import com.android.settingslib.core.instrumentation.Instrumentable;
import com.android.settingslib.search.SearchIndexable;
@@ -67,6 +68,12 @@ public class TopLevelSettings extends DashboardFragment implements
return MetricsProto.MetricsEvent.DASHBOARD_SUMMARY;
}
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ use(SupportPreferenceController.class).setActivity(getActivity());
+ }
+
@Override
public int getHelpResource() {
// Disable the help icon because this page uses a full search view in actionbar.
diff --git a/src/com/android/settings/support/SupportPreferenceController.java b/src/com/android/settings/support/SupportPreferenceController.java
new file mode 100644
index 00000000000..793842f8712
--- /dev/null
+++ b/src/com/android/settings/support/SupportPreferenceController.java
@@ -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.support;
+
+import android.app.Activity;
+import android.content.Context;
+import android.text.TextUtils;
+
+import androidx.preference.Preference;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settings.overlay.SupportFeatureProvider;
+
+public class SupportPreferenceController extends BasePreferenceController {
+
+ private final SupportFeatureProvider mSupportFeatureProvider;
+
+ private Activity mActivity;
+
+ public SupportPreferenceController(Context context, String preferenceKey) {
+ super(context, preferenceKey);
+ mSupportFeatureProvider = FeatureFactory.getFactory(context)
+ .getSupportFeatureProvider(context);
+ }
+
+ public void setActivity(Activity activity) {
+ mActivity = activity;
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return mSupportFeatureProvider == null ? UNSUPPORTED_ON_DEVICE : AVAILABLE;
+ }
+
+ @Override
+ public boolean handlePreferenceTreeClick(Preference preference) {
+ if (preference == null || mActivity == null ||
+ !TextUtils.equals(preference.getKey(), getPreferenceKey())) {
+ return false;
+ }
+ mSupportFeatureProvider.startSupport(mActivity);
+ return true;
+
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/MasterClearTest.java b/tests/robotests/src/com/android/settings/MasterClearTest.java
index e1243655bb1..174f5ab7af6 100644
--- a/tests/robotests/src/com/android/settings/MasterClearTest.java
+++ b/tests/robotests/src/com/android/settings/MasterClearTest.java
@@ -122,8 +122,8 @@ public class MasterClearTest {
verify(context).startActivity(intent.capture());
assertThat(intent.getValue().getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS)
- .getBoolean(MasterClear.ERASE_ESIMS_EXTRA, false))
- .isTrue();
+ .getBoolean(MasterClear.ERASE_ESIMS_EXTRA, false))
+ .isTrue();
}
@Test
@@ -139,8 +139,8 @@ public class MasterClearTest {
verify(context).startActivity(intent.capture());
assertThat(intent.getValue().getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS)
- .getBoolean(MasterClear.ERASE_ESIMS_EXTRA, false))
- .isFalse();
+ .getBoolean(MasterClear.ERASE_ESIMS_EXTRA, false))
+ .isFalse();
}
@Test
@@ -210,11 +210,10 @@ public class MasterClearTest {
ShadowUtils.setIsDemoUser(true);
final ComponentName componentName =
- ComponentName.unflattenFromString("com.android.retaildemo/.DeviceAdminReceiver");
+ ComponentName.unflattenFromString("com.android.retaildemo/.DeviceAdminReceiver");
ShadowUtils.setDeviceOwnerComponent(componentName);
- mMasterClear.mInitiateListener
- .onClick(mContentView.findViewById(R.id.initiate_master_clear));
+ mMasterClear.mInitiateListener.onClick(mContentView);
final Intent intent = mShadowActivity.getNextStartedActivity();
assertThat(Intent.ACTION_FACTORY_RESET).isEqualTo(intent.getAction());
assertThat(componentName).isNotNull();
@@ -240,7 +239,8 @@ public class MasterClearTest {
doNothing().when(mMasterClear).establishInitialState();
mMasterClear
- .onActivityResultInternal(MasterClear.KEYGUARD_REQUEST, Activity.RESULT_CANCELED, null);
+ .onActivityResultInternal(MasterClear.KEYGUARD_REQUEST, Activity.RESULT_CANCELED,
+ null);
verify(mMasterClear, times(1)).isValidRequestCode(eq(MasterClear.KEYGUARD_REQUEST));
verify(mMasterClear, times(1)).establishInitialState();
@@ -255,7 +255,7 @@ public class MasterClearTest {
doNothing().when(mMasterClear).showAccountCredentialConfirmation(eq(mMockIntent));
mMasterClear
- .onActivityResultInternal(MasterClear.KEYGUARD_REQUEST, Activity.RESULT_OK, null);
+ .onActivityResultInternal(MasterClear.KEYGUARD_REQUEST, Activity.RESULT_OK, null);
verify(mMasterClear, times(1)).isValidRequestCode(eq(MasterClear.KEYGUARD_REQUEST));
verify(mMasterClear, times(0)).establishInitialState();
@@ -270,7 +270,7 @@ public class MasterClearTest {
doNothing().when(mMasterClear).showFinalConfirmation();
mMasterClear
- .onActivityResultInternal(MasterClear.KEYGUARD_REQUEST, Activity.RESULT_OK, null);
+ .onActivityResultInternal(MasterClear.KEYGUARD_REQUEST, Activity.RESULT_OK, null);
verify(mMasterClear, times(1)).isValidRequestCode(eq(MasterClear.KEYGUARD_REQUEST));
verify(mMasterClear, times(0)).establishInitialState();
@@ -281,14 +281,14 @@ public class MasterClearTest {
@Test
public void testOnActivityResultInternal_confirmRequestTriggeringShowFinal() {
doReturn(true).when(mMasterClear)
- .isValidRequestCode(eq(MasterClear.CREDENTIAL_CONFIRM_REQUEST));
+ .isValidRequestCode(eq(MasterClear.CREDENTIAL_CONFIRM_REQUEST));
doNothing().when(mMasterClear).showFinalConfirmation();
mMasterClear.onActivityResultInternal(
- MasterClear.CREDENTIAL_CONFIRM_REQUEST, Activity.RESULT_OK, null);
+ MasterClear.CREDENTIAL_CONFIRM_REQUEST, Activity.RESULT_OK, null);
verify(mMasterClear, times(1))
- .isValidRequestCode(eq(MasterClear.CREDENTIAL_CONFIRM_REQUEST));
+ .isValidRequestCode(eq(MasterClear.CREDENTIAL_CONFIRM_REQUEST));
verify(mMasterClear, times(0)).establishInitialState();
verify(mMasterClear, times(0)).getAccountConfirmationIntent();
verify(mMasterClear, times(1)).showFinalConfirmation();
@@ -306,9 +306,9 @@ public class MasterClearTest {
when(mMasterClear.getActivity()).thenReturn(mMockActivity);
when(mMockActivity.getString(R.string.account_type)).thenReturn(TEST_ACCOUNT_TYPE);
when(mMockActivity.getString(R.string.account_confirmation_package))
- .thenReturn(TEST_CONFIRMATION_PACKAGE);
+ .thenReturn(TEST_CONFIRMATION_PACKAGE);
when(mMockActivity.getString(R.string.account_confirmation_class))
- .thenReturn(TEST_CONFIRMATION_CLASS);
+ .thenReturn(TEST_CONFIRMATION_CLASS);
Account[] accounts = new Account[0];
when(mMockActivity.getSystemService(Context.ACCOUNT_SERVICE)).thenReturn(mAccountManager);
@@ -321,10 +321,10 @@ public class MasterClearTest {
when(mMasterClear.getActivity()).thenReturn(mMockActivity);
when(mMockActivity.getString(R.string.account_type)).thenReturn(TEST_ACCOUNT_TYPE);
when(mMockActivity.getString(R.string.account_confirmation_package))
- .thenReturn(TEST_CONFIRMATION_PACKAGE);
+ .thenReturn(TEST_CONFIRMATION_PACKAGE);
when(mMockActivity.getString(R.string.account_confirmation_class))
- .thenReturn(TEST_CONFIRMATION_CLASS);
- Account[] accounts = new Account[] { new Account(TEST_ACCOUNT_NAME, TEST_ACCOUNT_TYPE) };
+ .thenReturn(TEST_CONFIRMATION_CLASS);
+ Account[] accounts = new Account[]{new Account(TEST_ACCOUNT_NAME, TEST_ACCOUNT_TYPE)};
when(mMockActivity.getSystemService(Context.ACCOUNT_SERVICE)).thenReturn(mAccountManager);
when(mAccountManager.getAccountsByType(TEST_ACCOUNT_TYPE)).thenReturn(accounts);
// The package manager should not resolve the confirmation intent targeting the non-existent
@@ -339,11 +339,11 @@ public class MasterClearTest {
// Only try to show account confirmation if the appropriate resource overlays are available.
when(mMockActivity.getString(R.string.account_type)).thenReturn(TEST_ACCOUNT_TYPE);
when(mMockActivity.getString(R.string.account_confirmation_package))
- .thenReturn(TEST_CONFIRMATION_PACKAGE);
+ .thenReturn(TEST_CONFIRMATION_PACKAGE);
when(mMockActivity.getString(R.string.account_confirmation_class))
- .thenReturn(TEST_CONFIRMATION_CLASS);
+ .thenReturn(TEST_CONFIRMATION_CLASS);
// Add accounts to trigger the search for a resolving intent.
- Account[] accounts = new Account[] { new Account(TEST_ACCOUNT_NAME, TEST_ACCOUNT_TYPE) };
+ Account[] accounts = new Account[]{new Account(TEST_ACCOUNT_NAME, TEST_ACCOUNT_TYPE)};
when(mMockActivity.getSystemService(Context.ACCOUNT_SERVICE)).thenReturn(mAccountManager);
when(mAccountManager.getAccountsByType(TEST_ACCOUNT_TYPE)).thenReturn(accounts);
// The package manager should not resolve the confirmation intent targeting the non-existent
@@ -366,17 +366,19 @@ public class MasterClearTest {
public void testShowAccountCredentialConfirmation() {
// Finally mock out the startActivityForResultCall
doNothing().when(mMasterClear)
- .startActivityForResult(eq(mMockIntent), eq(MasterClear.CREDENTIAL_CONFIRM_REQUEST));
+ .startActivityForResult(eq(mMockIntent),
+ eq(MasterClear.CREDENTIAL_CONFIRM_REQUEST));
mMasterClear.showAccountCredentialConfirmation(mMockIntent);
verify(mMasterClear, times(1))
- .startActivityForResult(eq(mMockIntent), eq(MasterClear.CREDENTIAL_CONFIRM_REQUEST));
+ .startActivityForResult(eq(mMockIntent),
+ eq(MasterClear.CREDENTIAL_CONFIRM_REQUEST));
}
@Test
public void testIsValidRequestCode() {
assertThat(mMasterClear.isValidRequestCode(MasterClear.KEYGUARD_REQUEST)).isTrue();
assertThat(mMasterClear.isValidRequestCode(MasterClear.CREDENTIAL_CONFIRM_REQUEST))
- .isTrue();
+ .isTrue();
assertThat(mMasterClear.isValidRequestCode(0)).isFalse();
}
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceUpdaterTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceUpdaterTest.java
index 28bf3ab8903..4ede9477995 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceUpdaterTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceUpdaterTest.java
@@ -161,7 +161,7 @@ public class BluetoothDeviceUpdaterTest {
@Test
public void isDeviceConnected_deviceConnected() {
doReturn(BluetoothDevice.BOND_BONDED).when(mBluetoothDevice).getBondState();
- doReturn(true).when(mBluetoothDevice).isConnected();
+ doReturn(true).when(mCachedBluetoothDevice).isConnected();
assertThat(mBluetoothDeviceUpdater.isDeviceConnected(mCachedBluetoothDevice)).isTrue();
}
@@ -169,7 +169,7 @@ public class BluetoothDeviceUpdaterTest {
@Test
public void isDeviceConnected_deviceNotConnected() {
doReturn(BluetoothDevice.BOND_BONDED).when(mBluetoothDevice).getBondState();
- doReturn(false).when(mBluetoothDevice).isConnected();
+ doReturn(false).when(mCachedBluetoothDevice).isConnected();
assertThat(mBluetoothDeviceUpdater.isDeviceConnected(mCachedBluetoothDevice)).isFalse();
}
diff --git a/tests/robotests/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdaterTest.java b/tests/robotests/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdaterTest.java
index e25e4b22744..4d4a711ff5e 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdaterTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/SavedBluetoothDeviceUpdaterTest.java
@@ -77,7 +77,7 @@ public class SavedBluetoothDeviceUpdaterTest {
@Test
public void update_filterMatch_addPreference() {
doReturn(BluetoothDevice.BOND_BONDED).when(mBluetoothDevice).getBondState();
- doReturn(false).when(mBluetoothDevice).isConnected();
+ doReturn(false).when(mCachedBluetoothDevice).isConnected();
mBluetoothDeviceUpdater.update(mCachedBluetoothDevice);
@@ -87,7 +87,7 @@ public class SavedBluetoothDeviceUpdaterTest {
@Test
public void update_filterNotMatch_removePreference() {
doReturn(BluetoothDevice.BOND_NONE).when(mBluetoothDevice).getBondState();
- doReturn(true).when(mBluetoothDevice).isConnected();
+ doReturn(true).when(mCachedBluetoothDevice).isConnected();
mBluetoothDeviceUpdater.update(mCachedBluetoothDevice);
@@ -96,7 +96,7 @@ public class SavedBluetoothDeviceUpdaterTest {
@Test
public void onProfileConnectionStateChanged_deviceConnected_removePreference() {
- when(mBluetoothDevice.isConnected()).thenReturn(true);
+ when(mCachedBluetoothDevice.isConnected()).thenReturn(true);
mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice,
BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP);
@@ -106,7 +106,7 @@ public class SavedBluetoothDeviceUpdaterTest {
@Test
public void onProfileConnectionStateChanged_deviceDisconnected_addPreference() {
- when(mBluetoothDevice.isConnected()).thenReturn(false);
+ when(mCachedBluetoothDevice.isConnected()).thenReturn(false);
mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice,
BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.A2DP);
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceControllerTest.java
index fc08016f4d0..52b2e95593c 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/PreviouslyConnectedDevicePreferenceControllerTest.java
@@ -28,6 +28,9 @@ import android.content.Context;
import android.content.pm.PackageManager;
import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceGroup;
+import androidx.preference.PreferenceManager;
import com.android.settings.bluetooth.BluetoothDeviceUpdater;
import com.android.settings.connecteddevice.dock.DockUpdater;
@@ -54,10 +57,12 @@ public class PreviouslyConnectedDevicePreferenceControllerTest {
private DockUpdater mDockUpdater;
@Mock
private PackageManager mPackageManager;
+ @Mock
+ private PreferenceManager mPreferenceManager;
private Context mContext;
private PreviouslyConnectedDevicePreferenceController mPreConnectedDeviceController;
- private Preference mPreference;
+ private PreferenceGroup mPreferenceGroup;
@Before
public void setUp() {
@@ -70,8 +75,10 @@ public class PreviouslyConnectedDevicePreferenceControllerTest {
mPreConnectedDeviceController.setBluetoothDeviceUpdater(mBluetoothDeviceUpdater);
mPreConnectedDeviceController.setSavedDockUpdater(mDockUpdater);
- mPreference = new Preference(mContext);
- mPreConnectedDeviceController.setPreference(mPreference);
+ mPreferenceGroup = spy(new PreferenceCategory(mContext));
+ doReturn(mPreferenceManager).when(mPreferenceGroup).getPreferenceManager();
+ mPreferenceGroup.setVisible(false);
+ mPreConnectedDeviceController.setPreferenceGroup(mPreferenceGroup);
}
@Test
@@ -101,20 +108,34 @@ public class PreviouslyConnectedDevicePreferenceControllerTest {
}
@Test
- public void onDeviceAdded_addFirstDevice_preferenceIsEnable() {
- doReturn(true).when(mPackageManager).hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);
- mPreConnectedDeviceController.setPreferenceSize(0);
- mPreConnectedDeviceController.onDeviceAdded(mPreference);
+ public void onDeviceAdded_addDevicePreference_displayIt() {
+ mPreConnectedDeviceController.onDeviceAdded(new Preference(mContext));
- assertThat(mPreference.isEnabled()).isTrue();
+ assertThat(mPreferenceGroup.isVisible()).isTrue();
+ assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(1);
}
@Test
- public void onDeviceRemoved_removeLastDevice_preferenceIsDisable() {
- doReturn(true).when(mPackageManager).hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);
- mPreConnectedDeviceController.setPreferenceSize(1);
- mPreConnectedDeviceController.onDeviceRemoved(mPreference);
+ public void onDeviceAdded_addFourDevicePreference_onlyDisplayThree() {
+ mPreConnectedDeviceController.onDeviceAdded(new Preference(mContext));
+ mPreConnectedDeviceController.onDeviceAdded(new Preference(mContext));
+ mPreConnectedDeviceController.onDeviceAdded(new Preference(mContext));
+ mPreConnectedDeviceController.onDeviceAdded(new Preference(mContext));
- assertThat(mPreference.isEnabled()).isFalse();
+ assertThat(mPreferenceGroup.isVisible()).isTrue();
+ assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(3);
}
+
+ @Test
+ public void onDeviceRemoved_removeLastDevice_setInvisible() {
+ final Preference preference = new Preference(mContext);
+ mPreferenceGroup.addPreference(preference);
+ mPreferenceGroup.setVisible(true);
+
+ mPreConnectedDeviceController.onDeviceRemoved(preference);
+
+ assertThat(mPreferenceGroup.isVisible()).isFalse();
+ assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(0);
+ }
+
}
diff --git a/tests/robotests/src/com/android/settings/datausage/AppDataUsageV2Test.java b/tests/robotests/src/com/android/settings/datausage/AppDataUsageV2Test.java
index d979b6800ae..8796a395507 100644
--- a/tests/robotests/src/com/android/settings/datausage/AppDataUsageV2Test.java
+++ b/tests/robotests/src/com/android/settings/datausage/AppDataUsageV2Test.java
@@ -19,6 +19,7 @@ package com.android.settings.datausage;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.doNothing;
@@ -28,12 +29,14 @@ 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.pm.PackageManager;
import android.net.NetworkPolicyManager;
import android.os.Bundle;
import android.util.ArraySet;
import android.view.View;
+import androidx.preference.Preference;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
@@ -45,6 +48,7 @@ import com.android.settings.widget.EntityHeaderController;
import com.android.settingslib.AppItem;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import com.android.settingslib.RestrictedSwitchPreference;
+import com.android.settingslib.net.NetworkCycleDataForUid;
import org.junit.After;
import org.junit.Before;
@@ -57,6 +61,9 @@ import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers;
+import java.util.ArrayList;
+import java.util.List;
+
@RunWith(SettingsRobolectricTestRunner.class)
@Config(shadows = {ShadowEntityHeaderController.class, ShadowRestrictedLockUtilsInternal.class})
public class AppDataUsageV2Test {
@@ -172,4 +179,49 @@ public class AppDataUsageV2Test {
verify(restrictBackgroundPref).setDisabledByAdmin(any(EnforcedAdmin.class));
verify(unrestrictedDataPref).setDisabledByAdmin(any(EnforcedAdmin.class));
}
+
+ @Test
+ public void bindData_noAppUsageData_shouldHideCycleSpinner() {
+ mFragment = spy(new AppDataUsageV2());
+ final SpinnerPreference cycle = mock(SpinnerPreference.class);
+ ReflectionHelpers.setField(mFragment, "mCycle", cycle);
+ final Preference preference = mock(Preference.class);
+ ReflectionHelpers.setField(mFragment, "mBackgroundUsage", preference);
+ ReflectionHelpers.setField(mFragment, "mForegroundUsage", preference);
+ ReflectionHelpers.setField(mFragment, "mTotalUsage", preference);
+ doReturn(RuntimeEnvironment.application).when(mFragment).getContext();
+
+ mFragment.bindData(0 /* position */);
+
+ verify(cycle).setVisible(false);
+ }
+
+ @Test
+ public void bindData_hasAppUsageData_shouldShowCycleSpinnerAndUpdateUsageSummary() {
+ mFragment = spy(new AppDataUsageV2());
+ final Context context = RuntimeEnvironment.application;
+ doReturn(context).when(mFragment).getContext();
+ final long backgroundBytes = 1234L;
+ final long foregroundBytes = 5678L;
+ final List appUsage = new ArrayList<>();
+ appUsage.add(new NetworkCycleDataForUid.Builder()
+ .setBackgroundUsage(backgroundBytes).setForegroundUsage(foregroundBytes).build());
+ ReflectionHelpers.setField(mFragment, "mUsageData", appUsage);
+ final Preference backgroundPref = mock(Preference.class);
+ ReflectionHelpers.setField(mFragment, "mBackgroundUsage", backgroundPref);
+ final Preference foregroundPref = mock(Preference.class);
+ ReflectionHelpers.setField(mFragment, "mForegroundUsage", foregroundPref);
+ final Preference totalPref = mock(Preference.class);
+ ReflectionHelpers.setField(mFragment, "mTotalUsage", totalPref);
+ final SpinnerPreference cycle = mock(SpinnerPreference.class);
+ ReflectionHelpers.setField(mFragment, "mCycle", cycle);
+
+ mFragment.bindData(0 /* position */);
+
+ verify(cycle).setVisible(true);
+ verify(totalPref).setSummary(
+ DataUsageUtils.formatDataUsage(context, backgroundBytes + foregroundBytes));
+ verify(backgroundPref).setSummary(DataUsageUtils.formatDataUsage(context, backgroundBytes));
+ verify(foregroundPref).setSummary(DataUsageUtils.formatDataUsage(context, foregroundBytes));
+ }
}
diff --git a/tests/robotests/src/com/android/settings/support/SupportPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/support/SupportPreferenceControllerTest.java
new file mode 100644
index 00000000000..d8050472aee
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/support/SupportPreferenceControllerTest.java
@@ -0,0 +1,78 @@
+/*
+ * 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.support;
+
+import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.verify;
+
+import android.app.Activity;
+
+import androidx.preference.Preference;
+
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class SupportPreferenceControllerTest {
+
+
+ private Activity mActivity;
+ private FakeFeatureFactory mFeatureFactory;
+ private Preference mPreference;
+
+ @Before
+ public void setUp() {
+ mActivity = Robolectric.setupActivity(Activity.class);
+ mFeatureFactory = FakeFeatureFactory.setupForTest();
+ mPreference = new Preference(mActivity);
+ mPreference.setKey("test_key");
+ }
+
+ @Test
+ public void getAvailability_noSupport_unavailable() {
+ ReflectionHelpers.setField(mFeatureFactory, "supportFeatureProvider", null);
+ assertThat(new SupportPreferenceController(mActivity, "test_key").getAvailabilityStatus())
+ .isEqualTo(UNSUPPORTED_ON_DEVICE);
+ }
+
+ @Test
+ public void getAvailability_hasSupport_available() {
+ assertThat(new SupportPreferenceController(mActivity, "test_key").getAvailabilityStatus())
+ .isEqualTo(AVAILABLE);
+ }
+
+ @Test
+ public void handlePreferenceTreeClick_shouldLaunchSupport() {
+ final SupportPreferenceController controller = new SupportPreferenceController(mActivity,
+ mPreference.getKey());
+ controller.setActivity(mActivity);
+
+ assertThat(controller.handlePreferenceTreeClick(mPreference)).isTrue();
+ verify(mFeatureFactory.supportFeatureProvider).startSupport(mActivity);
+ }
+
+}