Merge "Move search resources to settingslib-search"
diff --git a/res/drawable-nodpi/gesture_ambient_reach b/res/drawable-nodpi/gesture_ambient_wake_lock_screen
similarity index 100%
rename from res/drawable-nodpi/gesture_ambient_reach
rename to res/drawable-nodpi/gesture_ambient_wake_lock_screen
diff --git a/res/raw/gesture_ambient_reach.mp4 b/res/raw/gesture_ambient_wake_lock_screen.mp4
similarity index 100%
rename from res/raw/gesture_ambient_reach.mp4
rename to res/raw/gesture_ambient_wake_lock_screen.mp4
diff --git a/res/values/strings.xml b/res/values/strings.xml
index db08953..3f4cd8d 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -9583,10 +9583,10 @@
<!-- Summary text for ambient display (device) [CHAR LIMIT=NONE]-->
<string name="ambient_display_pickup_summary" product="device">To check time, notifications, and other info, pick up your device.</string>
- <!-- Preference and settings suggestion title text for reach gesture [CHAR LIMIT=60]-->
- <string name="ambient_display_reach_title">Reach gesture</string>
+ <!-- Preference and settings suggestion title text for gesture that shows the lock screen [CHAR LIMIT=60]-->
+ <string name="ambient_display_wake_lock_screen_title">Wake lock screen gesture</string>
<!-- Summary text for ambient display [CHAR LIMIT=NONE]-->
- <string name="ambient_display_reach_summary" product="default"></string>
+ <string name="ambient_display_wake_lock_screen_summary" product="default"></string>
<!-- Title text for swiping downwards on fingerprint sensor for notifications [CHAR LIMIT=80]-->
<string name="fingerprint_swipe_for_notifications_title">Swipe fingerprint for notifications</string>
@@ -9939,6 +9939,13 @@
<!-- UI debug setting: preference summary - describes the behavior of showing a dialog every time an app crashes [CHAR LIMIT=NONE] -->
<string name="show_first_crash_dialog_summary">Show dialog every time an app crashes</string>
+ <!-- UI debug setting: select current app to use ANGLE [CHAR LIMIT=100] -->
+ <string name="angle_enabled_app">Select ANGLE enabled app</string>
+ <!-- UI debug setting: no ANGLE enabled app has been set [CHAR LIMIT=100] -->
+ <string name="angle_enabled_app_not_set">No ANGLE enabled application set</string>
+ <!-- UI debug setting: ANGLE enabled app has been set [CHAR LIMIT=NONE] -->
+ <string name="angle_enabled_app_set">ANGLE enabled application: <xliff:g id="app_name" example="com.company.app">%1$s</xliff:g></string>
+
<!-- Title for Directory Access settings -->
<string name="directory_access">Directory access</string>
<!-- Keywords for Directory Access settings -->
diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml
index 5b6d215..5a36463 100644
--- a/res/xml/development_settings.xml
+++ b/res/xml/development_settings.xml
@@ -424,6 +424,9 @@
android:summary="%s"
android:title="@string/simulate_color_space" />
+ <Preference android:key="angle_enabled_app"
+ android:title="@string/angle_enabled_app" />
+
</PreferenceCategory>
<PreferenceCategory
diff --git a/res/xml/gestures.xml b/res/xml/gestures.xml
index aa99446..211157c 100644
--- a/res/xml/gestures.xml
+++ b/res/xml/gestures.xml
@@ -28,10 +28,10 @@
settings:controller="com.android.settings.gestures.AssistGestureSettingsPreferenceController" />
<Preference
- android:key="gesture_reach_summary"
- android:title="@string/ambient_display_reach_title"
- android:fragment="com.android.settings.gestures.ReachGestureSettings"
- settings:controller="com.android.settings.gestures.ReachGesturePreferenceController" />
+ android:key="gesture_wake_lock_screen_summary"
+ android:title="@string/ambient_display_wake_lock_screen_title"
+ android:fragment="com.android.settings.gestures.WakeLockScreenGestureSettings"
+ settings:controller="com.android.settings.gestures.WakeLockScreenGesturePreferenceController" />
<Preference
android:key="gesture_swipe_down_fingerprint_input_summary"
diff --git a/res/xml/reach_gesture_settings.xml b/res/xml/wake_lock_screen_gesture_settings.xml
similarity index 62%
rename from res/xml/reach_gesture_settings.xml
rename to res/xml/wake_lock_screen_gesture_settings.xml
index e933e15..5491bb1 100644
--- a/res/xml/reach_gesture_settings.xml
+++ b/res/xml/wake_lock_screen_gesture_settings.xml
@@ -18,20 +18,20 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
- android:key="gesture_reach_screen"
- android:title="@string/ambient_display_reach_title">
+ android:key="gesture_wake_lock_screen_screen"
+ android:title="@string/ambient_display_wake_lock_screen_title">
<com.android.settings.widget.VideoPreference
- android:key="gesture_reach_video"
- app:animation="@raw/gesture_ambient_reach"
- app:preview="@drawable/gesture_ambient_reach" />
+ android:key="gesture_wake_lock_screen_video"
+ app:animation="@raw/gesture_ambient_wake_lock_screen"
+ app:preview="@drawable/gesture_ambient_wake_lock_screen" />
<SwitchPreference
- android:key="gesture_reach"
- android:title="@string/ambient_display_reach_title"
- android:summary="@string/ambient_display_reach_summary"
+ android:key="gesture_wake_lock_screen"
+ android:title="@string/ambient_display_wake_lock_screen_title"
+ android:summary="@string/ambient_display_wake_lock_screen_summary"
app:keywords="@string/keywords_gesture"
- app:controller="com.android.settings.gestures.ReachGesturePreferenceController"
+ app:controller="com.android.settings.gestures.WakeLockScreenGesturePreferenceController"
app:allowDividerAbove="true" />
</PreferenceScreen>
\ No newline at end of file
diff --git a/src/com/android/settings/datausage/AppDataUsageV2.java b/src/com/android/settings/datausage/AppDataUsageV2.java
new file mode 100644
index 0000000..6d6089e
--- /dev/null
+++ b/src/com/android/settings/datausage/AppDataUsageV2.java
@@ -0,0 +1,451 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.settings.datausage;
+
+import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
+
+import android.app.Activity;
+import android.content.Context;
+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;
+import android.util.Log;
+import android.view.View;
+import android.widget.AdapterView;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.loader.app.LoaderManager;
+import androidx.loader.content.Loader;
+import androidx.preference.Preference;
+import androidx.preference.Preference.OnPreferenceChangeListener;
+import androidx.preference.PreferenceCategory;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.R;
+import com.android.settings.applications.AppInfoBase;
+import com.android.settings.widget.EntityHeaderController;
+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.UidDetail;
+import com.android.settingslib.net.UidDetailProvider;
+
+public class AppDataUsageV2 extends DataUsageBaseFragment implements OnPreferenceChangeListener,
+ DataSaverBackend.Listener {
+
+ private static final String TAG = "AppDataUsageV2";
+
+ public static final String ARG_APP_ITEM = "app_item";
+ public static final String ARG_NETWORK_TEMPLATE = "network_template";
+
+ private static final String KEY_TOTAL_USAGE = "total_usage";
+ private static final String KEY_FOREGROUND_USAGE = "foreground_usage";
+ private static final String KEY_BACKGROUND_USAGE = "background_usage";
+ private static final String KEY_APP_SETTINGS = "app_settings";
+ private static final String KEY_RESTRICT_BACKGROUND = "restrict_background";
+ private static final String KEY_APP_LIST = "app_list";
+ 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_PREF = 3;
+
+ private PackageManager mPackageManager;
+ private final ArraySet<String> mPackages = new ArraySet<>();
+ private Preference mTotalUsage;
+ private Preference mForegroundUsage;
+ private Preference mBackgroundUsage;
+ private Preference mAppSettings;
+ private RestrictedSwitchPreference mRestrictBackground;
+ private PreferenceCategory mAppList;
+
+ 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 NetworkTemplate mTemplate;
+ private NetworkPolicy mPolicy;
+ private AppItem mAppItem;
+ private Intent mAppSettingsIntent;
+ private SpinnerPreference mCycle;
+ private RestrictedSwitchPreference mUnrestrictedData;
+ private DataSaverBackend mDataSaverBackend;
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ 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;
+ if (mTemplate == null) {
+ Context context = getContext();
+ mTemplate = DataUsageUtils.getDefaultTemplate(context,
+ DataUsageUtils.getDefaultSubscriptionId(context));
+ }
+ if (mAppItem == null) {
+ int uid = (args != null) ? args.getInt(AppInfoBase.ARG_PACKAGE_UID, -1)
+ : getActivity().getIntent().getIntExtra(AppInfoBase.ARG_PACKAGE_UID, -1);
+ if (uid == -1) {
+ // TODO: Log error.
+ getActivity().finish();
+ } else {
+ addUid(uid);
+ mAppItem = new AppItem(uid);
+ mAppItem.addUid(uid);
+ }
+ } else {
+ for (int i = 0; i < mAppItem.uids.size(); i++) {
+ addUid(mAppItem.uids.keyAt(i));
+ }
+ }
+
+ mTotalUsage = findPreference(KEY_TOTAL_USAGE);
+ mForegroundUsage = findPreference(KEY_FOREGROUND_USAGE);
+ mBackgroundUsage = findPreference(KEY_BACKGROUND_USAGE);
+
+ mCycle = (SpinnerPreference) findPreference(KEY_CYCLE);
+ mCycleAdapter = new CycleAdapter(getContext(), mCycle, mCycleListener, false);
+
+ if (mAppItem.key > 0) {
+ if (mPackages.size() != 0) {
+ try {
+ ApplicationInfo info = mPackageManager.getApplicationInfoAsUser(
+ mPackages.valueAt(0), 0, UserHandle.getUserId(mAppItem.key));
+ mIcon = IconDrawableFactory.newInstance(getActivity()).getBadgedIcon(info);
+ mLabel = info.loadLabel(mPackageManager);
+ mPackageName = info.packageName;
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+ }
+ if (!UserHandle.isApp(mAppItem.key)) {
+ removePreference(KEY_UNRESTRICTED_DATA);
+ removePreference(KEY_RESTRICT_BACKGROUND);
+ } else {
+ mRestrictBackground = (RestrictedSwitchPreference) findPreference(
+ KEY_RESTRICT_BACKGROUND);
+ mRestrictBackground.setOnPreferenceChangeListener(this);
+ mUnrestrictedData = (RestrictedSwitchPreference) findPreference(
+ KEY_UNRESTRICTED_DATA);
+ mUnrestrictedData.setOnPreferenceChangeListener(this);
+ }
+ mDataSaverBackend = new DataSaverBackend(getContext());
+ mAppSettings = findPreference(KEY_APP_SETTINGS);
+
+ mAppSettingsIntent = new Intent(Intent.ACTION_MANAGE_NETWORK_USAGE);
+ mAppSettingsIntent.addCategory(Intent.CATEGORY_DEFAULT);
+
+ PackageManager pm = getPackageManager();
+ boolean matchFound = false;
+ for (String packageName : mPackages) {
+ mAppSettingsIntent.setPackage(packageName);
+ if (pm.resolveActivity(mAppSettingsIntent, 0) != null) {
+ matchFound = true;
+ break;
+ }
+ }
+ if (!matchFound) {
+ removePreference(KEY_APP_SETTINGS);
+ mAppSettings = null;
+ }
+
+ if (mPackages.size() > 1) {
+ mAppList = (PreferenceCategory) findPreference(KEY_APP_LIST);
+ getLoaderManager().initLoader(LOADER_APP_PREF, Bundle.EMPTY, mAppPrefCallbacks);
+ } else {
+ removePreference(KEY_APP_LIST);
+ }
+ } else {
+ final Context context = getActivity();
+ UidDetail uidDetail = new UidDetailProvider(context).getUidDetail(mAppItem.key, true);
+ mIcon = uidDetail.icon;
+ mLabel = uidDetail.label;
+ mPackageName = context.getPackageName();
+
+ removePreference(KEY_UNRESTRICTED_DATA);
+ removePreference(KEY_APP_SETTINGS);
+ removePreference(KEY_RESTRICT_BACKGROUND);
+ removePreference(KEY_APP_LIST);
+ }
+ }
+
+ @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);
+ updatePrefs();
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ if (mDataSaverBackend != null) {
+ mDataSaverBackend.remListener(this);
+ }
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ if (preference == mRestrictBackground) {
+ mDataSaverBackend.setIsBlacklisted(mAppItem.key, mPackageName, !(Boolean) newValue);
+ updatePrefs();
+ return true;
+ } else if (preference == mUnrestrictedData) {
+ mDataSaverBackend.setIsWhitelisted(mAppItem.key, mPackageName, (Boolean) newValue);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean onPreferenceTreeClick(Preference preference) {
+ if (preference == mAppSettings) {
+ // TODO: target towards entire UID instead of just first package
+ getActivity().startActivityAsUser(mAppSettingsIntent, new UserHandle(
+ UserHandle.getUserId(mAppItem.key)));
+ return true;
+ }
+ return super.onPreferenceTreeClick(preference);
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.app_data_usage;
+ }
+
+ @Override
+ protected String getLogTag() {
+ return TAG;
+ }
+
+ @VisibleForTesting
+ void updatePrefs() {
+ updatePrefs(getAppRestrictBackground(), getUnrestrictData());
+ }
+
+ private void updatePrefs(boolean restrictBackground, boolean unrestrictData) {
+ final EnforcedAdmin admin = RestrictedLockUtilsInternal.checkIfMeteredDataRestricted(
+ getContext(), mPackageName, UserHandle.getUserId(mAppItem.key));
+ if (mRestrictBackground != null) {
+ mRestrictBackground.setChecked(!restrictBackground);
+ mRestrictBackground.setDisabledByAdmin(admin);
+ }
+ if (mUnrestrictedData != null) {
+ if (restrictBackground) {
+ mUnrestrictedData.setVisible(false);
+ } else {
+ mUnrestrictedData.setVisible(true);
+ mUnrestrictedData.setChecked(unrestrictData);
+ mUnrestrictedData.setDisabledByAdmin(admin);
+ }
+ }
+ }
+
+ private void addUid(int uid) {
+ String[] packages = getPackageManager().getPackagesForUid(uid);
+ if (packages != null) {
+ for (int i = 0; i < packages.length; i++) {
+ mPackages.add(packages[i]);
+ }
+ }
+ }
+
+ private void bindData() {
+ final long backgroundBytes, foregroundBytes;
+ if (mChartData == null || mStart == 0) {
+ 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 long totalBytes = backgroundBytes + foregroundBytes;
+ final Context context = getContext();
+
+ mTotalUsage.setSummary(DataUsageUtils.formatDataUsage(context, totalBytes));
+ mForegroundUsage.setSummary(DataUsageUtils.formatDataUsage(context, foregroundBytes));
+ mBackgroundUsage.setSummary(DataUsageUtils.formatDataUsage(context, backgroundBytes));
+ }
+
+ private boolean getAppRestrictBackground() {
+ final int uid = mAppItem.key;
+ final int uidPolicy = services.mPolicyManager.getUidPolicy(uid);
+ return (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0;
+ }
+
+ private boolean getUnrestrictData() {
+ if (mDataSaverBackend != null) {
+ return mDataSaverBackend.isWhitelisted(mAppItem.key);
+ }
+ return false;
+ }
+
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+
+ String pkg = mPackages.size() != 0 ? mPackages.valueAt(0) : null;
+ int uid = 0;
+ if (pkg != null) {
+ try {
+ uid = mPackageManager.getPackageUidAsUser(pkg,
+ UserHandle.getUserId(mAppItem.key));
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.w(TAG, "Skipping UID because cannot find package " + pkg);
+ }
+ }
+
+ final boolean showInfoButton = mAppItem.key > 0;
+
+ final Activity activity = getActivity();
+ final Preference pref = EntityHeaderController
+ .newInstance(activity, this, null /* header */)
+ .setRecyclerView(getListView(), getSettingsLifecycle())
+ .setUid(uid)
+ .setHasAppInfoLink(showInfoButton)
+ .setButtonActions(EntityHeaderController.ActionType.ACTION_NONE,
+ EntityHeaderController.ActionType.ACTION_NONE)
+ .setIcon(mIcon)
+ .setLabel(mLabel)
+ .setPackageName(pkg)
+ .done(activity, getPrefContext());
+ getPreferenceScreen().addPreference(pref);
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsEvent.APP_DATA_USAGE;
+ }
+
+ private AdapterView.OnItemSelectedListener mCycleListener =
+ 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();
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView<?> parent) {
+ // ignored
+ }
+ };
+
+ private final LoaderManager.LoaderCallbacks<ChartData> mChartDataCallbacks =
+ new LoaderManager.LoaderCallbacks<ChartData>() {
+ @Override
+ public Loader<ChartData> onCreateLoader(int id, Bundle args) {
+ return new ChartDataLoaderCompat(getActivity(), mStatsSession, args);
+ }
+
+ @Override
+ public void onLoadFinished(Loader<ChartData> loader, ChartData data) {
+ mChartData = data;
+ mCycleAdapter.updateCycleList(mPolicy, mChartData);
+ bindData();
+ }
+
+ @Override
+ public void onLoaderReset(Loader<ChartData> loader) {
+ }
+ };
+
+ private final LoaderManager.LoaderCallbacks<ArraySet<Preference>> mAppPrefCallbacks =
+ new LoaderManager.LoaderCallbacks<ArraySet<Preference>>() {
+ @Override
+ public Loader<ArraySet<Preference>> onCreateLoader(int i, Bundle bundle) {
+ return new AppPrefLoader(getPrefContext(), mPackages, getPackageManager());
+ }
+
+ @Override
+ public void onLoadFinished(Loader<ArraySet<Preference>> loader,
+ ArraySet<Preference> preferences) {
+ if (preferences != null && mAppList != null) {
+ for (Preference preference : preferences) {
+ mAppList.addPreference(preference);
+ }
+ }
+ }
+
+ @Override
+ public void onLoaderReset(Loader<ArraySet<Preference>> loader) {
+ }
+ };
+
+ @Override
+ public void onDataSaverChanged(boolean isDataSaving) {
+
+ }
+
+ @Override
+ public void onWhitelistStatusChanged(int uid, boolean isWhitelisted) {
+ if (mAppItem.uids.get(uid, false)) {
+ updatePrefs(getAppRestrictBackground(), isWhitelisted);
+ }
+ }
+
+ @Override
+ public void onBlacklistStatusChanged(int uid, boolean isBlacklisted) {
+ if (mAppItem.uids.get(uid, false)) {
+ updatePrefs(isBlacklisted, getUnrestrictData());
+ }
+ }
+}
diff --git a/src/com/android/settings/datausage/ChartDataUsagePreference.java b/src/com/android/settings/datausage/ChartDataUsagePreference.java
index 321cf74..a0cef3a 100644
--- a/src/com/android/settings/datausage/ChartDataUsagePreference.java
+++ b/src/com/android/settings/datausage/ChartDataUsagePreference.java
@@ -24,7 +24,6 @@
import android.text.style.ForegroundColorSpan;
import android.util.AttributeSet;
import android.util.FeatureFlagUtils;
-import android.util.Pair;
import android.util.SparseIntArray;
import androidx.annotation.VisibleForTesting;
@@ -35,6 +34,7 @@
import com.android.settings.Utils;
import com.android.settings.core.FeatureFlags;
import com.android.settings.widget.UsageView;
+import com.android.settingslib.net.NetworkCycleChartData;
import com.android.settingslib.net.NetworkCycleData;
import java.util.List;
@@ -53,7 +53,7 @@
private long mEnd;
@Deprecated
private NetworkStatsHistory mNetwork;
- private NetworkCycleData mNetworkCycleData;
+ private NetworkCycleChartData mNetworkCycleChartData;
private int mSecondaryColor;
private int mSeriesColor;
@@ -70,7 +70,7 @@
super.onBindViewHolder(holder);
final UsageView chart = (UsageView) holder.findViewById(R.id.data_usage);
if (FeatureFlagUtils.isEnabled(getContext(), FeatureFlags.DATA_USAGE_V2)) {
- if (mNetworkCycleData == null) {
+ if (mNetworkCycleChartData == null) {
return;
}
} else {
@@ -83,7 +83,7 @@
chart.clearPaths();
chart.configureGraph(toInt(mEnd - mStart), top);
if (FeatureFlagUtils.isEnabled(getContext(), FeatureFlags.DATA_USAGE_V2)) {
- calcPoints(chart, mNetworkCycleData.usageBuckets);
+ calcPoints(chart, mNetworkCycleChartData.getUsageBuckets());
} else {
calcPoints(chart);
}
@@ -98,7 +98,7 @@
public int getTop() {
long totalData = 0;
if (FeatureFlagUtils.isEnabled(getContext(), FeatureFlags.DATA_USAGE_V2)) {
- totalData = mNetworkCycleData.totalUsage;
+ totalData = mNetworkCycleChartData.getTotalUsage();
} else {
NetworkStatsHistory.Entry entry = null;
final int start = mNetwork.getIndexBefore(mStart);
@@ -158,14 +158,14 @@
long totalData = 0;
for (NetworkCycleData data : usageSummary) {
- final long startTime = data.startTime;
- final long endTime = data.endTime;
+ final long startTime = data.getStartTime();
+ final long endTime = data.getEndTime();
// increment by current bucket total
- totalData += data.totalUsage;
+ totalData += data.getTotalUsage();
if (points.size() == 1) {
- points.put(toInt(data.startTime - mStart) - 1, -1);
+ points.put(toInt(startTime - mStart) - 1, -1);
}
points.put(toInt(startTime - mStart + 1), (int) (totalData / RESOLUTION));
points.put(toInt(endTime - mStart), (int) (totalData / RESOLUTION));
@@ -241,10 +241,10 @@
notifyChanged();
}
- public void setNetworkCycleData(NetworkCycleData data) {
- mNetworkCycleData = data;
- mStart = data.startTime;
- mEnd = data.endTime;
+ public void setNetworkCycleData(NetworkCycleChartData data) {
+ mNetworkCycleChartData = data;
+ mStart = data.getStartTime();
+ mEnd = data.getEndTime();
notifyChanged();
}
diff --git a/src/com/android/settings/datausage/CycleAdapter.java b/src/com/android/settings/datausage/CycleAdapter.java
index bc4f649..9378dea 100644
--- a/src/com/android/settings/datausage/CycleAdapter.java
+++ b/src/com/android/settings/datausage/CycleAdapter.java
@@ -156,7 +156,7 @@
* Rebuild list based on network data. Always selects the newest item,
* updating the inspection range on chartData.
*/
- public boolean updateCycleList(List<NetworkCycleData> cycleData) {
+ public boolean updateCycleList(List<? extends NetworkCycleData> cycleData) {
// stash away currently selected cycle to try restoring below
final CycleAdapter.CycleItem previousItem = (CycleAdapter.CycleItem)
mSpinner.getSelectedItem();
@@ -164,7 +164,7 @@
final Context context = getContext();
for (NetworkCycleData data : cycleData) {
- add(new CycleAdapter.CycleItem(context, data.startTime, data.endTime));
+ add(new CycleAdapter.CycleItem(context, data.getStartTime(), data.getEndTime()));
}
// force pick the current cycle (first item)
diff --git a/src/com/android/settings/datausage/DataUsageListV2.java b/src/com/android/settings/datausage/DataUsageListV2.java
index 301eb44..ea652b3 100644
--- a/src/com/android/settings/datausage/DataUsageListV2.java
+++ b/src/com/android/settings/datausage/DataUsageListV2.java
@@ -61,8 +61,8 @@
import com.android.settings.widget.LoadingViewController;
import com.android.settingslib.AppItem;
import com.android.settingslib.net.ChartDataLoaderCompat;
-import com.android.settingslib.net.NetworkCycleDataLoader;
-import com.android.settingslib.net.NetworkCycleData;
+import com.android.settingslib.net.NetworkCycleChartDataLoader;
+import com.android.settingslib.net.NetworkCycleChartData;
import com.android.settingslib.net.NetworkStatsSummaryLoader;
import com.android.settingslib.net.UidDetailProvider;
@@ -107,7 +107,7 @@
int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
@VisibleForTesting
int mNetworkType;
- private List<NetworkCycleData> mCycleData;
+ private List<NetworkCycleChartData> mCycleData;
private LoadingViewController mLoadingViewController;
private UidDetailProvider mUidDetailProvider;
@@ -322,7 +322,7 @@
mNetworkStatsDetailCallbacks);
final long totalBytes = mCycleData != null
- ? mCycleData.get(mCycleSpinner.getSelectedItemPosition()).totalUsage : 0;
+ ? mCycleData.get(mCycleSpinner.getSelectedItemPosition()).getTotalUsage() : 0;
final CharSequence totalPhrase = DataUsageUtils.formatDataUsage(getActivity(), totalBytes);
mUsageAmount.setTitle(getString(R.string.data_used_template, totalPhrase));
}
@@ -485,11 +485,11 @@
}
};
- private final LoaderCallbacks<List<NetworkCycleData>> mNetworkCycleDataCallbacks =
- new LoaderCallbacks<List<NetworkCycleData>>() {
+ private final LoaderCallbacks<List<NetworkCycleChartData>> mNetworkCycleDataCallbacks =
+ new LoaderCallbacks<List<NetworkCycleChartData>>() {
@Override
- public Loader<List<NetworkCycleData>> onCreateLoader(int id, Bundle args) {
- return new NetworkCycleDataLoader.Builder(getContext())
+ public Loader<List<NetworkCycleChartData>> onCreateLoader(int id, Bundle args) {
+ return NetworkCycleChartDataLoader.builder(getContext())
.setNetworkPolicy(services.mPolicyEditor.getPolicy(mTemplate))
.setNetworkType(mNetworkType)
.setNetworkTemplate(mTemplate)
@@ -498,8 +498,8 @@
}
@Override
- public void onLoadFinished(Loader<List<NetworkCycleData>> loader,
- List<NetworkCycleData> data) {
+ public void onLoadFinished(Loader<List<NetworkCycleChartData>> loader,
+ List<NetworkCycleChartData> data) {
mLoadingViewController.showContent(false /* animate */);
mCycleData = data;
// calculate policy cycles based on available data
@@ -507,7 +507,7 @@
}
@Override
- public void onLoaderReset(Loader<List<NetworkCycleData>> loader) {
+ public void onLoaderReset(Loader<List<NetworkCycleChartData>> loader) {
mCycleData = null;
}
};
diff --git a/src/com/android/settings/development/AngleEnabledAppPreferenceController.java b/src/com/android/settings/development/AngleEnabledAppPreferenceController.java
new file mode 100644
index 0000000..3a7f6bf
--- /dev/null
+++ b/src/com/android/settings/development/AngleEnabledAppPreferenceController.java
@@ -0,0 +1,119 @@
+/*
+ * 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.development;
+
+import static com.android.settings.development.DevelopmentOptionsActivityRequestCodes
+ .REQUEST_CODE_ANGLE_ENABLED_APP;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.provider.Settings;
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+
+import com.android.settings.R;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.development.DeveloperOptionsPreferenceController;
+
+public class AngleEnabledAppPreferenceController extends DeveloperOptionsPreferenceController
+ implements PreferenceControllerMixin, OnActivityResultListener {
+
+ private static final String ANGLE_ENABLED_APP_KEY = "angle_enabled_app";
+
+ private final DevelopmentSettingsDashboardFragment mFragment;
+ private final PackageManager mPackageManager;
+
+ public AngleEnabledAppPreferenceController(Context context,
+ DevelopmentSettingsDashboardFragment fragment) {
+ super(context);
+ mFragment = fragment;
+ mPackageManager = mContext.getPackageManager();
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return ANGLE_ENABLED_APP_KEY;
+ }
+
+ @Override
+ public boolean handlePreferenceTreeClick(Preference preference) {
+ if (ANGLE_ENABLED_APP_KEY.equals(preference.getKey())) {
+ // pass it on to settings
+ final Intent intent = getActivityStartIntent();
+ mFragment.startActivityForResult(intent, REQUEST_CODE_ANGLE_ENABLED_APP);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ updatePreferenceSummary();
+ }
+
+ @Override
+ public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode != REQUEST_CODE_ANGLE_ENABLED_APP || resultCode != Activity.RESULT_OK) {
+ return false;
+ }
+ Settings.Global.putString(mContext.getContentResolver(), Settings.Global.ANGLE_ENABLED_APP,
+ data.getAction());
+ updatePreferenceSummary();
+ return true;
+ }
+
+ @Override
+ protected void onDeveloperOptionsSwitchDisabled() {
+ super.onDeveloperOptionsSwitchDisabled();
+ mPreference.setSummary(mContext.getResources().getString(
+ R.string.angle_enabled_app_not_set));
+ }
+
+ @VisibleForTesting
+ Intent getActivityStartIntent() {
+ Intent intent = new Intent(mContext, AppPicker.class);
+ intent.putExtra(AppPicker.EXTRA_NON_SYSTEM, true /* value */);
+ return intent;
+ }
+
+ private void updatePreferenceSummary() {
+ final String angleEnabledApp = Settings.Global.getString(
+ mContext.getContentResolver(), Settings.Global.ANGLE_ENABLED_APP);
+ if (angleEnabledApp != null && angleEnabledApp.length() > 0) {
+ mPreference.setSummary(mContext.getResources().getString(
+ R.string.angle_enabled_app_set,
+ getAppLabel(angleEnabledApp)));
+ } else {
+ mPreference.setSummary(mContext.getResources().getString(
+ R.string.angle_enabled_app_not_set));
+ }
+ }
+
+ private String getAppLabel(String angleEnabledApp) {
+ try {
+ final ApplicationInfo ai = mPackageManager.getApplicationInfo(angleEnabledApp,
+ PackageManager.GET_DISABLED_COMPONENTS);
+ final CharSequence lab = mPackageManager.getApplicationLabel(ai);
+ return lab != null ? lab.toString() : angleEnabledApp;
+ } catch (PackageManager.NameNotFoundException e) {
+ return angleEnabledApp;
+ }
+ }
+}
diff --git a/src/com/android/settings/development/AppPicker.java b/src/com/android/settings/development/AppPicker.java
index 433f31a..04f318f 100644
--- a/src/com/android/settings/development/AppPicker.java
+++ b/src/com/android/settings/development/AppPicker.java
@@ -45,9 +45,11 @@
public static final String EXTRA_REQUESTIING_PERMISSION
= "com.android.settings.extra.REQUESTIING_PERMISSION";
public static final String EXTRA_DEBUGGABLE = "com.android.settings.extra.DEBUGGABLE";
+ public static final String EXTRA_NON_SYSTEM = "com.android.settings.extra.NON_SYSTEM";
private String mPermissionName;
private boolean mDebuggableOnly;
+ private boolean mNonSystemOnly;
@Override
protected void onCreate(Bundle icicle) {
@@ -55,6 +57,7 @@
mPermissionName = getIntent().getStringExtra(EXTRA_REQUESTIING_PERMISSION);
mDebuggableOnly = getIntent().getBooleanExtra(EXTRA_DEBUGGABLE, false);
+ mNonSystemOnly = getIntent().getBooleanExtra(EXTRA_NON_SYSTEM, false);
mAdapter = new AppListAdapter(this);
if (mAdapter.getCount() <= 0) {
@@ -113,6 +116,11 @@
}
}
+ // Filter out apps that are system apps if requested
+ if (mNonSystemOnly && ai.isSystemApp()) {
+ continue;
+ }
+
// Filter out apps that do not request the permission if required.
if (mPermissionName != null) {
boolean requestsPermission = false;
diff --git a/src/com/android/settings/development/DevelopmentOptionsActivityRequestCodes.java b/src/com/android/settings/development/DevelopmentOptionsActivityRequestCodes.java
index b7b2759..6e3ec93 100644
--- a/src/com/android/settings/development/DevelopmentOptionsActivityRequestCodes.java
+++ b/src/com/android/settings/development/DevelopmentOptionsActivityRequestCodes.java
@@ -25,4 +25,6 @@
int REQUEST_CODE_DEBUG_APP = 1;
int REQUEST_MOCK_LOCATION_APP = 2;
+
+ int REQUEST_CODE_ANGLE_ENABLED_APP = 3;
}
diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
index 873cec4..cc8bd2e 100644
--- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
+++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
@@ -405,6 +405,7 @@
controllers.add(new SelectDebugAppPreferenceController(context, fragment));
controllers.add(new WaitForDebuggerPreferenceController(context));
controllers.add(new EnableGpuDebugLayersPreferenceController(context));
+ controllers.add(new AngleEnabledAppPreferenceController(context, fragment));
controllers.add(new VerifyAppsOverUsbPreferenceController(context));
controllers.add(new LogdSizePreferenceController(context));
controllers.add(new LogPersistPreferenceController(context, fragment, lifecycle));
diff --git a/src/com/android/settings/gestures/ReachGesturePreferenceController.java b/src/com/android/settings/gestures/WakeLockScreenGesturePreferenceController.java
similarity index 69%
rename from src/com/android/settings/gestures/ReachGesturePreferenceController.java
rename to src/com/android/settings/gestures/WakeLockScreenGesturePreferenceController.java
index 6bfe4f3..1f1630e 100644
--- a/src/com/android/settings/gestures/ReachGesturePreferenceController.java
+++ b/src/com/android/settings/gestures/WakeLockScreenGesturePreferenceController.java
@@ -16,7 +16,7 @@
package com.android.settings.gestures;
-import static android.provider.Settings.Secure.DOZE_REACH_GESTURE;
+import static android.provider.Settings.Secure.DOZE_WAKE_LOCK_SCREEN_GESTURE;
import android.annotation.UserIdInt;
import android.content.Context;
@@ -26,33 +26,34 @@
import com.android.internal.hardware.AmbientDisplayConfiguration;
-public class ReachGesturePreferenceController extends GesturePreferenceController {
+public class WakeLockScreenGesturePreferenceController extends GesturePreferenceController {
private static final int ON = 1;
private static final int OFF = 0;
- private static final String PREF_KEY_VIDEO = "gesture_reach_video";
- private final String mReachUpPrefKey;
+ private static final String PREF_KEY_VIDEO = "gesture_wake_lock_screen_video";
+ private final String mWakeLockScreenPrefKey;
private AmbientDisplayConfiguration mAmbientConfig;
@UserIdInt
private final int mUserId;
- public ReachGesturePreferenceController(Context context, String key) {
+ public WakeLockScreenGesturePreferenceController(Context context, String key) {
super(context, key);
mUserId = UserHandle.myUserId();
- mReachUpPrefKey = key;
+ mWakeLockScreenPrefKey = key;
}
- public ReachGesturePreferenceController setConfig(AmbientDisplayConfiguration config) {
+ public WakeLockScreenGesturePreferenceController
+ setConfig(AmbientDisplayConfiguration config) {
mAmbientConfig = config;
return this;
}
@Override
public int getAvailabilityStatus() {
- // No hardware support for Reach Gesture
- if (!getAmbientConfig().reachGestureAvailable()) {
+ // No hardware support for this Gesture
+ if (!getAmbientConfig().wakeLockScreenGestureAvailable()) {
return UNSUPPORTED_ON_DEVICE;
}
@@ -61,7 +62,7 @@
@Override
public boolean isSliceable() {
- return TextUtils.equals(getPreferenceKey(), "gesture_reach");
+ return TextUtils.equals(getPreferenceKey(), "gesture_wake_lock_screen");
}
@Override
@@ -71,17 +72,17 @@
@Override
public boolean isChecked() {
- return getAmbientConfig().reachGestureEnabled(mUserId);
+ return getAmbientConfig().wakeLockScreenGestureEnabled(mUserId);
}
@Override
public String getPreferenceKey() {
- return mReachUpPrefKey;
+ return mWakeLockScreenPrefKey;
}
@Override
public boolean setChecked(boolean isChecked) {
- return Settings.Secure.putInt(mContext.getContentResolver(), DOZE_REACH_GESTURE,
+ return Settings.Secure.putInt(mContext.getContentResolver(), DOZE_WAKE_LOCK_SCREEN_GESTURE,
isChecked ? ON : OFF);
}
diff --git a/src/com/android/settings/gestures/ReachGestureSettings.java b/src/com/android/settings/gestures/WakeLockScreenGestureSettings.java
similarity index 84%
rename from src/com/android/settings/gestures/ReachGestureSettings.java
rename to src/com/android/settings/gestures/WakeLockScreenGestureSettings.java
index 3df9fcf..e6b7265 100644
--- a/src/com/android/settings/gestures/ReachGestureSettings.java
+++ b/src/com/android/settings/gestures/WakeLockScreenGestureSettings.java
@@ -33,12 +33,12 @@
import java.util.List;
@SearchIndexable
-public class ReachGestureSettings extends DashboardFragment {
+public class WakeLockScreenGestureSettings extends DashboardFragment {
- private static final String TAG = "ReachGestureSettings";
+ private static final String TAG = "WakeLockScreenGestureSettings";
public static final String PREF_KEY_SUGGESTION_COMPLETE =
- "pref_reach_gesture_suggestion_complete";
+ "pref_wake_lock_screen_gesture_suggestion_complete";
@Override
public void onAttach(Context context) {
@@ -48,13 +48,13 @@
SharedPreferences prefs = suggestionFeatureProvider.getSharedPrefs(context);
prefs.edit().putBoolean(PREF_KEY_SUGGESTION_COMPLETE, true).apply();
- use(ReachGesturePreferenceController.class)
+ use(WakeLockScreenGesturePreferenceController.class)
.setConfig(new AmbientDisplayConfiguration(context));
}
@Override
public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.SETTINGS_GESTURE_REACH;
+ return MetricsProto.MetricsEvent.SETTINGS_GESTURE_WAKE_LOCK_SCREEN;
}
@Override
@@ -64,7 +64,7 @@
@Override
protected int getPreferenceScreenResId() {
- return R.xml.reach_gesture_settings;
+ return R.xml.wake_lock_screen_gesture_settings;
}
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
@@ -73,7 +73,7 @@
public List<SearchIndexableResource> getXmlResourcesToIndex(
Context context, boolean enabled) {
final SearchIndexableResource sir = new SearchIndexableResource(context);
- sir.xmlResId = R.xml.reach_gesture_settings;
+ sir.xmlResId = R.xml.wake_lock_screen_gesture_settings;
return Arrays.asList(sir);
}
};
diff --git a/src/com/android/settings/homepage/CardContentLoader.java b/src/com/android/settings/homepage/CardContentLoader.java
index 9805ae3..5b81a23 100644
--- a/src/com/android/settings/homepage/CardContentLoader.java
+++ b/src/com/android/settings/homepage/CardContentLoader.java
@@ -17,16 +17,21 @@
package com.android.settings.homepage;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.database.Cursor;
+import android.util.Log;
import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
+import com.android.settings.homepage.deviceinfo.DataUsageSlice;
import com.android.settingslib.utils.AsyncLoaderCompat;
import java.util.ArrayList;
import java.util.List;
public class CardContentLoader extends AsyncLoaderCompat<List<ContextualCard>> {
+ private static final String TAG = "CardContentLoader";
static final int CARD_CONTENT_LOADER_ID = 1;
private Context mContext;
@@ -49,9 +54,9 @@
@Override
public List<ContextualCard> loadInBackground() {
final List<ContextualCard> result = new ArrayList<>();
- try (Cursor cursor = CardDatabaseHelper.getInstance(mContext).getContextualCards()) {
+ try (Cursor cursor = getContextualCardsFromProvider()) {
if (cursor.getCount() == 0) {
- //TODO(b/113372471): Load Default static cards and return 3 static cards
+ result.addAll(createStaticCards());
return result;
}
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
@@ -65,4 +70,58 @@
}
return result;
}
+
+ @VisibleForTesting
+ Cursor getContextualCardsFromProvider() {
+ return CardDatabaseHelper.getInstance(mContext).getContextualCards();
+ }
+
+ @VisibleForTesting
+ List<ContextualCard> createStaticCards() {
+ final long appVersionCode = getAppVersionCode();
+ final String packageName = mContext.getPackageName();
+ final double rankingScore = 0.0;
+ final List<ContextualCard> result = new ArrayList() {{
+ add(new ContextualCard.Builder()
+ .setSliceUri(DataUsageSlice.DATA_USAGE_CARD_URI.toString())
+ .setName(packageName + "/" + DataUsageSlice.PATH_DATA_USAGE_CARD)
+ .setPackageName(packageName)
+ .setRankingScore(rankingScore)
+ .setAppVersion(appVersionCode)
+ .setCardType(ContextualCard.CardType.SLICE)
+ .setIsHalfWidth(true)
+ .build());
+ //TODO(b/115971399): Will change following values of SliceUri and Name
+ // after landing these slice cards.
+ add(new ContextualCard.Builder()
+ .setSliceUri("content://com.android.settings.slices/intent/battery_card")
+ .setName(packageName + "/" + "battery_card")
+ .setPackageName(packageName)
+ .setRankingScore(rankingScore)
+ .setAppVersion(appVersionCode)
+ .setCardType(ContextualCard.CardType.SLICE)
+ .setIsHalfWidth(true)
+ .build());
+ add(new ContextualCard.Builder()
+ .setSliceUri("content://com.android.settings.slices/intent/device_info_card")
+ .setName(packageName + "/" + "device_info_card")
+ .setPackageName(packageName)
+ .setRankingScore(rankingScore)
+ .setAppVersion(appVersionCode)
+ .setCardType(ContextualCard.CardType.SLICE)
+ .setIsHalfWidth(true)
+ .build());
+ }};
+ return result;
+ }
+
+ private long getAppVersionCode() {
+ try {
+ return mContext.getPackageManager().getPackageInfo(mContext.getPackageName(),
+ 0 /* flags */).getLongVersionCode();
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(TAG, "Invalid package name for context", e);
+ }
+ return -1L;
+ }
}
diff --git a/tests/robotests/assets/grandfather_not_implementing_index_provider b/tests/robotests/assets/grandfather_not_implementing_index_provider
index 1ed50c9..38108f7 100644
--- a/tests/robotests/assets/grandfather_not_implementing_index_provider
+++ b/tests/robotests/assets/grandfather_not_implementing_index_provider
@@ -28,6 +28,7 @@
com.android.settings.bluetooth.BluetoothPairingDetail
com.android.settings.bluetooth.DevicePickerFragment
com.android.settings.datausage.AppDataUsage
+com.android.settings.datausage.AppDataUsageV2
com.android.settings.datausage.DataUsageList
com.android.settings.datausage.DataUsageListV2
com.android.settings.datetime.timezone.TimeZoneSettings
diff --git a/tests/robotests/src/com/android/settings/datausage/AppDataUsageV2Test.java b/tests/robotests/src/com/android/settings/datausage/AppDataUsageV2Test.java
new file mode 100644
index 0000000..d979b68
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/datausage/AppDataUsageV2Test.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.datausage;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.pm.PackageManager;
+import android.net.NetworkPolicyManager;
+import android.os.Bundle;
+import android.util.ArraySet;
+import android.view.View;
+
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
+import com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal;
+import com.android.settings.widget.EntityHeaderController;
+import com.android.settingslib.AppItem;
+import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import com.android.settingslib.RestrictedSwitchPreference;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(shadows = {ShadowEntityHeaderController.class, ShadowRestrictedLockUtilsInternal.class})
+public class AppDataUsageV2Test {
+
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private EntityHeaderController mHeaderController;
+ @Mock
+ private PackageManager mPackageManager;
+
+ private AppDataUsageV2 mFragment;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ FakeFeatureFactory.setupForTest();
+ }
+
+ @After
+ public void tearDown() {
+ ShadowEntityHeaderController.reset();
+ }
+
+ @Test
+ public void bindAppHeader_allWorkApps_shouldNotShowAppInfoLink() {
+ ShadowEntityHeaderController.setUseMock(mHeaderController);
+ when(mHeaderController.setRecyclerView(any(), any())).thenReturn(mHeaderController);
+ when(mHeaderController.setUid(anyInt())).thenReturn(mHeaderController);
+
+ mFragment = spy(new AppDataUsageV2());
+
+ when(mFragment.getPreferenceManager())
+ .thenReturn(mock(PreferenceManager.class, RETURNS_DEEP_STUBS));
+ doReturn(mock(PreferenceScreen.class)).when(mFragment).getPreferenceScreen();
+ ReflectionHelpers.setField(mFragment, "mAppItem", mock(AppItem.class));
+
+ mFragment.onViewCreated(new View(RuntimeEnvironment.application), new Bundle());
+
+ verify(mHeaderController).setHasAppInfoLink(false);
+ }
+
+ @Test
+ public void bindAppHeader_workApp_shouldSetWorkAppUid() throws
+ PackageManager.NameNotFoundException {
+ final int fakeUserId = 100;
+
+ mFragment = spy(new AppDataUsageV2());
+ final ArraySet<String> packages = new ArraySet<>();
+ packages.add("pkg");
+ final AppItem appItem = new AppItem(123456789);
+
+ ReflectionHelpers.setField(mFragment, "mPackageManager", mPackageManager);
+ ReflectionHelpers.setField(mFragment, "mAppItem", appItem);
+ ReflectionHelpers.setField(mFragment, "mPackages", packages);
+
+ when(mPackageManager.getPackageUidAsUser(anyString(), anyInt()))
+ .thenReturn(fakeUserId);
+
+ ShadowEntityHeaderController.setUseMock(mHeaderController);
+ when(mHeaderController.setRecyclerView(any(), any())).thenReturn(mHeaderController);
+ when(mHeaderController.setUid(fakeUserId)).thenReturn(mHeaderController);
+ when(mHeaderController.setHasAppInfoLink(anyBoolean())).thenReturn(mHeaderController);
+
+ when(mFragment.getPreferenceManager())
+ .thenReturn(mock(PreferenceManager.class, RETURNS_DEEP_STUBS));
+ doReturn(mock(PreferenceScreen.class)).when(mFragment).getPreferenceScreen();
+
+ mFragment.onViewCreated(new View(RuntimeEnvironment.application), new Bundle());
+
+ verify(mHeaderController).setHasAppInfoLink(true);
+ verify(mHeaderController).setUid(fakeUserId);
+ }
+
+ @Test
+ public void changePreference_backgroundData_shouldUpdateUI() {
+ mFragment = spy(new AppDataUsageV2());
+ final AppItem appItem = new AppItem(123456789);
+ final RestrictedSwitchPreference pref = mock(RestrictedSwitchPreference.class);
+ final DataSaverBackend dataSaverBackend = mock(DataSaverBackend.class);
+ ReflectionHelpers.setField(mFragment, "mAppItem", appItem);
+ ReflectionHelpers.setField(mFragment, "mRestrictBackground", pref);
+ ReflectionHelpers.setField(mFragment, "mDataSaverBackend", dataSaverBackend);
+
+ doNothing().when(mFragment).updatePrefs();
+
+ mFragment.onPreferenceChange(pref, true /* value */);
+
+ verify(mFragment).updatePrefs();
+ }
+
+ @Test
+ public void updatePrefs_restrictedByAdmin_shouldDisablePreference() {
+ mFragment = spy(new AppDataUsageV2());
+ final int testUid = 123123;
+ final AppItem appItem = new AppItem(testUid);
+ final RestrictedSwitchPreference restrictBackgroundPref
+ = mock(RestrictedSwitchPreference.class);
+ final RestrictedSwitchPreference unrestrictedDataPref
+ = mock(RestrictedSwitchPreference.class);
+ final DataSaverBackend dataSaverBackend = mock(DataSaverBackend.class);
+ final NetworkPolicyManager networkPolicyManager = mock(NetworkPolicyManager.class);
+ ReflectionHelpers.setField(mFragment, "mAppItem", appItem);
+ ReflectionHelpers.setField(mFragment, "mRestrictBackground", restrictBackgroundPref);
+ ReflectionHelpers.setField(mFragment, "mUnrestrictedData", unrestrictedDataPref);
+ ReflectionHelpers.setField(mFragment, "mDataSaverBackend", dataSaverBackend);
+ ReflectionHelpers.setField(mFragment.services, "mPolicyManager", networkPolicyManager);
+
+ ShadowRestrictedLockUtilsInternal.setRestricted(true);
+ doReturn(NetworkPolicyManager.POLICY_NONE).when(networkPolicyManager)
+ .getUidPolicy(testUid);
+
+ mFragment.updatePrefs();
+
+ verify(restrictBackgroundPref).setDisabledByAdmin(any(EnforcedAdmin.class));
+ verify(unrestrictedDataPref).setDisabledByAdmin(any(EnforcedAdmin.class));
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/development/AngleEnabledAppPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/AngleEnabledAppPreferenceControllerTest.java
new file mode 100644
index 0000000..03837c2
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/development/AngleEnabledAppPreferenceControllerTest.java
@@ -0,0 +1,138 @@
+/*
+ * 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.development;
+
+import static com.android.settings.development.DevelopmentOptionsActivityRequestCodes.REQUEST_CODE_ANGLE_ENABLED_APP;
+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.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Activity;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.provider.Settings;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class AngleEnabledAppPreferenceControllerTest {
+
+ @Mock
+ private Preference mPreference;
+ @Mock
+ private PreferenceScreen mPreferenceScreen;
+ @Mock
+ private DevelopmentSettingsDashboardFragment mFragment;
+ @Mock
+ private PackageManager mPackageManager;
+
+ private Context mContext;
+ private AngleEnabledAppPreferenceController mController;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ mContext = RuntimeEnvironment.application;
+ mController = spy(new AngleEnabledAppPreferenceController(mContext, mFragment));
+ ReflectionHelpers
+ .setField(mController, "mPackageManager" /* field name */, mPackageManager);
+ when(mPreferenceScreen.findPreference(mController.getPreferenceKey()))
+ .thenReturn(mPreference);
+ mController.displayPreference(mPreferenceScreen);
+ }
+
+ @Test
+ public void handlePreferenceTreeClick_preferenceClicked_launchActivity() {
+ final Intent activityStartIntent = new Intent(mContext, AppPicker.class);
+ final String preferenceKey = mController.getPreferenceKey();
+ doReturn(activityStartIntent).when(mController).getActivityStartIntent();
+ when(mPreference.getKey()).thenReturn(preferenceKey);
+ mController.handlePreferenceTreeClick(mPreference);
+
+ verify(mFragment).startActivityForResult(activityStartIntent,
+ REQUEST_CODE_ANGLE_ENABLED_APP);
+ }
+
+ @Test
+ public void updateState_foobarAppSelected_shouldUpdateSummaryWithAngleEnabledAppLabel() {
+ final String angleEnabledApp = "foobar";
+ final ContentResolver contentResolver = mContext.getContentResolver();
+ Settings.Global.putString(contentResolver, Settings.Global.ANGLE_ENABLED_APP,
+ angleEnabledApp);
+ mController.updateState(mPreference);
+
+ verify(mPreference).setSummary(
+ mContext.getString(R.string.angle_enabled_app_set, angleEnabledApp));
+ }
+
+ @Test
+ public void updateState_noAppSelected_shouldUpdateSummaryWithNoAppSelected() {
+ final String angleEnabledApp = null;
+ final ContentResolver contentResolver = mContext.getContentResolver();
+ Settings.Global.putString(contentResolver, Settings.Global.ANGLE_ENABLED_APP,
+ angleEnabledApp);
+ mController.updateState(mPreference);
+
+ verify(mPreference).setSummary(
+ mContext.getString(R.string.angle_enabled_app_not_set));
+ }
+
+ @Test
+ public void onActivityResult_foobarAppSelected_shouldUpdateSummaryWithAngleEnabledLabel() {
+ Intent activityResultIntent = new Intent(mContext, AppPicker.class);
+ final String appLabel = "foobar";
+ activityResultIntent.setAction(appLabel);
+ final boolean result = mController
+ .onActivityResult(REQUEST_CODE_ANGLE_ENABLED_APP, Activity.RESULT_OK,
+ activityResultIntent);
+
+ assertThat(result).isTrue();
+ verify(mPreference).setSummary(
+ mContext.getString(R.string.angle_enabled_app_set, appLabel));
+ }
+
+ @Test
+ public void onActivityResult_badRequestCode_shouldReturnFalse() {
+ assertThat(mController.onActivityResult(
+ -1 /* requestCode */, -1 /* resultCode */, null /* intent */)).isFalse();
+ }
+
+ @Test
+ public void onDeveloperOptionsSwitchDisabled_shouldDisablePreference() {
+ mController.onDeveloperOptionsSwitchDisabled();
+
+ assertThat(mPreference.isEnabled()).isFalse();
+ verify(mPreference).setSummary(
+ mContext.getString(R.string.angle_enabled_app_not_set));
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/gestures/ReachGesturePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/WakeLockScreenGesturePreferenceControllerTest.java
similarity index 73%
rename from tests/robotests/src/com/android/settings/gestures/ReachGesturePreferenceControllerTest.java
rename to tests/robotests/src/com/android/settings/gestures/WakeLockScreenGesturePreferenceControllerTest.java
index 78e899c..c6249fb 100644
--- a/tests/robotests/src/com/android/settings/gestures/ReachGesturePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/WakeLockScreenGesturePreferenceControllerTest.java
@@ -37,41 +37,41 @@
import org.mockito.MockitoAnnotations;
@RunWith(SettingsRobolectricTestRunner.class)
-public class ReachGesturePreferenceControllerTest {
+public class WakeLockScreenGesturePreferenceControllerTest {
- private static final String KEY_REACH = "gesture_reach";
+ private static final String KEY_WAKE_LOCK_SCREEN = "gesture_wake_lock_screen";
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mContext;
@Mock
private AmbientDisplayConfiguration mAmbientDisplayConfiguration;
- private ReachGesturePreferenceController mController;
+ private WakeLockScreenGesturePreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mController = new ReachGesturePreferenceController(mContext, KEY_REACH);
+ mController = new WakeLockScreenGesturePreferenceController(mContext, KEY_WAKE_LOCK_SCREEN);
mController.setConfig(mAmbientDisplayConfiguration);
}
@Test
public void testIsChecked_configIsSet_shouldReturnTrue() {
// Set the setting to be enabled.
- when(mAmbientDisplayConfiguration.reachGestureEnabled(anyInt())).thenReturn(true);
+ when(mAmbientDisplayConfiguration.wakeLockScreenGestureEnabled(anyInt())).thenReturn(true);
assertThat(mController.isChecked()).isTrue();
}
@Test
public void testIsChecked_configIsNotSet_shouldReturnFalse() {
// Set the setting to be disabled.
- when(mAmbientDisplayConfiguration.reachGestureEnabled(anyInt())).thenReturn(false);
+ when(mAmbientDisplayConfiguration.wakeLockScreenGestureEnabled(anyInt())).thenReturn(false);
assertThat(mController.isChecked()).isFalse();
}
@Test
public void getAvailabilityStatus_gestureNotSupported_UNSUPPORTED_ON_DEVICE() {
- when(mAmbientDisplayConfiguration.reachGestureAvailable()).thenReturn(false);
+ when(mAmbientDisplayConfiguration.wakeLockScreenGestureAvailable()).thenReturn(false);
final int availabilityStatus = mController.getAvailabilityStatus();
assertThat(availabilityStatus).isEqualTo(UNSUPPORTED_ON_DEVICE);
@@ -79,7 +79,7 @@
@Test
public void getAvailabilityStatus_gestureSupported_AVAILABLE() {
- when(mAmbientDisplayConfiguration.reachGestureAvailable()).thenReturn(true);
+ when(mAmbientDisplayConfiguration.wakeLockScreenGestureAvailable()).thenReturn(true);
final int availabilityStatus = mController.getAvailabilityStatus();
assertThat(availabilityStatus).isEqualTo(AVAILABLE);
@@ -87,15 +87,15 @@
@Test
public void isSliceableCorrectKey_returnsTrue() {
- final ReachGesturePreferenceController controller =
- new ReachGesturePreferenceController(mContext, "gesture_reach");
+ final WakeLockScreenGesturePreferenceController controller =
+ new WakeLockScreenGesturePreferenceController(mContext, KEY_WAKE_LOCK_SCREEN);
assertThat(controller.isSliceable()).isTrue();
}
@Test
public void isSliceableIncorrectKey_returnsFalse() {
- final ReachGesturePreferenceController controller =
- new ReachGesturePreferenceController(mContext, "bad_key");
+ final WakeLockScreenGesturePreferenceController controller =
+ new WakeLockScreenGesturePreferenceController(mContext, "bad_key");
assertThat(controller.isSliceable()).isFalse();
}
}
diff --git a/tests/robotests/src/com/android/settings/gestures/ReachGestureSettingsTest.java b/tests/robotests/src/com/android/settings/gestures/WakeLockScreenGestureSettingsTest.java
similarity index 84%
rename from tests/robotests/src/com/android/settings/gestures/ReachGestureSettingsTest.java
rename to tests/robotests/src/com/android/settings/gestures/WakeLockScreenGestureSettingsTest.java
index 9371c71..0cd777d 100644
--- a/tests/robotests/src/com/android/settings/gestures/ReachGestureSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/WakeLockScreenGestureSettingsTest.java
@@ -30,19 +30,19 @@
import java.util.List;
@RunWith(SettingsRobolectricTestRunner.class)
-public class ReachGestureSettingsTest {
+public class WakeLockScreenGestureSettingsTest {
- private ReachGestureSettings mSettings;
+ private WakeLockScreenGestureSettings mSettings;
@Before
public void setUp() {
- mSettings = new ReachGestureSettings();
+ mSettings = new WakeLockScreenGestureSettings();
}
@Test
public void testSearchIndexProvider_shouldIndexResource() {
final List<SearchIndexableResource> indexRes =
- ReachGestureSettings.SEARCH_INDEX_DATA_PROVIDER.getXmlResourcesToIndex(
+ WakeLockScreenGestureSettings.SEARCH_INDEX_DATA_PROVIDER.getXmlResourcesToIndex(
RuntimeEnvironment.application, true /* enabled */);
assertThat(indexRes).isNotNull();
diff --git a/tests/robotests/src/com/android/settings/homepage/CardContentLoaderTest.java b/tests/robotests/src/com/android/settings/homepage/CardContentLoaderTest.java
new file mode 100644
index 0000000..20ad067
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/homepage/CardContentLoaderTest.java
@@ -0,0 +1,145 @@
+/*
+ * 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.homepage;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+
+import java.util.List;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class CardContentLoaderTest {
+ private static final String[] QUERY_PROJECTION = {
+ CardDatabaseHelper.CardColumns.NAME,
+ CardDatabaseHelper.CardColumns.TYPE,
+ CardDatabaseHelper.CardColumns.SCORE,
+ CardDatabaseHelper.CardColumns.SLICE_URI,
+ CardDatabaseHelper.CardColumns.CATEGORY,
+ CardDatabaseHelper.CardColumns.LOCALIZED_TO_LOCALE,
+ CardDatabaseHelper.CardColumns.PACKAGE_NAME,
+ CardDatabaseHelper.CardColumns.APP_VERSION,
+ CardDatabaseHelper.CardColumns.TITLE_RES_NAME,
+ CardDatabaseHelper.CardColumns.TITLE_TEXT,
+ CardDatabaseHelper.CardColumns.SUMMARY_RES_NAME,
+ CardDatabaseHelper.CardColumns.SUMMARY_TEXT,
+ CardDatabaseHelper.CardColumns.ICON_RES_NAME,
+ CardDatabaseHelper.CardColumns.ICON_RES_ID,
+ CardDatabaseHelper.CardColumns.CARD_ACTION,
+ CardDatabaseHelper.CardColumns.EXPIRE_TIME_MS,
+ CardDatabaseHelper.CardColumns.SUPPORT_HALF_WIDTH
+ };
+
+ private Context mContext;
+ private CardContentLoader mCardContentLoader;
+
+ @Before
+ public void setUp() {
+ mContext = RuntimeEnvironment.application;
+ mCardContentLoader = spy(new CardContentLoader(mContext));
+ }
+
+ @Test
+ public void loadInBackground_hasDataInDb_shouldReturnData() {
+ final Cursor cursor = generateTwoRowContextualCards();
+ doReturn(cursor).when(mCardContentLoader).getContextualCardsFromProvider();
+
+ final List<ContextualCard> contextualCards = mCardContentLoader.loadInBackground();
+
+ assertThat(contextualCards.size()).isEqualTo(cursor.getCount());
+ }
+
+ @Test
+ public void loadInBackground_hasNoData_shouldReturnThreeDefaultData() {
+ final Cursor cursor = generateEmptyContextualCards();
+ doReturn(cursor).when(mCardContentLoader).getContextualCardsFromProvider();
+
+ final List<ContextualCard> contextualCards = mCardContentLoader.loadInBackground();
+
+ assertThat(contextualCards.size()).isEqualTo(mCardContentLoader.createStaticCards().size());
+ }
+
+ private MatrixCursor generateEmptyContextualCards() {
+ final MatrixCursor result = new MatrixCursor(QUERY_PROJECTION);
+ return result;
+ }
+
+ private MatrixCursor generateTwoRowContextualCards() {
+ final MatrixCursor result = generateEmptyContextualCards();
+ result.addRow(generateFirstFakeData());
+ result.addRow(generateSecondFakeData());
+ return result;
+ }
+
+ private Object[] generateFirstFakeData() {
+ final Object[] ref = new Object[]{
+ "auto_rotate", /* NAME */
+ ContextualCard.CardType.SLICE, /* TYPE */
+ 0.5, /* SCORE */
+ "content://com.android.settings.slices/action/auto_rotate", /* SLICE_URI */
+ 2, /* CATEGORY */
+ "", /* LOCALIZED_TO_LOCALE */
+ "com.android.settings", /* PACKAGE_NAME */
+ 1l, /* APP_VERSION */
+ "", /* TITLE_RES_NAME */
+ "", /* TITLE_TEXT */
+ "", /* SUMMARY_RES_NAME */
+ "", /* SUMMARY_TEXT */
+ "", /* ICON_RES_NAME */
+ 0, /* ICON_RES_ID */
+ 0, /* CARD_ACTION */
+ -1, /* EXPIRE_TIME_MS */
+ 0 /* SUPPORT_HALF_WIDTH */
+ };
+ return ref;
+ }
+
+ private Object[] generateSecondFakeData() {
+ final Object[] ref = new Object[]{
+ "toggle_airplane", /* NAME */
+ ContextualCard.CardType.SLICE, /* TYPE */
+ 0.5, /* SCORE */
+ "content://com.android.settings.slices/action/toggle_airplane", /* SLICE_URI */
+ 2, /* CATEGORY */
+ "", /* LOCALIZED_TO_LOCALE */
+ "com.android.settings", /* PACKAGE_NAME */
+ 1l, /* APP_VERSION */
+ "", /* TITLE_RES_NAME */
+ "", /* TITLE_TEXT */
+ "", /* SUMMARY_RES_NAME */
+ "", /* SUMMARY_TEXT */
+ "", /* ICON_RES_NAME */
+ 0, /* ICON_RES_ID */
+ 0, /* CARD_ACTION */
+ -1, /* EXPIRE_TIME_MS */
+ 0 /* SUPPORT_HALF_WIDTH */
+ };
+ return ref;
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java b/tests/unit/src/com/android/settings/homepage/SettingsHomepageActivityTest.java
similarity index 68%
rename from tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java
rename to tests/unit/src/com/android/settings/homepage/SettingsHomepageActivityTest.java
index 4b237a0..89ec476 100644
--- a/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java
+++ b/tests/unit/src/com/android/settings/homepage/SettingsHomepageActivityTest.java
@@ -16,25 +16,28 @@
package com.android.settings.homepage;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+
import static com.android.settings.homepage.SettingsHomepageActivity.PERSONAL_SETTINGS_TAG;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
+import android.content.Intent;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
import android.util.FeatureFlagUtils;
import androidx.fragment.app.Fragment;
import com.android.settings.core.FeatureFlags;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.Robolectric;
-import org.robolectric.RuntimeEnvironment;
-@RunWith(SettingsRobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class SettingsHomepageActivityTest {
private Context mContext;
@@ -42,16 +45,27 @@
@Before
public void setUp() {
- mContext = RuntimeEnvironment.application;
+ mContext = InstrumentationRegistry.getTargetContext();
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.DYNAMIC_HOMEPAGE, true);
}
+ @After
+ public void tearDown() {
+ FeatureFlagUtils.setEnabled(mContext, FeatureFlags.DYNAMIC_HOMEPAGE, false);
+ }
+
@Test
public void launchHomepage_shouldOpenPersonalSettings() {
- mActivity = Robolectric.setupActivity(SettingsHomepageActivity.class);
+ final Intent intent = new Intent().setClass(mContext, SettingsHomepageActivity.class)
+ .addFlags(FLAG_ACTIVITY_NEW_TASK);
+
+ mActivity = (SettingsHomepageActivity) InstrumentationRegistry.getInstrumentation()
+ .startActivitySync(intent);
+
final Fragment fragment = mActivity.getSupportFragmentManager()
.findFragmentByTag(PERSONAL_SETTINGS_TAG);
assertThat(fragment).isInstanceOf(PersonalSettingsFragment.class);
}
+
}