Merge "Ignore MobileNetworkActivityTest"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 4242609..86fb8d9 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -9969,6 +9969,12 @@
<!-- [CHAR_LIMIT=40] Positive button text in dark theme notification -->
<string name="dark_ui_settings_dialog_acknowledge">Got it</string>
+ <!-- [CHAR_LIMIT=50] Title string in the dark theme slice(suggestion) -->
+ <string name="dark_theme_slice_title">Try Dark theme</string>
+
+ <!-- [CHAR_LIMIT=50] Subtitle string in the dark theme slice(suggestion) -->
+ <string name="dark_theme_slice_subtitle">Helps extend battery life</string>
+
<!-- [CHAR LIMIT=60] Name of dev option to enable extra quick settings tiles -->
<string name="quick_settings_developer_tiles">Quick settings developer tiles</string>
diff --git a/res/xml/inactive_apps.xml b/res/xml/dummy_preference_screen.xml
similarity index 85%
rename from res/xml/inactive_apps.xml
rename to res/xml/dummy_preference_screen.xml
index 6f93bdb..4ffa916 100644
--- a/res/xml/inactive_apps.xml
+++ b/res/xml/dummy_preference_screen.xml
@@ -15,8 +15,7 @@
-->
<PreferenceScreen
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:title="@string/inactive_apps_title">
-
+ xmlns:settings="http://schemas.android.com/apk/res-auto"
+ settings:searchable="false">
</PreferenceScreen>
diff --git a/res/xml/storage_dashboard_fragment.xml b/res/xml/storage_dashboard_fragment.xml
index 63ce90b..66447cd 100644
--- a/res/xml/storage_dashboard_fragment.xml
+++ b/res/xml/storage_dashboard_fragment.xml
@@ -22,7 +22,9 @@
android:orderingFromXml="false">
<com.android.settings.deviceinfo.storage.StorageSummaryDonutPreference
android:key="pref_summary"
- android:order="0" />
+ android:order="0"
+ settings:searchable="false"
+ settings:controller="com.android.settings.deviceinfo.storage.StorageSummaryDonutPreferenceController"/>
<com.android.settings.widget.MasterSwitchPreference
android:fragment="com.android.settings.deletionhelper.AutomaticStorageManagerSettings"
android:key="toggle_asm"
diff --git a/res/xml/storage_summary_donut.xml b/res/xml/storage_summary_donut.xml
new file mode 100644
index 0000000..be95cf8
--- /dev/null
+++ b/res/xml/storage_summary_donut.xml
@@ -0,0 +1,28 @@
+<!--
+ ~ Copyright (C) 2019 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="storage_dashboard_screen"
+ android:title="@string/storage_settings"
+ android:orderingFromXml="false">
+ <com.android.settings.deviceinfo.storage.StorageSummaryDonutPreference
+ android:key="pref_summary"
+ android:order="0"
+ settings:searchable="false"
+ settings:controller="com.android.settings.deviceinfo.storage.StorageSummaryDonutPreferenceController"/>
+</PreferenceScreen>
\ No newline at end of file
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index 65d0c82..b5a1539 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -21,9 +21,6 @@
import static android.text.format.DateUtils.FORMAT_ABBREV_MONTH;
import static android.text.format.DateUtils.FORMAT_SHOW_DATE;
-import static com.android.settings.applications.manageapplications.ManageApplications.EXTRA_PERSONAL_ONLY;
-import static com.android.settings.applications.manageapplications.ManageApplications.EXTRA_WORK_ONLY;
-
import android.annotation.Nullable;
import android.app.ActionBar;
import android.app.Activity;
@@ -106,6 +103,7 @@
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.core.FeatureFlags;
import com.android.settings.dashboard.profileselector.ProfileFragmentBridge;
+import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settingslib.widget.ActionBarShadowController;
@@ -1061,12 +1059,14 @@
*/
public static Fragment getTargetFragment(Activity activity, String fragmentName, Bundle args) {
Fragment f = null;
- final boolean isWorkOnly = args == null ? false : args.getBoolean(EXTRA_WORK_ONLY);
- final boolean isPersonalOnly = args == null ? false : args.getBoolean(EXTRA_PERSONAL_ONLY);
+ final boolean isPersonal = args != null ? args.getInt(ProfileSelectFragment.EXTRA_PROFILE)
+ == ProfileSelectFragment.PERSONAL : false;
+ final boolean isWork = args != null ? args.getInt(ProfileSelectFragment.EXTRA_PROFILE)
+ == ProfileSelectFragment.WORK : false;
if (FeatureFlagUtils.isEnabled(activity, FeatureFlags.PERSONAL_WORK_PROFILE)
&& UserManager.get(activity).getUserProfiles().size() > 1
&& ProfileFragmentBridge.FRAGMENT_MAP.get(fragmentName) != null
- && !isWorkOnly && !isPersonalOnly) {
+ && !isWork && !isPersonal) {
f = Fragment.instantiate(activity, ProfileFragmentBridge.FRAGMENT_MAP.get(fragmentName),
args);
} else {
diff --git a/src/com/android/settings/applications/manageapplications/ManageApplications.java b/src/com/android/settings/applications/manageapplications/ManageApplications.java
index 01289f2..1906a2d 100644
--- a/src/com/android/settings/applications/manageapplications/ManageApplications.java
+++ b/src/com/android/settings/applications/manageapplications/ManageApplications.java
@@ -29,6 +29,7 @@
import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_POWER_WHITELIST_ALL;
import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_RECENT;
import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_WORK;
+import static com.android.settings.search.actionbar.SearchMenuController.MENU_SEARCH;
import android.annotation.Nullable;
import android.annotation.StringRes;
@@ -99,6 +100,7 @@
import com.android.settings.applications.appinfo.WriteSettingsDetails;
import com.android.settings.core.InstrumentedFragment;
import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
import com.android.settings.fuelgauge.HighPowerDetail;
import com.android.settings.notification.AppNotificationSettings;
import com.android.settings.notification.ConfigureNotificationSettings;
@@ -141,9 +143,7 @@
public static final String EXTRA_VOLUME_UUID = "volumeUuid";
public static final String EXTRA_VOLUME_NAME = "volumeName";
public static final String EXTRA_STORAGE_TYPE = "storageType";
- public static final String EXTRA_WORK_ONLY = "workProfileOnly";
public static final String EXTRA_WORK_ID = "workId";
- public static final String EXTRA_PERSONAL_ONLY = "personalOnly";
private static final String EXTRA_SORT_ORDER = "sortOrder";
private static final String EXTRA_SHOW_SYSTEM = "showSystem";
@@ -310,8 +310,10 @@
}
final AppFilterRegistry appFilterRegistry = AppFilterRegistry.getInstance();
mFilter = appFilterRegistry.get(appFilterRegistry.getDefaultFilterType(mListType));
- mIsPersonalOnly = args != null ? args.getBoolean(EXTRA_PERSONAL_ONLY) : false;
- mIsWorkOnly = args != null ? args.getBoolean(EXTRA_WORK_ONLY) : false;
+ mIsPersonalOnly = args != null ? args.getInt(ProfileSelectFragment.EXTRA_PROFILE)
+ == ProfileSelectFragment.PERSONAL : false;
+ mIsWorkOnly = args != null ? args.getInt(ProfileSelectFragment.EXTRA_PROFILE)
+ == ProfileSelectFragment.WORK : false;
mWorkUserId = args != null ? args.getInt(EXTRA_WORK_ID) : NO_USER_SPECIFIED;
mExpandSearch = activity.getIntent().getBooleanExtra(EXTRA_EXPAND_SEARCH_VIEW, false);
@@ -696,6 +698,10 @@
// Hide notification menu items, because sorting happens when filtering
mOptionsMenu.findItem(R.id.sort_order_recent_notification).setVisible(false);
mOptionsMenu.findItem(R.id.sort_order_frequent_notification).setVisible(false);
+ final MenuItem searchItem = mOptionsMenu.findItem(MENU_SEARCH);
+ if (searchItem != null) {
+ searchItem.setVisible(false);
+ }
}
@Override
diff --git a/src/com/android/settings/dashboard/profileselector/ProfileSelectFragment.java b/src/com/android/settings/dashboard/profileselector/ProfileSelectFragment.java
index b7a1301..b8d4be1 100644
--- a/src/com/android/settings/dashboard/profileselector/ProfileSelectFragment.java
+++ b/src/com/android/settings/dashboard/profileselector/ProfileSelectFragment.java
@@ -22,13 +22,15 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;
import com.android.settings.R;
-import com.android.settings.core.InstrumentedFragment;
+import com.android.settings.dashboard.DashboardFragment;
import com.google.android.material.tabs.TabLayout;
@@ -38,7 +40,9 @@
/**
* Base fragment class for profile settings.
*/
-public abstract class ProfileSelectFragment extends InstrumentedFragment {
+public abstract class ProfileSelectFragment extends DashboardFragment {
+
+ private static final String TAG = "ProfileSelectFragment";
/**
* Denotes the profile type.
@@ -63,16 +67,29 @@
*/
public static final int ALL = PERSONAL | WORK;
- private View mContentView;
+ /**
+ * Used in fragment argument and pass {@link ProfileType} to it
+ */
+ public static final String EXTRA_PROFILE = "profile";
+
+ private ViewGroup mContentView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
- mContentView = inflater.inflate(R.layout.profile_select_tablayout, null /* root */);
- final ViewPager viewPager = mContentView.findViewById(R.id.view_pager);
- viewPager.setAdapter(new ViewPagerAdapter(this));
- final TabLayout tabs = mContentView.findViewById(R.id.tabs);
+ mContentView = (ViewGroup) super.onCreateView(inflater, container, savedInstanceState);
+
+ final View tabContainer = mContentView.findViewById(R.id.tab_container);
+ final ViewPager viewPager = tabContainer.findViewById(R.id.view_pager);
+ viewPager.setAdapter(new ProfileSelectFragment.ViewPagerAdapter(this));
+ final TabLayout tabs = tabContainer.findViewById(R.id.tabs);
tabs.setupWithViewPager(viewPager);
+ tabContainer.setVisibility(View.VISIBLE);
+
+ final FrameLayout listContainer = mContentView.findViewById(android.R.id.list_container);
+ listContainer.setLayoutParams(new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT));
return mContentView;
}
@@ -87,13 +104,23 @@
*/
public abstract Fragment[] getFragments();
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.dummy_preference_screen;
+ }
+
+ @Override
+ protected String getLogTag() {
+ return TAG;
+ }
+
static class ViewPagerAdapter extends FragmentStatePagerAdapter {
private final Fragment[] mChildFragments;
private final Context mContext;
ViewPagerAdapter(ProfileSelectFragment fragment) {
- super(fragment.getActivity().getSupportFragmentManager());
+ super(fragment.getChildFragmentManager());
mContext = fragment.getContext();
mChildFragments = fragment.getFragments();
}
diff --git a/src/com/android/settings/dashboard/profileselector/ProfileSelectManageApplications.java b/src/com/android/settings/dashboard/profileselector/ProfileSelectManageApplications.java
index 7290258..8a9e4f8 100644
--- a/src/com/android/settings/dashboard/profileselector/ProfileSelectManageApplications.java
+++ b/src/com/android/settings/dashboard/profileselector/ProfileSelectManageApplications.java
@@ -16,9 +16,6 @@
package com.android.settings.dashboard.profileselector;
-import static com.android.settings.applications.manageapplications.ManageApplications.EXTRA_PERSONAL_ONLY;
-import static com.android.settings.applications.manageapplications.ManageApplications.EXTRA_WORK_ONLY;
-
import android.os.Bundle;
import androidx.fragment.app.Fragment;
@@ -33,12 +30,12 @@
@Override
public Fragment[] getFragments() {
final Bundle workOnly = new Bundle();
- workOnly.putBoolean(EXTRA_WORK_ONLY, true);
+ workOnly.putInt(EXTRA_PROFILE, ProfileSelectFragment.WORK);
final Fragment workFragment = new ManageApplications();
workFragment.setArguments(workOnly);
final Bundle personalOnly = new Bundle();
- personalOnly.putBoolean(EXTRA_PERSONAL_ONLY, true);
+ personalOnly.putInt(EXTRA_PROFILE, ProfileSelectFragment.PERSONAL);
final Fragment personalFragment = new ManageApplications();
personalFragment.setArguments(personalOnly);
return new Fragment[]{
diff --git a/src/com/android/settings/dashboard/profileselector/ProfileSelectStorageFragment.java b/src/com/android/settings/dashboard/profileselector/ProfileSelectStorageFragment.java
index c7e4fd8..fccabb5 100644
--- a/src/com/android/settings/dashboard/profileselector/ProfileSelectStorageFragment.java
+++ b/src/com/android/settings/dashboard/profileselector/ProfileSelectStorageFragment.java
@@ -23,6 +23,7 @@
import androidx.fragment.app.Fragment;
+import com.android.settings.R;
import com.android.settings.deviceinfo.StorageDashboardFragment;
import com.android.settings.deviceinfo.StorageProfileFragment;
@@ -35,6 +36,7 @@
final Bundle storageBundle = new Bundle();
storageBundle.putString(VolumeInfo.EXTRA_VOLUME_ID, VolumeInfo.ID_PRIVATE_INTERNAL);
+ storageBundle.putInt(EXTRA_PROFILE, ProfileSelectFragment.PERSONAL);
final Fragment storageDashboardFragment = new StorageDashboardFragment();
storageDashboardFragment.setArguments(storageBundle);
@@ -46,7 +48,6 @@
break;
}
}
- // TODO(b/143330969): Need to think about more profile users case
if (targetUser != null) {
storageBundle.putInt(StorageProfileFragment.USER_ID_EXTRA, targetUser.id);
}
@@ -58,5 +59,10 @@
storageProfileFragment
};
}
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.storage_summary_donut;
+ }
}
diff --git a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
index 0e53333..b36ad43 100644
--- a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
+++ b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
@@ -33,16 +33,17 @@
import androidx.annotation.VisibleForTesting;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.Loader;
+import androidx.preference.Preference;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
import com.android.settings.deviceinfo.storage.AutomaticStorageManagementSwitchPreferenceController;
import com.android.settings.deviceinfo.storage.CachedStorageValuesHelper;
import com.android.settings.deviceinfo.storage.SecondaryUserController;
import com.android.settings.deviceinfo.storage.StorageAsyncLoader;
import com.android.settings.deviceinfo.storage.StorageItemPreferenceController;
-import com.android.settings.deviceinfo.storage.StorageSummaryDonutPreferenceController;
import com.android.settings.deviceinfo.storage.UserIconLoader;
import com.android.settings.deviceinfo.storage.VolumeSizesLoader;
import com.android.settings.search.BaseSearchIndexProvider;
@@ -62,6 +63,7 @@
implements
LoaderManager.LoaderCallbacks<SparseArray<StorageAsyncLoader.AppsStorageResult>> {
private static final String TAG = "StorageDashboardFrag";
+ private static final String SUMMARY_PREF_KEY = "pref_summary";
private static final int STORAGE_JOB_ID = 0;
private static final int ICON_JOB_ID = 1;
private static final int VOLUME_SIZE_JOB_ID = 2;
@@ -71,10 +73,10 @@
private SparseArray<StorageAsyncLoader.AppsStorageResult> mAppsResult;
private CachedStorageValuesHelper mCachedStorageValuesHelper;
- private StorageSummaryDonutPreferenceController mSummaryController;
private StorageItemPreferenceController mPreferenceController;
private PrivateVolumeOptionMenuController mOptionMenuController;
private List<AbstractPreferenceController> mSecondaryUsers;
+ private boolean mPersonalOnly;
@Override
public void onCreate(Bundle icicle) {
@@ -84,12 +86,19 @@
final Activity activity = getActivity();
StorageManager sm = activity.getSystemService(StorageManager.class);
mVolume = Utils.maybeInitializeVolume(sm, getArguments());
+ mPersonalOnly = getArguments().getInt(ProfileSelectFragment.EXTRA_PROFILE)
+ == ProfileSelectFragment.PERSONAL;
if (mVolume == null) {
activity.finish();
return;
}
-
initializeOptionsMenu(activity);
+ if (mPersonalOnly) {
+ final Preference summary = getPreferenceScreen().findPreference(SUMMARY_PREF_KEY);
+ if (summary != null) {
+ summary.setVisible(false);
+ }
+ }
}
@Override
@@ -119,7 +128,6 @@
null /* header view */)
.setRecyclerView(getListView(), getSettingsLifecycle())
.styleActionBar(activity);
-
}
@Override
@@ -140,7 +148,6 @@
boolean stopLoading = false;
if (mStorageInfo != null) {
long privateUsedBytes = mStorageInfo.totalBytes - mStorageInfo.freeBytes;
- mSummaryController.updateBytes(privateUsedBytes, mStorageInfo.totalBytes);
mPreferenceController.setVolume(mVolume);
mPreferenceController.setUsedSize(privateUsedBytes);
mPreferenceController.setTotalSize(mStorageInfo.totalBytes);
@@ -187,8 +194,6 @@
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
final List<AbstractPreferenceController> controllers = new ArrayList<>();
- mSummaryController = new StorageSummaryDonutPreferenceController(context);
- controllers.add(mSummaryController);
StorageManager sm = context.getSystemService(StorageManager.class);
mPreferenceController = new StorageItemPreferenceController(context, this,
@@ -241,7 +246,6 @@
final StorageManager sm = context.getSystemService(StorageManager.class);
final UserManager userManager = context.getSystemService(UserManager.class);
final List<AbstractPreferenceController> controllers = new ArrayList<>();
- controllers.add(new StorageSummaryDonutPreferenceController(context));
controllers.add(new StorageItemPreferenceController(context, null /* host */,
null /* volume */, new StorageManagerVolumeProvider(sm)));
controllers.addAll(SecondaryUserController.getSecondaryUserControllers(
diff --git a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
index 31898d1..26039fb 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
@@ -41,6 +41,7 @@
import com.android.settings.core.FeatureFlags;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
import com.android.settings.deviceinfo.PrivateVolumeSettings.SystemInfoFragment;
import com.android.settings.deviceinfo.StorageItemPreference;
import com.android.settings.overlay.FeatureFactory;
@@ -392,14 +393,15 @@
private Bundle getWorkAnnotatedBundle(int additionalCapacity) {
if (FeatureFlagUtils.isEnabled(mContext, FeatureFlags.PERSONAL_WORK_PROFILE)) {
- final Bundle args = new Bundle(3 + additionalCapacity);
- args.putBoolean(ManageApplications.EXTRA_WORK_ONLY, mIsWorkProfile);
+ final Bundle args = new Bundle(2 + additionalCapacity);
+ args.putInt(ProfileSelectFragment.EXTRA_PROFILE,
+ mIsWorkProfile ? ProfileSelectFragment.WORK : ProfileSelectFragment.PERSONAL);
args.putInt(ManageApplications.EXTRA_WORK_ID, mUserId);
- args.putBoolean(ManageApplications.EXTRA_PERSONAL_ONLY, !mIsWorkProfile);
return args;
} else {
final Bundle args = new Bundle(2 + additionalCapacity);
- args.putBoolean(ManageApplications.EXTRA_WORK_ONLY, mIsWorkProfile);
+ args.putInt(ProfileSelectFragment.EXTRA_PROFILE,
+ mIsWorkProfile ? ProfileSelectFragment.WORK : ProfileSelectFragment.ALL);
args.putInt(ManageApplications.EXTRA_WORK_ID, mUserId);
return args;
}
diff --git a/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceController.java
index d450a2a..d8ee711 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceController.java
@@ -17,6 +17,7 @@
package com.android.settings.deviceinfo.storage;
import android.content.Context;
+import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
import android.text.TextUtils;
import android.text.format.Formatter;
@@ -25,22 +26,29 @@
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
-import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.deviceinfo.PrivateStorageInfo;
+import com.android.settingslib.deviceinfo.StorageManagerVolumeProvider;
import com.android.settingslib.deviceinfo.StorageVolumeProvider;
+import com.android.settingslib.utils.ThreadUtils;
+
+import java.text.NumberFormat;
/**
- * StorgaeSummaryPreferenceController updates the donut storage summary preference to have the
+ * SummaryPreferenceController updates the donut storage summary preference to have the
* correct sizes showing.
*/
-public class StorageSummaryDonutPreferenceController extends AbstractPreferenceController implements
- PreferenceControllerMixin {
+public class StorageSummaryDonutPreferenceController extends BasePreferenceController {
private long mUsedBytes;
private long mTotalBytes;
private StorageSummaryDonutPreference mSummary;
+ private final StorageManager mStorageManager;
+ private final StorageManagerVolumeProvider mStorageManagerVolumeProvider;
- public StorageSummaryDonutPreferenceController(Context context) {
- super(context);
+ public StorageSummaryDonutPreferenceController(Context context, String key) {
+ super(context, key);
+ mStorageManager = mContext.getSystemService(StorageManager.class);
+ mStorageManagerVolumeProvider = new StorageManagerVolumeProvider(mStorageManager);
}
/**
@@ -58,19 +66,31 @@
@Override
public void displayPreference(PreferenceScreen screen) {
- mSummary = screen.findPreference("pref_summary");
+ mSummary = screen.findPreference(getPreferenceKey());
mSummary.setEnabled(true);
+
+ ThreadUtils.postOnBackgroundThread(() -> {
+ final NumberFormat percentageFormat = NumberFormat.getPercentInstance();
+ final PrivateStorageInfo info = PrivateStorageInfo.getPrivateStorageInfo(
+ mStorageManagerVolumeProvider);
+ final double privateUsedBytes = info.totalBytes - info.freeBytes;
+ mTotalBytes = info.totalBytes;
+ mUsedBytes = info.totalBytes - info.freeBytes;
+
+ ThreadUtils.postOnMainThread(() -> {
+ updateState(mSummary);
+ });
+ });
}
@Override
public void updateState(Preference preference) {
super.updateState(preference);
- StorageSummaryDonutPreference summary = (StorageSummaryDonutPreference) preference;
- summary.setTitle(convertUsedBytesToFormattedText(mContext, mUsedBytes));
- summary.setSummary(mContext.getString(R.string.storage_volume_total,
+ mSummary.setTitle(convertUsedBytesToFormattedText(mContext, mUsedBytes));
+ mSummary.setSummary(mContext.getString(R.string.storage_volume_total,
Formatter.formatShortFileSize(mContext, mTotalBytes)));
- summary.setPercent(mUsedBytes, mTotalBytes);
- summary.setEnabled(true);
+ mSummary.setPercent(mUsedBytes, mTotalBytes);
+ mSummary.setEnabled(true);
}
/** Invalidates the data on the view and re-renders. */
@@ -81,13 +101,8 @@
}
@Override
- public boolean isAvailable() {
- return true;
- }
-
- @Override
- public String getPreferenceKey() {
- return "pref_summary";
+ public int getAvailabilityStatus() {
+ return AVAILABLE;
}
/**
diff --git a/src/com/android/settings/fuelgauge/InactiveApps.java b/src/com/android/settings/fuelgauge/InactiveApps.java
index 6c8a954..c386a7d 100644
--- a/src/com/android/settings/fuelgauge/InactiveApps.java
+++ b/src/com/android/settings/fuelgauge/InactiveApps.java
@@ -67,7 +67,8 @@
super.onCreate(icicle);
mUsageStats = getActivity().getSystemService(UsageStatsManager.class);
- addPreferencesFromResource(R.xml.inactive_apps);
+ addPreferencesFromResource(R.xml.dummy_preference_screen);
+ getActivity().setTitle(R.string.inactive_apps_title);
}
@Override
diff --git a/src/com/android/settings/homepage/contextualcards/SettingsContextualCardProvider.java b/src/com/android/settings/homepage/contextualcards/SettingsContextualCardProvider.java
index 385f8cd..1494293 100644
--- a/src/com/android/settings/homepage/contextualcards/SettingsContextualCardProvider.java
+++ b/src/com/android/settings/homepage/contextualcards/SettingsContextualCardProvider.java
@@ -78,6 +78,12 @@
.setCardName(CustomSliceRegistry.FACE_ENROLL_SLICE_URI.toString())
.setCardCategory(ContextualCard.Category.DEFAULT)
.build();
+ final ContextualCard darkThemeCard =
+ ContextualCard.newBuilder()
+ .setSliceUri(CustomSliceRegistry.DARK_THEME_SLICE_URI.toString())
+ .setCardName(CustomSliceRegistry.DARK_THEME_SLICE_URI.toString())
+ .setCardCategory(ContextualCard.Category.IMPORTANT)
+ .build();
final ContextualCardList cards = ContextualCardList.newBuilder()
.addCard(wifiCard)
.addCard(connectedDeviceCard)
@@ -86,6 +92,7 @@
.addCard(notificationChannelCard)
.addCard(contextualAdaptiveSleepCard)
.addCard(contextualFaceSettingsCard)
+ .addCard(darkThemeCard)
.build();
return cards;
diff --git a/src/com/android/settings/homepage/contextualcards/slices/DarkThemeSlice.java b/src/com/android/settings/homepage/contextualcards/slices/DarkThemeSlice.java
new file mode 100644
index 0000000..36a3980
--- /dev/null
+++ b/src/com/android/settings/homepage/contextualcards/slices/DarkThemeSlice.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2019 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.homepage.contextualcards.slices;
+
+import static androidx.slice.builders.ListBuilder.ICON_IMAGE;
+
+import android.annotation.ColorInt;
+import android.app.PendingIntent;
+import android.app.UiModeManager;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.BatteryManager;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.core.graphics.drawable.IconCompat;
+import androidx.slice.Slice;
+import androidx.slice.builders.ListBuilder;
+import androidx.slice.builders.SliceAction;
+
+import com.android.settings.R;
+import com.android.settings.Utils;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settings.slices.CustomSliceRegistry;
+import com.android.settings.slices.CustomSliceable;
+
+public class DarkThemeSlice implements CustomSliceable {
+ private static final String TAG = "DarkThemeSlice";
+ private static final int BATTERY_LEVEL_THRESHOLD = 50;
+ private static final int DELAY_TIME_EXECUTING_DARK_THEME = 200;
+
+ // Keep the slice even Dark theme mode changed when it is on HomePage
+ @VisibleForTesting
+ static boolean sKeepSliceShow;
+ @VisibleForTesting
+ static long sActiveUiSession = -1000;
+
+ private final Context mContext;
+ private final UiModeManager mUiModeManager;
+
+ public DarkThemeSlice(Context context) {
+ mContext = context;
+ mUiModeManager = context.getSystemService(UiModeManager.class);
+ }
+
+ @Override
+ public Slice getSlice() {
+ final long currentUiSession = FeatureFactory.getFactory(mContext)
+ .getSlicesFeatureProvider().getUiSessionToken();
+ if (currentUiSession != sActiveUiSession) {
+ sActiveUiSession = currentUiSession;
+ sKeepSliceShow = false;
+ }
+ if (!sKeepSliceShow && !isAvailable(mContext)) {
+ return null;
+ }
+ sKeepSliceShow = true;
+ final PendingIntent toggleAction = getBroadcastIntent(mContext);
+ @ColorInt final int color = Utils.getColorAccentDefaultColor(mContext);
+ final IconCompat icon =
+ IconCompat.createWithResource(mContext, R.drawable.dark_theme);
+ final boolean isChecked = mUiModeManager.getNightMode() == UiModeManager.MODE_NIGHT_YES;
+ return new ListBuilder(mContext, CustomSliceRegistry.DARK_THEME_SLICE_URI,
+ ListBuilder.INFINITY)
+ .setAccentColor(color)
+ .addRow(new ListBuilder.RowBuilder()
+ .setTitle(mContext.getText(R.string.dark_theme_slice_title))
+ .setTitleItem(icon, ICON_IMAGE)
+ .setSubtitle(mContext.getText(R.string.dark_theme_slice_subtitle))
+ .setPrimaryAction(
+ SliceAction.createToggle(toggleAction, null /* actionTitle */,
+ isChecked)))
+ .build();
+ }
+
+ @Override
+ public Uri getUri() {
+ return CustomSliceRegistry.DARK_THEME_SLICE_URI;
+ }
+
+ @Override
+ public void onNotifyChange(Intent intent) {
+ final boolean isChecked = intent.getBooleanExtra(android.app.slice.Slice.EXTRA_TOGGLE_STATE,
+ false);
+ // make toggle transition more smooth before dark theme takes effect
+ new Handler(Looper.getMainLooper()).postDelayed(() -> {
+ mUiModeManager.setNightMode(
+ isChecked ? UiModeManager.MODE_NIGHT_YES : UiModeManager.MODE_NIGHT_NO);
+ }, DELAY_TIME_EXECUTING_DARK_THEME);
+ }
+
+ @Override
+ public Intent getIntent() {
+ return null;
+ }
+
+ @VisibleForTesting
+ boolean isAvailable(Context context) {
+ // checking dark theme mode.
+ if (mUiModeManager.getNightMode() == UiModeManager.MODE_NIGHT_YES) {
+ return false;
+ }
+
+ // checking the current battery level
+ final BatteryManager batteryManager = context.getSystemService(BatteryManager.class);
+ final int level = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
+ Log.d(TAG, "battery level=" + level);
+
+ return level <= BATTERY_LEVEL_THRESHOLD;
+ }
+}
diff --git a/src/com/android/settings/search/actionbar/SearchMenuController.java b/src/com/android/settings/search/actionbar/SearchMenuController.java
index 0243c09..9e22bbf 100644
--- a/src/com/android/settings/search/actionbar/SearchMenuController.java
+++ b/src/com/android/settings/search/actionbar/SearchMenuController.java
@@ -42,6 +42,7 @@
public class SearchMenuController implements LifecycleObserver, OnCreateOptionsMenu {
public static final String NEED_SEARCH_ICON_IN_ACTION_BAR = "need_search_icon_in_action_bar";
+ public static final int MENU_SEARCH = Menu.FIRST + 10;
private final Fragment mHost;
private final int mPageId;
@@ -80,7 +81,11 @@
if (arguments != null && !arguments.getBoolean(NEED_SEARCH_ICON_IN_ACTION_BAR, true)) {
return;
}
- final MenuItem searchItem = menu.add(Menu.NONE, Menu.NONE, 0 /* order */,
+ // menu contains search item, skip it
+ if (menu.findItem(MENU_SEARCH) != null) {
+ return;
+ }
+ final MenuItem searchItem = menu.add(Menu.NONE, MENU_SEARCH, 0 /* order */,
R.string.search_menu);
searchItem.setIcon(R.drawable.ic_search_24dp);
searchItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
diff --git a/src/com/android/settings/slices/CustomSliceRegistry.java b/src/com/android/settings/slices/CustomSliceRegistry.java
index d5b631a..a019687 100644
--- a/src/com/android/settings/slices/CustomSliceRegistry.java
+++ b/src/com/android/settings/slices/CustomSliceRegistry.java
@@ -37,6 +37,7 @@
import com.android.settings.homepage.contextualcards.slices.BluetoothDevicesSlice;
import com.android.settings.homepage.contextualcards.slices.ContextualAdaptiveSleepSlice;
import com.android.settings.homepage.contextualcards.slices.ContextualNotificationChannelSlice;
+import com.android.settings.homepage.contextualcards.slices.DarkThemeSlice;
import com.android.settings.homepage.contextualcards.slices.FaceSetupSlice;
import com.android.settings.homepage.contextualcards.slices.LowStorageSlice;
import com.android.settings.homepage.contextualcards.slices.NotificationChannelSlice;
@@ -332,6 +333,16 @@
.appendPath("media_output_indicator")
.build();
+ /**
+ * Backing Uri for the Dark theme Slice.
+ */
+ public static final Uri DARK_THEME_SLICE_URI = new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+ .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+ .appendPath("dark_theme")
+ .build();
+
@VisibleForTesting
static final Map<Uri, Class<? extends CustomSliceable>> sUriToSlice;
@@ -357,6 +368,7 @@
sUriToSlice.put(NOTIFICATION_CHANNEL_SLICE_URI, NotificationChannelSlice.class);
sUriToSlice.put(STORAGE_SLICE_URI, StorageSlice.class);
sUriToSlice.put(WIFI_SLICE_URI, WifiSlice.class);
+ sUriToSlice.put(DARK_THEME_SLICE_URI, DarkThemeSlice.class);
}
public static Class<? extends CustomSliceable> getSliceClassByUri(Uri uri) {
diff --git a/src/com/android/settings/widget/RadioButtonPickerFragment.java b/src/com/android/settings/widget/RadioButtonPickerFragment.java
index 3193afb..0f4fbc3 100644
--- a/src/com/android/settings/widget/RadioButtonPickerFragment.java
+++ b/src/com/android/settings/widget/RadioButtonPickerFragment.java
@@ -150,12 +150,10 @@
/**
* A chance for subclasses to bind additional things to the preference.
*/
- @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
public void bindPreferenceExtra(RadioButtonPreference pref,
String key, CandidateInfo info, String defaultKey, String systemDefaultKey) {
}
- @VisibleForTesting
public void updateCandidates() {
mCandidates.clear();
final List<? extends CandidateInfo> candidateList = getCandidates();
@@ -204,7 +202,6 @@
}
}
- @VisibleForTesting
public RadioButtonPreference bindPreference(RadioButtonPreference pref,
String key, CandidateInfo info, String defaultKey) {
pref.setTitle(info.loadLabel());
@@ -218,7 +215,6 @@
return pref;
}
- @VisibleForTesting
public void updateCheckedState(String selectedKey) {
final PreferenceScreen screen = getPreferenceScreen();
if (screen != null) {
@@ -236,7 +232,6 @@
}
}
- @VisibleForTesting
public void mayCheckOnlyRadioButton() {
final PreferenceScreen screen = getPreferenceScreen();
// If there is only 1 thing on screen, select it.
diff --git a/src/com/android/settings/wifi/NetworkRequestDialogActivity.java b/src/com/android/settings/wifi/NetworkRequestDialogActivity.java
index 1f2b221..2326a0e 100644
--- a/src/com/android/settings/wifi/NetworkRequestDialogActivity.java
+++ b/src/com/android/settings/wifi/NetworkRequestDialogActivity.java
@@ -26,12 +26,16 @@
import android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback;
import android.os.Bundle;
import android.os.Handler;
+import android.os.HandlerExecutor;
import android.os.Message;
import android.widget.Toast;
+
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity;
+
import com.android.settings.R;
import com.android.settings.wifi.NetworkRequestErrorDialogFragment.ERROR_DIALOG_TYPE;
+
import java.util.List;
/**
@@ -115,7 +119,7 @@
final WifiManager wifiManager = getSystemService(WifiManager.class);
if (wifiManager != null) {
- wifiManager.registerNetworkRequestMatchCallback(this, mHandler);
+ wifiManager.registerNetworkRequestMatchCallback(new HandlerExecutor(mHandler), this);
}
// Sets time-out to stop scanning.
mHandler.sendEmptyMessageDelayed(MESSAGE_STOP_SCAN_WIFI_LIST, DELAY_TIME_STOP_SCAN_MS);
diff --git a/src/com/android/settings/wifi/RequestToggleWiFiActivity.java b/src/com/android/settings/wifi/RequestToggleWiFiActivity.java
index 879a93e..034ec56 100644
--- a/src/com/android/settings/wifi/RequestToggleWiFiActivity.java
+++ b/src/com/android/settings/wifi/RequestToggleWiFiActivity.java
@@ -29,7 +29,6 @@
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
-import android.widget.Toast;
import androidx.annotation.NonNull;
@@ -313,11 +312,6 @@
finish();
}
} break;
-
- case WifiManager.ERROR: {
- Toast.makeText(activity, R.string.wifi_error, Toast.LENGTH_SHORT).show();
- finish();
- } break;
}
}
}
diff --git a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
index e9d2e08..c935b6a 100644
--- a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
+++ b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
@@ -781,6 +781,11 @@
}
private boolean canConnectNetwork() {
+ // Do not allow a cloned network to connect when out of range
+ // Otherwise it may create inconsistencies in the UI
+ if (mAccessPoint.isCloned() && mIsOutOfRange) {
+ return false;
+ }
// Display connect button for disconnected AP even not in the range.
return !mAccessPoint.isActive();
}
diff --git a/src/com/android/settings/wifi/p2p/WifiP2pSettings.java b/src/com/android/settings/wifi/p2p/WifiP2pSettings.java
index 3975170..8544a53 100644
--- a/src/com/android/settings/wifi/p2p/WifiP2pSettings.java
+++ b/src/com/android/settings/wifi/p2p/WifiP2pSettings.java
@@ -152,7 +152,7 @@
} else {
updateSearchMenu(false);
}
- } else if (WifiP2pManager.WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION.equals(action)) {
+ } else if (WifiP2pManager.ACTION_WIFI_P2P_PERSISTENT_GROUPS_CHANGED.equals(action)) {
if (mWifiP2pManager != null) {
mWifiP2pManager.requestPersistentGroupInfo(mChannel, WifiP2pSettings.this);
}
@@ -339,7 +339,7 @@
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION);
- mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION);
+ mIntentFilter.addAction(WifiP2pManager.ACTION_WIFI_P2P_PERSISTENT_GROUPS_CHANGED);
final PreferenceScreen preferenceScreen = getPreferenceScreen();
getActivity().registerReceiver(mReceiver, mIntentFilter);
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
index 73fea77..32c706c 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
@@ -16,15 +16,13 @@
package com.android.settings.deviceinfo.storage;
import static com.android.settings.applications.manageapplications.ManageApplications.EXTRA_WORK_ID;
-import static com.android.settings.applications.manageapplications.ManageApplications
- .EXTRA_WORK_ONLY;
import static com.android.settings.utils.FileSizeFormatter.MEGABYTE_IN_BYTES;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
@@ -51,6 +49,7 @@
import com.android.settings.SettingsActivity;
import com.android.settings.SubSettings;
import com.android.settings.applications.manageapplications.ManageApplications;
+import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
import com.android.settings.deviceinfo.PrivateVolumeSettings;
import com.android.settings.deviceinfo.StorageItemPreference;
import com.android.settings.testutils.FakeFeatureFactory;
@@ -195,8 +194,8 @@
.isEqualTo(R.string.apps_storage);
assertThat(
intent.getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS)
- .getBoolean(EXTRA_WORK_ONLY))
- .isTrue();
+ .getInt(ProfileSelectFragment.EXTRA_PROFILE))
+ .isEqualTo(ProfileSelectFragment.WORK);
assertThat(
intent.getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS)
.getInt(EXTRA_WORK_ID))
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceControllerTest.java
index 4f72318..cd6f082 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceControllerTest.java
@@ -37,24 +37,30 @@
import android.widget.Button;
import android.widget.LinearLayout;
+import androidx.preference.PreferenceScreen;
import androidx.preference.PreferenceViewHolder;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.shadow.ShadowPrivateStorageInfo;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+import com.android.settingslib.deviceinfo.PrivateStorageInfo;
import com.android.settingslib.deviceinfo.StorageVolumeProvider;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
import java.io.File;
@RunWith(RobolectricTestRunner.class)
+@Config(shadows = ShadowPrivateStorageInfo.class)
public class StorageSummaryDonutPreferenceControllerTest {
private Context mContext;
@@ -63,14 +69,18 @@
private PreferenceViewHolder mHolder;
private FakeFeatureFactory mFakeFeatureFactory;
private MetricsFeatureProvider mMetricsFeatureProvider;
+ private PreferenceScreen mScreen;
@Before
public void setUp() throws Exception {
+ ShadowPrivateStorageInfo.setPrivateStorageInfo(new PrivateStorageInfo(10L, 100L));
mContext = spy(Robolectric.setupActivity(Activity.class));
mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
mMetricsFeatureProvider = mFakeFeatureFactory.getMetricsFeatureProvider();
- mController = new StorageSummaryDonutPreferenceController(mContext);
+ mController = new StorageSummaryDonutPreferenceController(mContext, "key");
mPreference = new StorageSummaryDonutPreference(mContext);
+ mScreen = spy(new PreferenceScreen(mContext, null));
+ when(mScreen.findPreference("key")).thenReturn(mPreference);
LayoutInflater inflater = LayoutInflater.from(mContext);
final View view =
@@ -79,10 +89,16 @@
mHolder = PreferenceViewHolder.createInstanceForTests(view);
}
+ @After
+ public void tearDown() {
+ ShadowPrivateStorageInfo.reset();
+ }
+
@Test
public void testEmpty() {
final long totalSpace = 32 * GIGABYTE;
final long usedSpace = 0;
+ mController.displayPreference(mScreen);
mController.updateBytes(0, 32 * GIGABYTE);
mController.updateState(mPreference);
@@ -98,6 +114,7 @@
public void testTotalStorage() {
final long totalSpace = KILOBYTE * 10;
final long usedSpace = KILOBYTE;
+ mController.displayPreference(mScreen);
mController.updateBytes(KILOBYTE, totalSpace);
mController.updateState(mPreference);
@@ -121,6 +138,7 @@
when(file.getTotalSpace()).thenReturn(totalSpace);
when(file.getFreeSpace()).thenReturn(freeSpace);
when(svp.getPrimaryStorageSize()).thenReturn(totalSpace);
+ mController.displayPreference(mScreen);
mController.updateSizes(svp, volume);
mController.updateState(mPreference);
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/DarkThemeSliceTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/DarkThemeSliceTest.java
new file mode 100644
index 0000000..bb21332
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/DarkThemeSliceTest.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2019 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.homepage.contextualcards.slices;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.app.UiModeManager;
+import android.content.Context;
+import android.net.Uri;
+import android.os.BatteryManager;
+
+import androidx.slice.Slice;
+import androidx.slice.SliceMetadata;
+import androidx.slice.SliceProvider;
+import androidx.slice.widget.SliceLiveData;
+
+import com.android.settings.R;
+import com.android.settings.slices.CustomSliceRegistry;
+import com.android.settings.slices.SlicesFeatureProviderImpl;
+import com.android.settings.testutils.FakeFeatureFactory;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class DarkThemeSliceTest {
+ @Mock
+ private UiModeManager mUiModeManager;
+ @Mock
+ private BatteryManager mBatteryManager;
+
+ private Context mContext;
+ private DarkThemeSlice mDarkThemeSlice;
+ private FakeFeatureFactory mFeatureFactory;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = spy(RuntimeEnvironment.application);
+ mFeatureFactory = FakeFeatureFactory.setupForTest();
+ mFeatureFactory.slicesFeatureProvider = new SlicesFeatureProviderImpl();
+ mFeatureFactory.slicesFeatureProvider.newUiSession();
+ doReturn(mUiModeManager).when(mContext).getSystemService(UiModeManager.class);
+
+ // Set-up specs for SliceMetadata.
+ SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
+ mDarkThemeSlice = new DarkThemeSlice(mContext);
+ mDarkThemeSlice.sKeepSliceShow = false;
+ }
+
+ @Test
+ public void getUri_shouldBeDarkThemeSliceUri() {
+ final Uri uri = mDarkThemeSlice.getUri();
+
+ assertThat(uri).isEqualTo(CustomSliceRegistry.DARK_THEME_SLICE_URI);
+ }
+
+ @Test
+ public void isAvailable_inDarkThemeMode_returnFalse() {
+ when(mUiModeManager.getNightMode()).thenReturn(UiModeManager.MODE_NIGHT_YES);
+
+ assertThat(mDarkThemeSlice.isAvailable(mContext)).isFalse();
+ }
+
+ @Test
+ public void isAvailable_nonDarkThemeBatteryCapacityEq100_returnFalse() {
+ setBatteryCapacityLevel(100);
+
+ assertThat(mDarkThemeSlice.isAvailable(mContext)).isFalse();
+ }
+
+ @Test
+ public void isAvailable_nonDarkThemeBatteryCapacityLt50_returnTrue() {
+ setBatteryCapacityLevel(40);
+
+ assertThat(mDarkThemeSlice.isAvailable(mContext)).isTrue();
+ }
+
+ @Test
+ public void getSlice_notAvailable_returnNull() {
+ when(mUiModeManager.getNightMode()).thenReturn(UiModeManager.MODE_NIGHT_YES);
+
+ assertThat(mDarkThemeSlice.getSlice()).isNull();
+ }
+
+ @Test
+ public void getSlice_newSession_notAvailable_returnNull() {
+ // previous displayed: yes
+ mDarkThemeSlice.sKeepSliceShow = true;
+ // Session: use original value + 1 to become a new session
+ mDarkThemeSlice.sActiveUiSession =
+ mFeatureFactory.slicesFeatureProvider.getUiSessionToken() + 1;
+
+ when(mUiModeManager.getNightMode()).thenReturn(UiModeManager.MODE_NIGHT_YES);
+
+ assertThat(mDarkThemeSlice.getSlice()).isNull();
+ }
+
+ @Test
+ public void getSlice_previouslyDisplayed_isAvailable_returnSlice() {
+ mDarkThemeSlice.sActiveUiSession =
+ mFeatureFactory.slicesFeatureProvider.getUiSessionToken();
+ mDarkThemeSlice.sKeepSliceShow = true;
+ setBatteryCapacityLevel(40);
+
+ assertThat(mDarkThemeSlice.getSlice()).isNotNull();
+ }
+
+ @Test
+ public void getSlice_isAvailable_returnSlice() {
+ setBatteryCapacityLevel(40);
+
+ assertThat(mDarkThemeSlice.getSlice()).isNotNull();
+ }
+
+ @Test
+ public void getSlice_isAvailable_showTitleSubtitle() {
+ setBatteryCapacityLevel(40);
+
+ final Slice slice = mDarkThemeSlice.getSlice();
+ final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
+ assertThat(metadata.getTitle()).isEqualTo(
+ mContext.getString(R.string.dark_theme_slice_title));
+ assertThat(metadata.getSubtitle()).isEqualTo(
+ mContext.getString(R.string.dark_theme_slice_subtitle));
+ }
+
+ private void setBatteryCapacityLevel(int power_level) {
+ when(mUiModeManager.getNightMode()).thenReturn(UiModeManager.MODE_NIGHT_NO);
+ doReturn(mBatteryManager).when(mContext).getSystemService(BatteryManager.class);
+ when(mBatteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY))
+ .thenReturn(power_level);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/LowStorageSliceTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/LowStorageSliceTest.java
index 99f2723..c8ec57a 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/LowStorageSliceTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/LowStorageSliceTest.java
@@ -28,8 +28,8 @@
import androidx.slice.widget.SliceLiveData;
import com.android.settings.R;
+import com.android.settings.testutils.shadow.ShadowPrivateStorageInfo;
import com.android.settingslib.deviceinfo.PrivateStorageInfo;
-import com.android.settingslib.deviceinfo.StorageVolumeProvider;
import org.junit.After;
import org.junit.Before;
@@ -38,9 +38,6 @@
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-import org.robolectric.annotation.Resetter;
@RunWith(RobolectricTestRunner.class)
public class LowStorageSliceTest {
@@ -104,26 +101,4 @@
assertThat(slice.hasHint(HINT_ERROR)).isTrue();
}
-
- @Implements(PrivateStorageInfo.class)
- public static class ShadowPrivateStorageInfo {
-
- private static PrivateStorageInfo sPrivateStorageInfo = null;
-
- @Resetter
- public static void reset() {
- sPrivateStorageInfo = null;
- }
-
- @Implementation
- public static PrivateStorageInfo getPrivateStorageInfo(
- StorageVolumeProvider storageVolumeProvider) {
- return sPrivateStorageInfo;
- }
-
- private static void setPrivateStorageInfo(
- PrivateStorageInfo privateStorageInfo) {
- sPrivateStorageInfo = privateStorageInfo;
- }
- }
}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/search/actionbar/SearchMenuControllerTest.java b/tests/robotests/src/com/android/settings/search/actionbar/SearchMenuControllerTest.java
index e2b896a..c646a93 100644
--- a/tests/robotests/src/com/android/settings/search/actionbar/SearchMenuControllerTest.java
+++ b/tests/robotests/src/com/android/settings/search/actionbar/SearchMenuControllerTest.java
@@ -16,6 +16,8 @@
package com.android.settings.search.actionbar;
+import static com.android.settings.search.actionbar.SearchMenuController.MENU_SEARCH;
+
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
@@ -69,7 +71,7 @@
Global.putInt(mActivity.getContentResolver(), Global.DEVICE_PROVISIONED, 1);
when(mHost.getActivity()).thenReturn(mActivity);
- when(mMenu.add(Menu.NONE, Menu.NONE, 0 /* order */, R.string.search_menu))
+ when(mMenu.add(Menu.NONE, MENU_SEARCH, 0 /* order */, R.string.search_menu))
.thenReturn(mock(MenuItem.class));
}
@@ -78,7 +80,7 @@
SearchMenuController.init(mHost);
mHost.getSettingsLifecycle().onCreateOptionsMenu(mMenu, null /* inflater */);
- verify(mMenu).add(Menu.NONE, Menu.NONE, 0 /* order */, R.string.search_menu);
+ verify(mMenu).add(Menu.NONE, MENU_SEARCH, 0 /* order */, R.string.search_menu);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowPrivateStorageInfo.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowPrivateStorageInfo.java
new file mode 100644
index 0000000..1baf3cb
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowPrivateStorageInfo.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2019 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.testutils.shadow;
+
+import com.android.settingslib.deviceinfo.PrivateStorageInfo;
+import com.android.settingslib.deviceinfo.StorageVolumeProvider;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.Resetter;
+
+@Implements(PrivateStorageInfo.class)
+public class ShadowPrivateStorageInfo {
+
+ private static PrivateStorageInfo sPrivateStorageInfo = null;
+
+ @Resetter
+ public static void reset() {
+ sPrivateStorageInfo = null;
+ }
+
+ @Implementation
+ protected static PrivateStorageInfo getPrivateStorageInfo(
+ StorageVolumeProvider storageVolumeProvider) {
+ return sPrivateStorageInfo;
+ }
+
+ public static void setPrivateStorageInfo(
+ PrivateStorageInfo privateStorageInfo) {
+ sPrivateStorageInfo = privateStorageInfo;
+ }
+}