Merge "API for notification listener for Companioon apps" into oc-dev
diff --git a/res/drawable/ic_media_stream_on_24dp.xml b/res/drawable/ic_media_stream_on_24dp.xml
new file mode 100644
index 0000000..3db55dd
--- /dev/null
+++ b/res/drawable/ic_media_stream_on_24dp.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+ -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M18,3h-5c-0.55,0 -1,0.45 -1,1v8.3a3.88,3.88 0,0 0,-2.9 -0.04c-1.79,0.67 -3.11,2.35 -3.1,4.26A4.483,4.483 0,0 0,10.5 21c2.5,0 4.5,-2.3 4.5,-4.5V6h3c0.55,0 1,-0.45 1,-1V4c0,-0.55 -0.45,-1 -1,-1z"/>
+</vector>
diff --git a/res/layout/storage_item.xml b/res/layout/storage_item.xml
index 33f4f9e..0c1f60c 100644
--- a/res/layout/storage_item.xml
+++ b/res/layout/storage_item.xml
@@ -76,6 +76,7 @@
android:id="@android:id/progress"
android:layout_width="match_parent"
android:layout_height="8dp"
+ android:layout_marginStart="60dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="8dp"
android:visibility="gone"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index dea40b6..36643d3 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -4686,9 +4686,9 @@
<string name="battery_last_full_charge">Last full charge</string>
<!-- Description for text in battery footer. [CHAR LIMIT=120] -->
<string name="battery_footer_summary">Remaining battery time is approximate and can change based on usage</string>
- <!-- Title for battery usage detail in foreground. [CHAR LIMIT=80] -->
+ <!-- Title for text that shows the amount of time an app has been running while in the foreground. [CHAR LIMIT=80] -->
<string name="battery_detail_foreground">While in active use</string>
- <!-- Title for battery usage detail in background. [CHAR LIMIT=80] -->
+ <!-- Title for text that shows the amount of time an app has been running while in the background. [CHAR LIMIT=80] -->
<string name="battery_detail_background">While in background</string>
<!-- Title for battery usage amount by this app. [CHAR LIMIT=80] -->
<string name="battery_detail_power_usage">Battery usage</string>
diff --git a/res/xml/app_memory_settings.xml b/res/xml/app_memory_settings.xml
index 53a71ff..308f189 100644
--- a/res/xml/app_memory_settings.xml
+++ b/res/xml/app_memory_settings.xml
@@ -18,26 +18,25 @@
android:title="@string/memory_usage">
<PreferenceCategory
- android:title="@string/average_memory_use"/>
+ android:title="@string/average_memory_use">
- <com.android.settings.SummaryPreference
- android:key="status_header"
- android:selectable="false" />
+ <com.android.settings.SummaryPreference
+ android:key="status_header"
+ android:selectable="false" />
- <com.android.settings.applications.SpacePreference
- android:layout_height="5dp" />
+ <Preference
+ android:key="frequency"
+ android:selectable="false"
+ android:layout="@layout/horizontal_preference"
+ android:title="@string/running_frequency" />
- <Preference
- android:key="frequency"
- android:selectable="false"
- android:layout="@layout/horizontal_preference"
- android:title="@string/running_frequency" />
+ <Preference
+ android:key="max_usage"
+ android:selectable="false"
+ android:layout="@layout/horizontal_preference"
+ android:title="@string/memory_maximum_usage" />
- <Preference
- android:key="max_usage"
- android:selectable="false"
- android:layout="@layout/horizontal_preference"
- android:title="@string/memory_maximum_usage" />
+ </PreferenceCategory>
<PreferenceCategory
android:key="processes"
diff --git a/res/xml/app_storage_settings.xml b/res/xml/app_storage_settings.xml
index 6bd8ae3..1c71bfa 100644
--- a/res/xml/app_storage_settings.xml
+++ b/res/xml/app_storage_settings.xml
@@ -15,8 +15,14 @@
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:settings="http://schemas.android.com/apk/res-auto"
android:title="@string/application_info_label">
+ <com.android.settings.applications.LayoutPreference
+ android:key="header_view"
+ android:layout="@layout/app_action_buttons"
+ android:selectable="false" />
+
<com.android.settings.applications.SpacePreference
android:key="storage_space"
android:layout_height="8dp" />
@@ -36,13 +42,9 @@
<PreferenceCategory
android:key="storage_category"
android:layout="@layout/tall_preference_category"
- android:title="@string/storage_label">
-
- <Preference
- android:key="total_size"
- android:title="@string/total_size_label"
- android:selectable="false"
- android:layout="@layout/horizontal_preference" />
+ android:title="@string/app_info_storage_title"
+ settings:allowDividerAbove="false"
+ settings:allowDividerBelow="false">
<Preference
android:key="app_size"
@@ -56,32 +58,28 @@
android:selectable="false"
android:layout="@layout/horizontal_preference" />
- <com.android.settings.applications.LayoutPreference
- android:key="clear_data_button"
+ <Preference
+ android:key="cache_size"
+ android:title="@string/cache_size_label"
android:selectable="false"
- android:layout="@layout/single_button_panel" />
+ android:layout="@layout/horizontal_preference" />
+
+ <Preference
+ android:key="total_size"
+ android:title="@string/total_size_label"
+ android:selectable="false"
+ android:layout="@layout/horizontal_preference" />
+
+ <com.android.settings.applications.SpacePreference
+ android:layout_height="8dp" />
+
</PreferenceCategory>
- <com.android.settings.applications.SpacePreference
- android:layout_height="8dp" />
-
- <Preference
- android:key="cache_size"
- android:title="@string/cache_size_label"
- android:selectable="false"
- android:layout="@layout/horizontal_preference" />
-
- <com.android.settings.applications.LayoutPreference
- android:key="clear_cache_button"
- android:selectable="false"
- android:layout="@layout/single_button_panel" />
-
- <com.android.settings.applications.SpacePreference
- android:layout_height="8dp" />
-
<PreferenceCategory
android:key="uri_category"
- android:layout="@layout/headerless_preference_category" >
+ android:layout="@layout/headerless_preference_category"
+ settings:allowDividerAbove="false"
+ settings:allowDividerBelow="false">
<com.android.settings.applications.LayoutPreference
android:key="clear_uri_button"
android:layout="@layout/single_button_panel"
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index 015af17..34990ec 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -83,7 +83,10 @@
// Constants for state save/restore
private static final String SAVE_KEY_CATEGORIES = ":settings:categories";
- private static final String SAVE_KEY_SHOW_HOME_AS_UP = ":settings:show_home_as_up";
+ @VisibleForTesting
+ static final String SAVE_KEY_SHOW_HOME_AS_UP = ":settings:show_home_as_up";
+ @VisibleForTesting
+ static final String SAVE_KEY_SHOW_SEARCH = ":settings:show_search";
/**
* When starting this activity, the invoking Intent can contain this extra
@@ -192,8 +195,10 @@
private Button mNextButton;
- private boolean mDisplayHomeAsUpEnabled;
- private boolean mDisplaySearch;
+ @VisibleForTesting
+ boolean mDisplayHomeAsUpEnabled;
+ @VisibleForTesting
+ boolean mDisplaySearch;
private boolean mIsShowingDashboard;
private boolean mIsShortcut;
@@ -230,7 +235,6 @@
if (!mDisplaySearch) {
return false;
}
-
mSearchFeatureProvider.setUpSearchMenu(menu, this);
return true;
}
@@ -513,12 +517,28 @@
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
+ saveState(outState);
+ }
+ /**
+ * For testing purposes to avoid crashes from final variables in Activity's onSaveInstantState.
+ */
+ @VisibleForTesting
+ void saveState(Bundle outState) {
if (mCategories.size() > 0) {
outState.putParcelableArrayList(SAVE_KEY_CATEGORIES, mCategories);
}
outState.putBoolean(SAVE_KEY_SHOW_HOME_AS_UP, mDisplayHomeAsUpEnabled);
+ outState.putBoolean(SAVE_KEY_SHOW_SEARCH, mDisplaySearch);
+ }
+
+ @Override
+ protected void onRestoreInstanceState(Bundle savedInstanceState) {
+ super.onRestoreInstanceState(savedInstanceState);
+
+ mDisplayHomeAsUpEnabled = savedInstanceState.getBoolean(SAVE_KEY_SHOW_HOME_AS_UP);
+ mDisplaySearch = savedInstanceState.getBoolean(SAVE_KEY_SHOW_SEARCH);
}
@Override
diff --git a/src/com/android/settings/applications/AppStorageSettings.java b/src/com/android/settings/applications/AppStorageSettings.java
index 8d41558..0676f56 100644
--- a/src/com/android/settings/applications/AppStorageSettings.java
+++ b/src/com/android/settings/applications/AppStorageSettings.java
@@ -90,13 +90,10 @@
private static final String KEY_TOTAL_SIZE = "total_size";
private static final String KEY_APP_SIZE = "app_size";
- private static final String KEY_EXTERNAL_CODE_SIZE = "external_code_size";
private static final String KEY_DATA_SIZE = "data_size";
- private static final String KEY_EXTERNAL_DATA_SIZE = "external_data_size";
private static final String KEY_CACHE_SIZE = "cache_size";
- private static final String KEY_CLEAR_DATA = "clear_data_button";
- private static final String KEY_CLEAR_CACHE = "clear_cache_button";
+ private static final String KEY_HEADER_BUTTONS = "header_view";
private static final String KEY_URI_CATEGORY = "uri_category";
private static final String KEY_CLEAR_URI = "clear_uri_button";
@@ -119,16 +116,11 @@
private boolean mCanClearData = true;
private boolean mCacheCleared;
- private AppStorageStats mLastResult;
private AppStorageSizesController mSizeController;
private ClearCacheObserver mClearCacheObserver;
private ClearUserDataObserver mClearDataObserver;
- // Resource strings
- private CharSequence mInvalidSizeStr;
- private CharSequence mComputingStr;
-
private VolumeInfo[] mCandidates;
private AlertDialog.Builder mDialogBuilder;
private ApplicationInfo mInfo;
@@ -158,9 +150,6 @@
}
private void setupViews() {
- mComputingStr = getActivity().getText(R.string.computing_size);
- mInvalidSizeStr = getActivity().getText(R.string.invalid_size_value);
-
// Set default values on sizes
mSizeController = new AppStorageSizesController.Builder()
.setTotalSizePreference(findPreference(KEY_TOTAL_SIZE))
@@ -171,8 +160,8 @@
.setErrorString(R.string.invalid_size_value)
.build();
- mClearDataButton = (Button) ((LayoutPreference) findPreference(KEY_CLEAR_DATA))
- .findViewById(R.id.button);
+ mClearDataButton = (Button) ((LayoutPreference) findPreference(KEY_HEADER_BUTTONS))
+ .findViewById(R.id.left_button);
mStorageUsed = findPreference(KEY_STORAGE_USED);
mChangeStorageButton = (Button) ((LayoutPreference) findPreference(KEY_CHANGE_STORAGE))
@@ -182,8 +171,8 @@
// Cache section
mCacheSize = findPreference(KEY_CACHE_SIZE);
- mClearCacheButton = (Button) ((LayoutPreference) findPreference(KEY_CLEAR_CACHE))
- .findViewById(R.id.button);
+ mClearCacheButton = (Button) ((LayoutPreference) findPreference(KEY_HEADER_BUTTONS))
+ .findViewById(R.id.right_button);
mClearCacheButton.setText(R.string.clear_cache_btn_text);
// URI permissions section
@@ -267,7 +256,7 @@
if (mAppEntry == null) {
return false;
}
- updateUiWithSize(mLastResult);
+ updateUiWithSize(mSizeController.getLastResult());
refreshGrantedUriPermissions();
final VolumeInfo currentVol = getActivity().getPackageManager()
diff --git a/src/com/android/settings/applications/AppStorageSizesController.java b/src/com/android/settings/applications/AppStorageSizesController.java
index 94935bd..23a3eb2 100644
--- a/src/com/android/settings/applications/AppStorageSizesController.java
+++ b/src/com/android/settings/applications/AppStorageSizesController.java
@@ -110,6 +110,13 @@
mCachedCleared = isCleared;
}
+ /**
+ * Returns the last result calculated, if it exists. If it does not, returns null.
+ */
+ public StorageStatsSource.AppStorageStats getLastResult() {
+ return mLastResult;
+ }
+
private String getSizeStr(Context context, long size) {
return Formatter.formatFileSize(context, size);
}
diff --git a/src/com/android/settings/applications/MusicViewHolderController.java b/src/com/android/settings/applications/MusicViewHolderController.java
index 4599fcc..69f8958 100644
--- a/src/com/android/settings/applications/MusicViewHolderController.java
+++ b/src/com/android/settings/applications/MusicViewHolderController.java
@@ -61,7 +61,7 @@
@Override
public void setupView(AppViewHolder holder) {
- holder.appIcon.setImageDrawable(mContext.getDrawable(R.drawable.empty_icon));
+ holder.appIcon.setImageDrawable(mContext.getDrawable(R.drawable.ic_media_stream_on_24dp));
holder.appName.setText(mContext.getText(R.string.audio_files_title));
holder.summary.setText(Formatter.formatFileSize(mContext, mMusicSize));
}
diff --git a/src/com/android/settings/applications/assist/DefaultAssistPreferenceController.java b/src/com/android/settings/applications/assist/DefaultAssistPreferenceController.java
index 747ce4d..b8d6a87 100644
--- a/src/com/android/settings/applications/assist/DefaultAssistPreferenceController.java
+++ b/src/com/android/settings/applications/assist/DefaultAssistPreferenceController.java
@@ -24,6 +24,7 @@
import android.service.voice.VoiceInteractionService;
import android.service.voice.VoiceInteractionServiceInfo;
+import android.support.annotation.VisibleForTesting;
import com.android.internal.app.AssistUtils;
import com.android.settings.applications.defaultapps.DefaultAppInfo;
import com.android.settings.applications.defaultapps.DefaultAppPreferenceController;
@@ -56,13 +57,10 @@
if (services == null || services.isEmpty()) {
return null;
}
- final ResolveInfo resolveInfo = services.get(0);
- final VoiceInteractionServiceInfo voiceInfo =
- new VoiceInteractionServiceInfo(pm, resolveInfo.serviceInfo);
- if (!voiceInfo.getSupportsAssist()) {
+ final String activity = getAssistSettingsActivity(cn, services.get(0), pm);
+ if (activity == null) {
return null;
}
- final String activity = voiceInfo.getSettingsActivity();
return new Intent(Intent.ACTION_MAIN)
.setComponent(new ComponentName(cn.getPackageName(), activity));
}
@@ -85,4 +83,14 @@
}
return new DefaultAppInfo(mPackageManager, mUserId, cn);
}
+
+ @VisibleForTesting
+ String getAssistSettingsActivity(ComponentName cn, ResolveInfo resolveInfo, PackageManager pm) {
+ final VoiceInteractionServiceInfo voiceInfo =
+ new VoiceInteractionServiceInfo(pm, resolveInfo.serviceInfo);
+ if (!voiceInfo.getSupportsAssist()) {
+ return null;
+ }
+ return voiceInfo.getSettingsActivity();
+ }
}
diff --git a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
index 602e65f..bc64ffa 100644
--- a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
+++ b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
@@ -117,7 +117,7 @@
@Override
public void onResume() {
super.onResume();
- getLoaderManager().initLoader(STORAGE_JOB_ID, Bundle.EMPTY, this);
+ getLoaderManager().restartLoader(STORAGE_JOB_ID, Bundle.EMPTY, this);
getLoaderManager().initLoader(ICON_JOB_ID, Bundle.EMPTY, new IconLoaderCallbacks());
}
diff --git a/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java b/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java
index e83c5d2..cf0239d 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java
@@ -79,8 +79,15 @@
UserHandle myUser = UserHandle.of(userId);
for (int i = 0, size = applicationInfos.size(); i < size; i++) {
ApplicationInfo app = applicationInfos.get(i);
- StorageStatsSource.AppStorageStats stats =
- mStatsManager.getStatsForPackage(mUuid, app.packageName, myUser);
+
+ StorageStatsSource.AppStorageStats stats;
+ try {
+ stats = mStatsManager.getStatsForPackage(mUuid, app.packageName, myUser);
+ } catch (IllegalStateException e) {
+ // This may happen if the package was removed during our calculation.
+ Log.w("App unexpectedly not found", e);
+ continue;
+ }
long attributedAppSizeInBytes = stats.getDataBytes();
// This matches how the package manager calculates sizes -- by zeroing out code sizes of
diff --git a/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java b/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java
index 3509834..a0ebba8 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java
@@ -172,7 +172,7 @@
mUsageListGroup.removeAll();
for (int i = 0, size = dataList.size(); i < size; i++) {
final PowerUsageData batteryData = dataList.get(i);
- if (shouldHide(batteryData)) {
+ if (shouldHideCategory(batteryData)) {
continue;
}
final PowerGaugePreference pref = new PowerGaugePreference(getPrefContext());
@@ -217,7 +217,7 @@
}
@VisibleForTesting
- boolean shouldHide(PowerUsageData powerUsageData) {
+ boolean shouldHideCategory(PowerUsageData powerUsageData) {
if (powerUsageData.usageType == UsageType.UNACCOUNTED
|| powerUsageData.usageType == UsageType.OVERCOUNTED) {
return true;
@@ -264,6 +264,9 @@
@VisibleForTesting
void updateUsageDataSummary(PowerUsageData usageData, double totalPower, int dischargeAmount) {
+ if (shouldHideSummary(usageData)) {
+ return;
+ }
if (usageData.usageList.size() <= 1) {
usageData.summary = getString(R.string.battery_used_for,
Utils.formatElapsedTime(getContext(), usageData.totalUsageTimeMs, false));
@@ -278,6 +281,13 @@
}
@VisibleForTesting
+ boolean shouldHideSummary(PowerUsageData powerUsageData) {
+ @UsageType final int usageType = powerUsageData.usageType;
+
+ return usageType == UsageType.CELL;
+ }
+
+ @VisibleForTesting
BatterySipper findBatterySipperWithMaxBatteryUsage(List<BatterySipper> usageList) {
BatterySipper sipper = usageList.get(0);
for (int i = 1, size = usageList.size(); i < size; i++) {
diff --git a/src/com/android/settings/network/NetworkResetActionMenuController.java b/src/com/android/settings/network/NetworkResetActionMenuController.java
index 028ac7b..254834b 100644
--- a/src/com/android/settings/network/NetworkResetActionMenuController.java
+++ b/src/com/android/settings/network/NetworkResetActionMenuController.java
@@ -17,9 +17,6 @@
package com.android.settings.network;
import android.content.Context;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.support.annotation.VisibleForTesting;
import android.view.Menu;
import android.view.MenuItem;
@@ -27,15 +24,16 @@
import com.android.settings.R;
import com.android.settings.ResetNetwork;
import com.android.settings.Utils;
-import com.android.settingslib.RestrictedLockUtils;
public class NetworkResetActionMenuController {
private static final int MENU_NETWORK_RESET = Menu.FIRST + 200;
private final Context mContext;
+ private final NetworkResetRestrictionChecker mRestrictionChecker;
public NetworkResetActionMenuController(Context context) {
mContext = context;
+ mRestrictionChecker = new NetworkResetRestrictionChecker(context);
}
public void buildMenuItem(Menu menu) {
@@ -53,14 +51,8 @@
}
}
- @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+
boolean isAvailable() {
- return isAvailable(mContext);
+ return !mRestrictionChecker.hasRestriction();
}
-
- static boolean isAvailable(Context context) {
- return !RestrictedLockUtils.hasBaseUserRestriction(context,
- UserManager.DISALLOW_NETWORK_RESET, UserHandle.myUserId());
- }
-
}
diff --git a/src/com/android/settings/network/NetworkResetPreferenceController.java b/src/com/android/settings/network/NetworkResetPreferenceController.java
index 04573c9..ce36a7f 100644
--- a/src/com/android/settings/network/NetworkResetPreferenceController.java
+++ b/src/com/android/settings/network/NetworkResetPreferenceController.java
@@ -22,13 +22,16 @@
public class NetworkResetPreferenceController extends PreferenceController {
+ private final NetworkResetRestrictionChecker mRestrictionChecker;
+
public NetworkResetPreferenceController(Context context) {
super(context);
+ mRestrictionChecker = new NetworkResetRestrictionChecker(context);
}
@Override
public boolean isAvailable() {
- return NetworkResetActionMenuController.isAvailable(mContext);
+ return !mRestrictionChecker.hasRestriction();
}
@Override
diff --git a/src/com/android/settings/network/NetworkResetRestrictionChecker.java b/src/com/android/settings/network/NetworkResetRestrictionChecker.java
new file mode 100644
index 0000000..4fe9f59
--- /dev/null
+++ b/src/com/android/settings/network/NetworkResetRestrictionChecker.java
@@ -0,0 +1,53 @@
+/*
+ * 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.network;
+
+import android.content.Context;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.support.annotation.VisibleForTesting;
+
+import com.android.settingslib.RestrictedLockUtils;
+
+public class NetworkResetRestrictionChecker {
+
+ private final Context mContext;
+ private final UserManager mUserManager;
+
+ public NetworkResetRestrictionChecker(Context context) {
+ mContext = context;
+ mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
+ }
+
+ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+ boolean hasUserBaseRestriction() {
+ return RestrictedLockUtils.hasBaseUserRestriction(mContext,
+ UserManager.DISALLOW_NETWORK_RESET, UserHandle.myUserId());
+ }
+
+ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+ boolean isRestrictionEnforcedByAdmin() {
+ return RestrictedLockUtils.checkIfRestrictionEnforced(
+ mContext, UserManager.DISALLOW_NETWORK_RESET, UserHandle.myUserId()) != null;
+ }
+
+ boolean hasRestriction() {
+ return !mUserManager.isAdminUser()
+ || hasUserBaseRestriction()
+ || isRestrictionEnforcedByAdmin();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/SettingsActivityTest.java b/tests/robotests/src/com/android/settings/SettingsActivityTest.java
index 9d53bc8..65e9708 100644
--- a/tests/robotests/src/com/android/settings/SettingsActivityTest.java
+++ b/tests/robotests/src/com/android/settings/SettingsActivityTest.java
@@ -16,20 +16,28 @@
package com.android.settings;
+import android.app.Activity;
import android.app.ActivityManager;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
+import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.view.Menu;
+import com.android.settings.testutils.FakeFeatureFactory;
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;
+import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.doReturn;
@@ -42,6 +50,9 @@
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class SettingsActivityTest {
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private Context mContext;
+
@Mock
private FragmentManager mFragmentManager;
@Mock
@@ -50,10 +61,15 @@
private Bitmap mBitmap;
private SettingsActivity mActivity;
+ private FakeFeatureFactory mFeatureFactory;
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
+ FakeFeatureFactory.setupForTest(mContext);
+ mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
+
mActivity = spy(new SettingsActivity());
doReturn(mBitmap).when(mActivity).getBitmapFromXmlResource(anyInt());
}
@@ -61,7 +77,6 @@
@Test
public void launchSettingFragment_nullExtraShowFragment_shouldNotCrash()
throws ClassNotFoundException {
- mActivity = spy(new SettingsActivity());
when(mActivity.getFragmentManager()).thenReturn(mFragmentManager);
when(mFragmentManager.beginTransaction()).thenReturn(mock(FragmentTransaction.class));
@@ -76,4 +91,51 @@
verify(mTaskDescription).setIcon(any());
}
+
+ @Test
+ public void testCreateOptionsMenu_setsUpSearch() {
+ ReflectionHelpers.setField(mActivity, "mSearchFeatureProvider",
+ mFeatureFactory.getSearchFeatureProvider());
+ mActivity.mDisplaySearch = true;
+ mActivity.onCreateOptionsMenu(null);
+
+ verify(mFeatureFactory.getSearchFeatureProvider()).setUpSearchMenu(any(Menu.class),
+ any(Activity.class));
+ }
+
+ @Test
+ public void testSaveState_DisplaySearchSaved() {
+ mActivity.mDisplaySearch = true;
+ Bundle bundle = new Bundle();
+ mActivity.saveState(bundle);
+
+ assertThat((boolean) bundle.get(SettingsActivity.SAVE_KEY_SHOW_SEARCH)).isTrue();
+ }
+
+ @Test
+ public void testSaveState_EnabledHomeSaved() {
+ mActivity.mDisplayHomeAsUpEnabled = true;
+ Bundle bundle = new Bundle();
+ mActivity.saveState(bundle);
+
+ assertThat((boolean) bundle.get(SettingsActivity.SAVE_KEY_SHOW_HOME_AS_UP)).isTrue();
+ }
+
+ @Test
+ public void testRestoreState_DisplaySearchRestored() {
+ Bundle bundle = new Bundle();
+ bundle.putBoolean(SettingsActivity.SAVE_KEY_SHOW_SEARCH, true);
+ mActivity.onRestoreInstanceState(bundle);
+
+ assertThat(mActivity.mDisplaySearch).isTrue();
+ }
+
+ @Test
+ public void testRestoreState_EnabledHomeRestored() {
+ Bundle bundle = new Bundle();
+ bundle.putBoolean(SettingsActivity.SAVE_KEY_SHOW_SEARCH, true);
+ mActivity.onRestoreInstanceState(bundle);
+
+ assertThat(mActivity.mDisplaySearch).isTrue();
+ }
}
diff --git a/tests/robotests/src/com/android/settings/applications/assist/DefaultAssistPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/assist/DefaultAssistPreferenceControllerTest.java
index 1182762..728a8a5 100644
--- a/tests/robotests/src/com/android/settings/applications/assist/DefaultAssistPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/assist/DefaultAssistPreferenceControllerTest.java
@@ -16,7 +16,16 @@
package com.android.settings.applications.assist;
+import android.Manifest;
+import android.app.SearchManager;
+import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
import android.provider.Settings;
import com.android.settings.SettingsRobolectricTestRunner;
@@ -24,6 +33,8 @@
import com.android.settings.applications.defaultapps.DefaultAppInfo;
import com.android.settings.testutils.shadow.ShadowSecureSettings;
+import java.util.ArrayList;
+import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -32,6 +43,13 @@
import org.robolectric.annotation.Config;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
@@ -39,6 +57,10 @@
@Mock
private Context mContext;
+ @Mock
+ private SearchManager mSearchManager;
+ @Mock
+ private PackageManager mPackageManager;
private DefaultAssistPreferenceController mController;
@Before
@@ -61,4 +83,33 @@
assertThat(appInfo.getKey()).isEqualTo(flattenKey);
}
+
+ @Test
+ public void getSettingIntent_noSettingsActivity_shouldNotCrash() {
+ final String flattenKey = "com.android.settings/assist";
+ ShadowSecureSettings.putString(null, Settings.Secure.ASSISTANT, flattenKey);
+ when(mContext.getPackageManager()).thenReturn(mPackageManager);
+ DefaultAssistPreferenceController controller =
+ spy(new DefaultAssistPreferenceController(mContext));
+ final ResolveInfo resolveInfo = new ResolveInfo();
+ resolveInfo.activityInfo = new ActivityInfo();
+ resolveInfo.activityInfo.name = "assist";
+ resolveInfo.activityInfo.applicationInfo = new ApplicationInfo();
+ resolveInfo.activityInfo.applicationInfo.packageName = "com.android.settings";
+ when(mPackageManager.resolveActivityAsUser(any(Intent.class), anyInt(), anyInt()))
+ .thenReturn(resolveInfo);
+ when(mContext.getSystemService(Context.SEARCH_SERVICE)).thenReturn(mSearchManager);
+ when(mSearchManager.getAssistIntent(anyBoolean())).thenReturn(mock(Intent.class));
+ final ServiceInfo serviceInfo = new ServiceInfo();
+ serviceInfo.permission = Manifest.permission.BIND_VOICE_INTERACTION;
+ resolveInfo.serviceInfo = serviceInfo;
+ final List<ResolveInfo> services = new ArrayList<>();
+ services.add(resolveInfo);
+ when(mPackageManager.queryIntentServices(any(Intent.class), anyInt())).thenReturn(services);
+ doReturn(null).when(controller).getAssistSettingsActivity(
+ ComponentName.unflattenFromString(flattenKey), resolveInfo, mPackageManager);
+
+ controller.getSettingIntent(null);
+ // should not crash
+ }
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageAdvancedTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageAdvancedTest.java
index 4216d57..3f87bb4 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageAdvancedTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageAdvancedTest.java
@@ -228,22 +228,36 @@
public void testShouldHide_typeUnAccounted_returnTrue() {
mPowerUsageData.usageType = UsageType.UNACCOUNTED;
- assertThat(mPowerUsageAdvanced.shouldHide(mPowerUsageData)).isTrue();
+ assertThat(mPowerUsageAdvanced.shouldHideCategory(mPowerUsageData)).isTrue();
}
@Test
- public void testShouldHide_typeOverCounted_returnTrue() {
+ public void testShouldHideCategory_typeOverCounted_returnTrue() {
mPowerUsageData.usageType = UsageType.OVERCOUNTED;
- assertThat(mPowerUsageAdvanced.shouldHide(mPowerUsageData)).isTrue();
+ assertThat(mPowerUsageAdvanced.shouldHideCategory(mPowerUsageData)).isTrue();
}
-
@Test
- public void testShouldHide_typeNormal_returnFalse() {
+ public void testShouldHideCategory_typeNormal_returnFalse() {
mPowerUsageData.usageType = UsageType.APP;
- assertThat(mPowerUsageAdvanced.shouldHide(mPowerUsageData)).isFalse();
+ assertThat(mPowerUsageAdvanced.shouldHideCategory(mPowerUsageData)).isFalse();
}
+
+ @Test
+ public void testShouldHideSummary_typeCell_returnTrue() {
+ mPowerUsageData.usageType = UsageType.CELL;
+
+ assertThat(mPowerUsageAdvanced.shouldHideSummary(mPowerUsageData)).isTrue();
+ }
+
+ @Test
+ public void testShouldHideSummary_typeNormal_returnFalse() {
+ mPowerUsageData.usageType = UsageType.APP;
+
+ assertThat(mPowerUsageAdvanced.shouldHideSummary(mPowerUsageData)).isFalse();
+ }
+
}
diff --git a/tests/robotests/src/com/android/settings/network/NetworkResetActionMenuControllerTest.java b/tests/robotests/src/com/android/settings/network/NetworkResetActionMenuControllerTest.java
index 7cd76d3..ee6ef69 100644
--- a/tests/robotests/src/com/android/settings/network/NetworkResetActionMenuControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/NetworkResetActionMenuControllerTest.java
@@ -19,9 +19,7 @@
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
-import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -39,6 +37,7 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
@@ -50,19 +49,21 @@
private Menu mMenu;
@Mock
private MenuItem mMenuItem;
+ @Mock
+ private NetworkResetRestrictionChecker mRestrictionChecker;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
- mController = spy(new NetworkResetActionMenuController(mContext));
+ mController = new NetworkResetActionMenuController(mContext);
+ ReflectionHelpers.setField(mController, "mRestrictionChecker", mRestrictionChecker);
when(mMenu.add(anyInt(), anyInt(), anyInt(), anyInt())).thenReturn(mMenuItem);
}
@Test
public void buildMenuItem_available_shouldAddToMenu() {
- doReturn(true).when(mController).isAvailable();
-
+ when(mRestrictionChecker.hasRestriction()).thenReturn(false);
mController.buildMenuItem(mMenu);
verify(mMenu).add(anyInt(), anyInt(), anyInt(), anyInt());
@@ -71,7 +72,7 @@
@Test
public void buildMenuItem_notAvailable_shouldNotAddToMenu() {
- doReturn(false).when(mController).isAvailable();
+ when(mRestrictionChecker.hasRestriction()).thenReturn(true);
mController.buildMenuItem(mMenu);
diff --git a/tests/robotests/src/com/android/settings/network/NetworkResetRestrictionCheckerTest.java b/tests/robotests/src/com/android/settings/network/NetworkResetRestrictionCheckerTest.java
new file mode 100644
index 0000000..b1c88d5
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/network/NetworkResetRestrictionCheckerTest.java
@@ -0,0 +1,90 @@
+/*
+ * 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.network;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.UserManager;
+
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class NetworkResetRestrictionCheckerTest {
+
+ @Mock
+ private UserManager mUserManager;
+ @Mock
+ private Context mContext;
+ private NetworkResetRestrictionChecker mRestrictionChecker;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+ mRestrictionChecker = spy(new NetworkResetRestrictionChecker(mContext));
+ }
+
+ @Test
+ public void testHasRestriction_notAdmin_shouldReturnTrue() {
+ final Context context = mock(Context.class);
+ when(context.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+ when(mUserManager.isAdminUser()).thenReturn(false);
+
+ assertThat(mRestrictionChecker.hasRestriction()).isTrue();
+ }
+
+ @Test
+ public void testHasRestriction_hasUserRestriction_shouldReturnTrue() {
+ when(mUserManager.isAdminUser()).thenReturn(true);
+ doReturn(true).when(mRestrictionChecker).hasUserBaseRestriction();
+ doReturn(false).when(mRestrictionChecker).isRestrictionEnforcedByAdmin();
+
+ assertThat(mRestrictionChecker.hasRestriction()).isTrue();
+ }
+
+ @Test
+ public void testHasRestriction_hasAdminRestriction_shouldReturnTrue() {
+ when(mUserManager.isAdminUser()).thenReturn(true);
+ doReturn(false).when(mRestrictionChecker).hasUserBaseRestriction();
+ doReturn(true).when(mRestrictionChecker).isRestrictionEnforcedByAdmin();
+
+ assertThat(mRestrictionChecker.hasRestriction()).isTrue();
+ }
+
+ @Test
+ public void testHasRestriction_noRestriction_shouldReturnFalse() {
+ when(mUserManager.isAdminUser()).thenReturn(true);
+ doReturn(false).when(mRestrictionChecker).hasUserBaseRestriction();
+ doReturn(false).when(mRestrictionChecker).isRestrictionEnforcedByAdmin();
+
+ assertThat(mRestrictionChecker.hasRestriction()).isFalse();
+ }
+}
diff --git a/tests/unit/src/com/android/settings/deviceinfo/storage/StorageAsyncLoaderTest.java b/tests/unit/src/com/android/settings/deviceinfo/storage/StorageAsyncLoaderTest.java
index e82482e..f7131b3 100644
--- a/tests/unit/src/com/android/settings/deviceinfo/storage/StorageAsyncLoaderTest.java
+++ b/tests/unit/src/com/android/settings/deviceinfo/storage/StorageAsyncLoaderTest.java
@@ -180,6 +180,20 @@
assertThat(result.get(PRIMARY_USER_ID).otherAppsSize).isEqualTo(0);
}
+ @Test
+ public void testRemovedPackageDoesNotCrash() throws Exception {
+ ApplicationInfo info = new ApplicationInfo();
+ info.packageName = PACKAGE_NAME_1;
+ info.category = ApplicationInfo.CATEGORY_UNDEFINED;
+ mInfo.add(info);
+ when(mSource.getStatsForPackage(anyString(), anyString(), any(UserHandle.class)))
+ .thenThrow(new IllegalStateException());
+
+ SparseArray<StorageAsyncLoader.AppsStorageResult> result = mLoader.loadInBackground();
+
+ // Should not crash.
+ }
+
private ApplicationInfo addPackage(
String packageName, long cacheSize, long codeSize, long dataSize, int category) {
StorageStatsSource.AppStorageStats storageStats =