resolveInfos =
+ activity.getPackageManager().queryIntentActivities(intent,
+ PackageManager.MATCH_DEFAULT_ONLY);
+ if (resolveInfos.isEmpty()) {
+ return;
+ }
+
+ final ComponentName searchComponentName = resolveInfos.get(0)
+ .getComponentInfo().getComponentName();
+ // Set a component name since activity embedding requires a component name for
+ // registering a rule.
+ intent.setComponent(searchComponentName);
+ ActivityEmbeddingRulesController.registerTwoPanePairRuleForSettingsHome(
+ context,
+ searchComponentName,
+ intent.getAction(),
+ false /* finishPrimaryWithSecondary */,
+ true /* finishSecondaryWithPrimary */,
+ false /* clearTop */);
+
toolbar.setOnClickListener(tb -> {
- final Context context = activity.getApplicationContext();
- final Intent intent = buildSearchIntent(context, pageId);
-
- if (activity.getPackageManager().queryIntentActivities(intent,
- PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
- return;
- }
-
FeatureFactory.getFactory(context).getSlicesFeatureProvider()
.indexSliceDataAsync(context);
FeatureFactory.getFactory(context).getMetricsFeatureProvider()
.logSettingsTileClick(KEY_HOMEPAGE_SEARCH_BAR, pageId);
+
final Bundle bundle = ActivityOptions.makeSceneTransitionAnimation(activity).toBundle();
- activity.startActivityForResult(intent, REQUEST_CODE, bundle);
+ activity.startActivity(intent, bundle);
});
}
diff --git a/src/com/android/settings/search/SearchFeatureProviderImpl.java b/src/com/android/settings/search/SearchFeatureProviderImpl.java
index 508d37d7e6a..6f909709058 100644
--- a/src/com/android/settings/search/SearchFeatureProviderImpl.java
+++ b/src/com/android/settings/search/SearchFeatureProviderImpl.java
@@ -50,7 +50,7 @@ public class SearchFeatureProviderImpl implements SearchFeatureProvider {
if (isSettingsPackage || isAllowlistedPackage) {
return;
}
- throw new SecurityException("Search result intents must be called with from a "
+ throw new SecurityException("Search result intents must be called with from an "
+ "allowlisted package.");
}
diff --git a/src/com/android/settings/search/SearchResultTrampoline.java b/src/com/android/settings/search/SearchResultTrampoline.java
index e9304739460..8b041b67f87 100644
--- a/src/com/android/settings/search/SearchResultTrampoline.java
+++ b/src/com/android/settings/search/SearchResultTrampoline.java
@@ -20,46 +20,112 @@ import static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENT
import static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT_TAB;
import android.app.Activity;
+import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.Log;
import com.android.settings.SettingsActivity;
+import com.android.settings.SettingsApplication;
import com.android.settings.SubSettings;
+import com.android.settings.activityembedding.ActivityEmbeddingRulesController;
+import com.android.settings.activityembedding.ActivityEmbeddingUtils;
+import com.android.settings.homepage.SettingsHomepageActivity;
import com.android.settings.overlay.FeatureFactory;
+import java.net.URISyntaxException;
+
/**
* A trampoline activity that launches setting result page.
*/
public class SearchResultTrampoline extends Activity {
+ private static final String TAG = "SearchResultTrampoline";
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ final ComponentName callingActivity = getCallingActivity();
// First make sure caller has privilege to launch a search result page.
FeatureFactory.getFactory(this)
.getSearchFeatureProvider()
- .verifyLaunchSearchResultPageCaller(this, getCallingActivity());
+ .verifyLaunchSearchResultPageCaller(this, callingActivity);
// Didn't crash, proceed and launch the result as a subsetting.
- final Intent intent = getIntent();
+ Intent intent = getIntent();
+ final String highlightMenuKey = intent.getStringExtra(
+ Settings.EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_HIGHLIGHT_MENU_KEY);
- // Hack to take EXTRA_FRAGMENT_ARG_KEY from intent and set into
- // EXTRA_SHOW_FRAGMENT_ARGUMENTS. This is necessary because intent could be from external
- // caller and args may not persisted.
- final String settingKey = intent.getStringExtra(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY);
- final int tab = intent.getIntExtra(EXTRA_SHOW_FRAGMENT_TAB, 0);
- final Bundle args = new Bundle();
- args.putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, settingKey);
- args.putInt(EXTRA_SHOW_FRAGMENT_TAB, tab);
- intent.putExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS, args);
+ final String fragment = intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT);
+ if (!TextUtils.isEmpty(fragment)) {
+ // Hack to take EXTRA_FRAGMENT_ARG_KEY from intent and set into
+ // EXTRA_SHOW_FRAGMENT_ARGUMENTS. This is necessary because intent could be from
+ // external caller and args may not persisted.
+ final String settingKey = intent.getStringExtra(
+ SettingsActivity.EXTRA_FRAGMENT_ARG_KEY);
+ final int tab = intent.getIntExtra(EXTRA_SHOW_FRAGMENT_TAB, 0);
+ final Bundle args = new Bundle();
+ args.putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, settingKey);
+ args.putInt(EXTRA_SHOW_FRAGMENT_TAB, tab);
+ intent.putExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS, args);
- // Reroute request to SubSetting.
- intent.setClass(this /* context */, SubSettings.class)
- .addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
- startActivity(intent);
+ // Reroute request to SubSetting.
+ intent.setClass(this /* context */, SubSettings.class);
+ } else {
+ // Direct link case
+ final String intentUriString = intent.getStringExtra(
+ Settings.EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_INTENT_URI);
+ if (TextUtils.isEmpty(intentUriString)) {
+ Log.e(TAG, "No EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_INTENT_URI for deep link");
+ finish();
+ return;
+ }
+
+ try {
+ intent = Intent.parseUri(intentUriString, Intent.URI_INTENT_SCHEME);
+ } catch (URISyntaxException e) {
+ Log.e(TAG, "Failed to parse deep link intent: " + e);
+ finish();
+ return;
+ }
+ }
+
+ intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
+
+ if (!ActivityEmbeddingUtils.isEmbeddingActivityEnabled(this)) {
+ startActivity(intent);
+ } else if (isSettingsIntelligence(callingActivity)) {
+ // Register SplitPairRule for SubSettings, set clearTop false to prevent unexpected back
+ // navigation behavior.
+ ActivityEmbeddingRulesController.registerSubSettingsPairRule(this,
+ false /* clearTop */);
+
+ intent.setFlags(intent.getFlags() & ~Intent.FLAG_ACTIVITY_NEW_TASK);
+ startActivity(intent);
+
+ // Pass menu key to homepage
+ final SettingsHomepageActivity homeActivity =
+ ((SettingsApplication) getApplicationContext()).getHomeActivity();
+ if (homeActivity != null) {
+ homeActivity.getMainFragment().setHighlightMenuKey(highlightMenuKey,
+ /* scrollNeeded= */ true);
+ }
+ } else {
+ // Two-pane case
+ startActivity(SettingsActivity.getTrampolineIntent(intent, highlightMenuKey)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+ }
// Done.
finish();
}
+ private boolean isSettingsIntelligence(ComponentName callingActivity) {
+ return callingActivity != null && TextUtils.equals(
+ callingActivity.getPackageName(),
+ FeatureFactory.getFactory(this).getSearchFeatureProvider()
+ .getSettingsIntelligencePkgName(this));
+ }
}
diff --git a/src/com/android/settings/search/SearchStateReceiver.java b/src/com/android/settings/search/SearchStateReceiver.java
new file mode 100644
index 00000000000..d1f6f161a48
--- /dev/null
+++ b/src/com/android/settings/search/SearchStateReceiver.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2021 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.search;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.settings.SettingsApplication;
+import com.android.settings.homepage.SettingsHomepageActivity;
+
+/**
+ * A broadcast receiver that monitors the search state to show/hide the menu highlight
+ */
+public class SearchStateReceiver extends BroadcastReceiver {
+
+ private static final String TAG = "SearchStateReceiver";
+ private static final String ACTION_SEARCH_START = "com.android.settings.SEARCH_START";
+ private static final String ACTION_SEARCH_EXIT = "com.android.settings.SEARCH_EXIT";
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent == null) {
+ Log.w(TAG, "Null intent");
+ return;
+ }
+
+ final SettingsHomepageActivity homeActivity =
+ ((SettingsApplication) context.getApplicationContext()).getHomeActivity();
+ if (homeActivity == null) {
+ return;
+ }
+
+ final String action = intent.getAction();
+ Log.d(TAG, "action: " + action);
+ if (TextUtils.equals(ACTION_SEARCH_START, action)) {
+ homeActivity.getMainFragment().setMenuHighlightShowed(false);
+ } else if (TextUtils.equals(ACTION_SEARCH_EXIT, action)) {
+ homeActivity.getMainFragment().setMenuHighlightShowed(true);
+ }
+ }
+}
diff --git a/src/com/android/settings/search/SettingsSearchIndexablesProvider.java b/src/com/android/settings/search/SettingsSearchIndexablesProvider.java
index feb9510bff9..d6635a197c2 100644
--- a/src/com/android/settings/search/SettingsSearchIndexablesProvider.java
+++ b/src/com/android/settings/search/SettingsSearchIndexablesProvider.java
@@ -365,7 +365,6 @@ public class SettingsSearchIndexablesProvider extends SearchIndexablesProvider {
// The classname and intent information comes from the PreIndexData
// This will be more clear when provider conversion is done at PreIndex time.
raw.className = bundle.getTargetClass().getName();
-
}
rawList.addAll(providerRaws);
}
diff --git a/src/com/android/settings/security/CredentialStorage.java b/src/com/android/settings/security/CredentialStorage.java
index 090fdf6bb07..ea336314566 100644
--- a/src/com/android/settings/security/CredentialStorage.java
+++ b/src/com/android/settings/security/CredentialStorage.java
@@ -86,7 +86,7 @@ public final class CredentialStorage extends FragmentActivity {
final String action = intent.getAction();
final UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
if (!userManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_CREDENTIALS)) {
- if (ACTION_RESET.equals(action)) {
+ if (ACTION_RESET.equals(action) && checkCallerIsSelf()) {
new ResetDialog();
} else {
if (ACTION_INSTALL.equals(action) && checkCallerIsCertInstallerOrSelfInProfile()) {
@@ -318,6 +318,19 @@ public final class CredentialStorage extends FragmentActivity {
finish();
}
+ /**
+ * Check that the caller is Settings.
+ */
+ private boolean checkCallerIsSelf() {
+ try {
+ return Process.myUid() == android.app.ActivityManager.getService()
+ .getLaunchedFromUid(getActivityToken());
+ } catch (RemoteException re) {
+ // Error talking to ActivityManager, just give up
+ return false;
+ }
+ }
+
/**
* Check that the caller is either certinstaller or Settings running in a profile of this user.
*/
diff --git a/src/com/android/settings/security/RequestManageCredentials.java b/src/com/android/settings/security/RequestManageCredentials.java
index 1a8da671a2c..6a1d40aef7a 100644
--- a/src/com/android/settings/security/RequestManageCredentials.java
+++ b/src/com/android/settings/security/RequestManageCredentials.java
@@ -16,6 +16,8 @@
package com.android.settings.security;
+import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+
import android.annotation.Nullable;
import android.app.Activity;
import android.app.admin.DevicePolicyEventLogger;
@@ -120,6 +122,7 @@ public class RequestManageCredentials extends Activity {
.setStrings(mCredentialManagerPackage)
.write();
setContentView(R.layout.request_manage_credentials);
+ getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
mIsLandscapeMode = getResources().getConfiguration().orientation
== Configuration.ORIENTATION_LANDSCAPE;
@@ -211,7 +214,9 @@ public class RequestManageCredentials extends Activity {
private void loadButtons() {
mButtonPanel = findViewById(R.id.button_panel);
Button dontAllowButton = findViewById(R.id.dont_allow_button);
+ dontAllowButton.setFilterTouchesWhenObscured(true);
Button allowButton = findViewById(R.id.allow_button);
+ allowButton.setFilterTouchesWhenObscured(true);
dontAllowButton.setOnClickListener(b -> {
DevicePolicyEventLogger
diff --git a/src/com/android/settings/security/ShowPasswordPreferenceController.java b/src/com/android/settings/security/ShowPasswordPreferenceController.java
index 472101bfc55..696854a3ce5 100644
--- a/src/com/android/settings/security/ShowPasswordPreferenceController.java
+++ b/src/com/android/settings/security/ShowPasswordPreferenceController.java
@@ -58,5 +58,9 @@ public class ShowPasswordPreferenceController extends TogglePreferenceController
? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
+ @Override
+ public int getSliceHighlightMenuRes() {
+ return R.string.menu_key_security;
+ }
}
diff --git a/src/com/android/settings/security/VisiblePatternProfilePreferenceController.java b/src/com/android/settings/security/VisiblePatternProfilePreferenceController.java
index 64ca8537b56..9e82e78ede3 100644
--- a/src/com/android/settings/security/VisiblePatternProfilePreferenceController.java
+++ b/src/com/android/settings/security/VisiblePatternProfilePreferenceController.java
@@ -28,6 +28,7 @@ import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.core.TogglePreferenceController;
import com.android.settings.overlay.FeatureFactory;
@@ -118,6 +119,11 @@ public class VisiblePatternProfilePreferenceController extends TogglePreferenceC
mPreference = screen.findPreference(getPreferenceKey());
}
+ @Override
+ public int getSliceHighlightMenuRes() {
+ return R.string.menu_key_security;
+ }
+
@Override
public void onResume() {
mPreference.setVisible(isAvailable());
diff --git a/src/com/android/settings/sim/SimSelectNotification.java b/src/com/android/settings/sim/SimSelectNotification.java
index 7dab4c0557a..84b75231b98 100644
--- a/src/com/android/settings/sim/SimSelectNotification.java
+++ b/src/com/android/settings/sim/SimSelectNotification.java
@@ -52,6 +52,7 @@ import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.HelpTrampoline;
import com.android.settings.R;
+import com.android.settings.network.MobileNetworkTwoPaneUtils;
import com.android.settings.network.SubscriptionUtil;
import com.android.settings.network.telephony.MobileNetworkActivity;
@@ -263,7 +264,9 @@ public class SimSelectNotification extends BroadcastReceiver {
Intent resultIntent = new Intent(Settings.ACTION_MMS_MESSAGE_SETTING);
resultIntent.setClass(context, MobileNetworkActivity.class);
resultIntent.putExtra(Settings.EXTRA_SUB_ID, subId);
- resultIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ // MobileNetworkActivity is singleTask, set SplitPairRule to show in 2-pane.
+ MobileNetworkTwoPaneUtils.registerTwoPaneForMobileNetwork(context, resultIntent,
+ Settings.ACTION_MMS_MESSAGE_SETTING);
PendingIntent resultPendingIntent = PendingIntent.getActivity(context, 0, resultIntent,
PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
builder.setContentIntent(resultPendingIntent);
diff --git a/src/com/android/settings/slices/CustomSliceable.java b/src/com/android/settings/slices/CustomSliceable.java
index d06ad1e89f0..2c807c4ef91 100644
--- a/src/com/android/settings/slices/CustomSliceable.java
+++ b/src/com/android/settings/slices/CustomSliceable.java
@@ -103,6 +103,9 @@ public interface CustomSliceable extends Sliceable {
return true;
}
+ @Override
+ int getSliceHighlightMenuRes();
+
/**
* Build an instance of a {@link CustomSliceable} which has a {@link Context}-only constructor.
*/
diff --git a/src/com/android/settings/slices/SliceBuilderUtils.java b/src/com/android/settings/slices/SliceBuilderUtils.java
index 402e044230d..4cefa4e430a 100644
--- a/src/com/android/settings/slices/SliceBuilderUtils.java
+++ b/src/com/android/settings/slices/SliceBuilderUtils.java
@@ -16,6 +16,9 @@
package com.android.settings.slices;
+import static android.provider.Settings.EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_HIGHLIGHT_MENU_KEY;
+
+import static com.android.settings.SettingsActivity.EXTRA_IS_FROM_SLICE;
import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING;
import static com.android.settings.slices.SettingsSliceProvider.EXTRA_SLICE_KEY;
@@ -202,8 +205,15 @@ public class SliceBuilderUtils {
}
public static Intent buildSearchResultPageIntent(Context context, String className, String key,
- String screenTitle, int sourceMetricsCategory) {
+ String screenTitle, int sourceMetricsCategory, int highlightMenuRes) {
final Bundle args = new Bundle();
+ String highlightMenuKey = null;
+ if (highlightMenuRes != 0) {
+ highlightMenuKey = context.getString(highlightMenuRes);
+ if (TextUtils.isEmpty(highlightMenuKey)) {
+ Log.w(TAG, "Invalid menu key res from: " + screenTitle);
+ }
+ }
args.putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, key);
final Intent searchDestination = new SubSettingLauncher(context)
.setDestination(className)
@@ -211,7 +221,10 @@ public class SliceBuilderUtils {
.setTitleText(screenTitle)
.setSourceMetricsCategory(sourceMetricsCategory)
.toIntent();
- searchDestination.putExtra(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, key)
+ searchDestination
+ .putExtra(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, key)
+ .putExtra(EXTRA_IS_FROM_SLICE, true)
+ .putExtra(EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_HIGHLIGHT_MENU_KEY, highlightMenuKey)
.setAction("com.android.settings.SEARCH_RESULT_TRAMPOLINE")
.setComponent(null);
searchDestination.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
@@ -219,13 +232,22 @@ public class SliceBuilderUtils {
return searchDestination;
}
+ /**
+ * Build a search result page intent for {@link CustomSliceable}
+ */
+ public static Intent buildSearchResultPageIntent(Context context, String className, String key,
+ String screenTitle, int sourceMetricsCategory, CustomSliceable sliceable) {
+ return buildSearchResultPageIntent(context, className, key, screenTitle,
+ sourceMetricsCategory, sliceable.getSliceHighlightMenuRes());
+ }
+
public static Intent getContentIntent(Context context, SliceData sliceData) {
final Uri contentUri = new Uri.Builder().appendPath(sliceData.getKey()).build();
final String screenTitle = TextUtils.isEmpty(sliceData.getScreenTitle()) ? null
: sliceData.getScreenTitle().toString();
final Intent intent = buildSearchResultPageIntent(context,
sliceData.getFragmentClassName(), sliceData.getKey(),
- screenTitle, 0 /* TODO */);
+ screenTitle, 0 /* TODO */, sliceData.getHighlightMenuRes());
intent.setClassName(context.getPackageName(), SubSettings.class.getName());
intent.setData(contentUri);
return intent;
diff --git a/src/com/android/settings/slices/SliceData.java b/src/com/android/settings/slices/SliceData.java
index 60f5e3fb840..01b29b23ce5 100644
--- a/src/com/android/settings/slices/SliceData.java
+++ b/src/com/android/settings/slices/SliceData.java
@@ -19,6 +19,7 @@ package com.android.settings.slices;
import android.annotation.IntDef;
import android.net.Uri;
import android.text.TextUtils;
+import android.util.Log;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -50,6 +51,8 @@ public class SliceData {
int SLIDER = 2;
}
+ private static final String TAG = "SliceData";
+
private final String mKey;
private final String mTitle;
@@ -68,6 +71,8 @@ public class SliceData {
private final String mPreferenceController;
+ private final int mHighlightMenuRes;
+
@SliceType
private final int mSliceType;
@@ -119,6 +124,10 @@ public class SliceData {
return mUnavailableSliceSubtitle;
}
+ public int getHighlightMenuRes() {
+ return mHighlightMenuRes;
+ }
+
public boolean isPublicSlice() {
return mIsPublicSlice;
}
@@ -136,6 +145,7 @@ public class SliceData {
mSliceType = builder.mSliceType;
mUnavailableSliceSubtitle = builder.mUnavailableSliceSubtitle;
mIsPublicSlice = builder.mIsPublicSlice;
+ mHighlightMenuRes = builder.mHighlightMenuRes;
}
@Override
@@ -175,6 +185,8 @@ public class SliceData {
private String mUnavailableSliceSubtitle;
+ private int mHighlightMenuRes;
+
private boolean mIsPublicSlice;
public Builder setKey(String key) {
@@ -233,6 +245,11 @@ public class SliceData {
return this;
}
+ public Builder setHighlightMenuRes(int highlightMenuRes) {
+ mHighlightMenuRes = highlightMenuRes;
+ return this;
+ }
+
public Builder setIsPublicSlice(boolean isPublicSlice) {
mIsPublicSlice = isPublicSlice;
return this;
@@ -255,6 +272,10 @@ public class SliceData {
throw new InvalidSliceDataException("Preference Controller cannot be empty");
}
+ if (mHighlightMenuRes == 0) {
+ Log.w(TAG, "Highlight menu key res is empty: " + mPrefControllerClassName);
+ }
+
return new SliceData(this);
}
diff --git a/src/com/android/settings/slices/SliceDataConverter.java b/src/com/android/settings/slices/SliceDataConverter.java
index 5608169a4db..eb08c5f978a 100644
--- a/src/com/android/settings/slices/SliceDataConverter.java
+++ b/src/com/android/settings/slices/SliceDataConverter.java
@@ -213,6 +213,7 @@ class SliceDataConverter {
final String unavailableSliceSubtitle = bundle.getString(
METADATA_UNAVAILABLE_SLICE_SUBTITLE);
final boolean isPublicSlice = controller.isPublicSlice();
+ final int highlightMenuRes = controller.getSliceHighlightMenuRes();
final SliceData xmlSlice = new SliceData.Builder()
.setKey(key)
@@ -226,6 +227,7 @@ class SliceDataConverter {
.setSliceType(sliceType)
.setUnavailableSliceSubtitle(unavailableSliceSubtitle)
.setIsPublicSlice(isPublicSlice)
+ .setHighlightMenuRes(highlightMenuRes)
.build();
xmlSliceData.add(xmlSlice);
diff --git a/src/com/android/settings/slices/Sliceable.java b/src/com/android/settings/slices/Sliceable.java
index ad27b7c0496..406cb3aeb73 100644
--- a/src/com/android/settings/slices/Sliceable.java
+++ b/src/com/android/settings/slices/Sliceable.java
@@ -25,6 +25,7 @@ import android.content.IntentFilter;
import android.net.Uri;
import android.widget.Toast;
+import androidx.annotation.StringRes;
import androidx.slice.Slice;
import com.android.settings.R;
@@ -50,6 +51,8 @@ public interface Sliceable {
* - Must be understandable as a stand-alone Setting.
*
* This does not guarantee the setting is available.
+ *
+ * {@link #getSliceHighlightMenuRes} should also be overridden when returning true.
*
* @return {@code true} if the controller should be used as a Slice.
*/
@@ -131,4 +134,18 @@ public interface Sliceable {
default Class extends SliceBackgroundWorker> getBackgroundWorkerClass() {
return null;
}
+
+ /**
+ * Used to mark a {@link Sliceable} that has no highlight menu string resource.
+ */
+ int NO_RES = 0;
+
+ /**
+ * @return a string resource declared in res/values/menu_keys.xml that indicates which menu
+ * entry should be highlighted in two-pane mode, or {@link #NO_RES} representing highlighting is
+ * not applicable.
+ */
+ @StringRes default int getSliceHighlightMenuRes() {
+ return NO_RES;
+ }
}
diff --git a/src/com/android/settings/slices/SlicesDatabaseAccessor.java b/src/com/android/settings/slices/SlicesDatabaseAccessor.java
index c0bb8de63da..75f0220f7ba 100644
--- a/src/com/android/settings/slices/SlicesDatabaseAccessor.java
+++ b/src/com/android/settings/slices/SlicesDatabaseAccessor.java
@@ -50,6 +50,7 @@ public class SlicesDatabaseAccessor {
IndexColumns.CONTROLLER,
IndexColumns.SLICE_TYPE,
IndexColumns.UNAVAILABLE_SLICE_SUBTITLE,
+ IndexColumns.HIGHLIGHT_MENU_RESOURCE,
};
private final Context mContext;
@@ -163,6 +164,8 @@ public class SlicesDatabaseAccessor {
cursor.getColumnIndex(IndexColumns.SLICE_TYPE));
final String unavailableSliceSubtitle = cursor.getString(
cursor.getColumnIndex(IndexColumns.UNAVAILABLE_SLICE_SUBTITLE));
+ final int highlightMenuRes = cursor.getInt(
+ cursor.getColumnIndex(IndexColumns.HIGHLIGHT_MENU_RESOURCE));
if (isIntentOnly) {
sliceType = SliceData.SliceType.INTENT;
@@ -180,6 +183,7 @@ public class SlicesDatabaseAccessor {
.setUri(uri)
.setSliceType(sliceType)
.setUnavailableSliceSubtitle(unavailableSliceSubtitle)
+ .setHighlightMenuRes(highlightMenuRes)
.build();
}
diff --git a/src/com/android/settings/slices/SlicesDatabaseHelper.java b/src/com/android/settings/slices/SlicesDatabaseHelper.java
index fe4420b26b0..69ad702913c 100644
--- a/src/com/android/settings/slices/SlicesDatabaseHelper.java
+++ b/src/com/android/settings/slices/SlicesDatabaseHelper.java
@@ -36,7 +36,7 @@ public class SlicesDatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "slices_index.db";
private static final String SHARED_PREFS_TAG = "slices_shared_prefs";
- private static final int DATABASE_VERSION = 8;
+ private static final int DATABASE_VERSION = 9;
public interface Tables {
String TABLE_SLICES_INDEX = "slices_index";
@@ -103,39 +103,43 @@ public class SlicesDatabaseHelper extends SQLiteOpenHelper {
* Whether the slice should be exposed publicly.
*/
String PUBLIC_SLICE = "public_slice";
+
+ /**
+ * Resource ID for the menu entry of the setting.
+ */
+ String HIGHLIGHT_MENU_RESOURCE = "highlight_menu";
}
private static final String CREATE_SLICES_TABLE =
- "CREATE VIRTUAL TABLE " + Tables.TABLE_SLICES_INDEX + " USING fts4" +
- "(" +
- IndexColumns.KEY +
- ", " +
- IndexColumns.SLICE_URI +
- ", " +
- IndexColumns.TITLE +
- ", " +
- IndexColumns.SUMMARY +
- ", " +
- IndexColumns.SCREENTITLE +
- ", " +
- IndexColumns.KEYWORDS +
- ", " +
- IndexColumns.ICON_RESOURCE +
- ", " +
- IndexColumns.FRAGMENT +
- ", " +
- IndexColumns.CONTROLLER +
- ", " +
- IndexColumns.SLICE_TYPE +
- ", " +
- IndexColumns.UNAVAILABLE_SLICE_SUBTITLE +
- ", "
- +
- IndexColumns.PUBLIC_SLICE
- +
- " INTEGER DEFAULT 0 "
- +
- ");";
+ "CREATE VIRTUAL TABLE " + Tables.TABLE_SLICES_INDEX + " USING fts4"
+ + "("
+ + IndexColumns.KEY
+ + ", "
+ + IndexColumns.SLICE_URI
+ + ", "
+ + IndexColumns.TITLE
+ + ", "
+ + IndexColumns.SUMMARY
+ + ", "
+ + IndexColumns.SCREENTITLE
+ + ", "
+ + IndexColumns.KEYWORDS
+ + ", "
+ + IndexColumns.ICON_RESOURCE
+ + ", "
+ + IndexColumns.FRAGMENT
+ + ", "
+ + IndexColumns.CONTROLLER
+ + ", "
+ + IndexColumns.SLICE_TYPE
+ + ", "
+ + IndexColumns.UNAVAILABLE_SLICE_SUBTITLE
+ + ", "
+ + IndexColumns.PUBLIC_SLICE
+ + ", "
+ + IndexColumns.HIGHLIGHT_MENU_RESOURCE
+ + " INTEGER DEFAULT 0 "
+ + ");";
private final Context mContext;
diff --git a/src/com/android/settings/slices/SlicesIndexer.java b/src/com/android/settings/slices/SlicesIndexer.java
index e527fd657ab..ac30c6c0a41 100644
--- a/src/com/android/settings/slices/SlicesIndexer.java
+++ b/src/com/android/settings/slices/SlicesIndexer.java
@@ -116,6 +116,7 @@ class SlicesIndexer implements Runnable {
values.put(IndexColumns.UNAVAILABLE_SLICE_SUBTITLE,
dataRow.getUnavailableSliceSubtitle());
values.put(IndexColumns.PUBLIC_SLICE, dataRow.isPublicSlice());
+ values.put(IndexColumns.HIGHLIGHT_MENU_RESOURCE, dataRow.getHighlightMenuRes());
database.replaceOrThrow(Tables.TABLE_SLICES_INDEX, null /* nullColumnHack */,
values);
diff --git a/src/com/android/settings/sound/MediaControlsPreferenceController.java b/src/com/android/settings/sound/MediaControlsPreferenceController.java
index ad09e2a6bee..e180b34fe34 100644
--- a/src/com/android/settings/sound/MediaControlsPreferenceController.java
+++ b/src/com/android/settings/sound/MediaControlsPreferenceController.java
@@ -23,6 +23,7 @@ import android.provider.Settings;
import androidx.annotation.VisibleForTesting;
+import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
/**
@@ -50,4 +51,9 @@ public class MediaControlsPreferenceController extends TogglePreferenceControlle
public int getAvailabilityStatus() {
return AVAILABLE;
}
+
+ @Override
+ public int getSliceHighlightMenuRes() {
+ return R.string.menu_key_sound;
+ }
}
diff --git a/src/com/android/settings/sound/MediaControlsRecommendationController.java b/src/com/android/settings/sound/MediaControlsRecommendationController.java
index 682cb5bc1e6..842a1417a15 100644
--- a/src/com/android/settings/sound/MediaControlsRecommendationController.java
+++ b/src/com/android/settings/sound/MediaControlsRecommendationController.java
@@ -21,6 +21,7 @@ import static android.provider.Settings.Secure.MEDIA_CONTROLS_RECOMMENDATION;
import android.content.Context;
import android.provider.Settings;
+import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
/**
@@ -50,4 +51,9 @@ public class MediaControlsRecommendationController extends TogglePreferenceContr
public int getAvailabilityStatus() {
return AVAILABLE;
}
+
+ @Override
+ public int getSliceHighlightMenuRes() {
+ return R.string.menu_key_sound;
+ }
}
diff --git a/src/com/android/settings/users/AddUserWhenLockedPreferenceController.java b/src/com/android/settings/users/AddUserWhenLockedPreferenceController.java
index f931fa4f662..ce5533e5c64 100644
--- a/src/com/android/settings/users/AddUserWhenLockedPreferenceController.java
+++ b/src/com/android/settings/users/AddUserWhenLockedPreferenceController.java
@@ -20,6 +20,7 @@ import android.provider.Settings;
import androidx.preference.Preference;
+import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
import com.android.settingslib.RestrictedSwitchPreference;
@@ -69,4 +70,9 @@ public class AddUserWhenLockedPreferenceController extends TogglePreferenceContr
return Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.ADD_USERS_WHEN_LOCKED, isChecked ? 1 : 0);
}
+
+ @Override
+ public int getSliceHighlightMenuRes() {
+ return R.string.menu_key_system;
+ }
}
diff --git a/src/com/android/settings/users/AppRestrictionsFragment.java b/src/com/android/settings/users/AppRestrictionsFragment.java
index a23aeefb1dc..c67a687d180 100644
--- a/src/com/android/settings/users/AppRestrictionsFragment.java
+++ b/src/com/android/settings/users/AppRestrictionsFragment.java
@@ -18,6 +18,7 @@ package com.android.settings.users;
import android.app.Activity;
import android.app.settings.SettingsEnums;
+import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -37,6 +38,7 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManager;
+import android.util.EventLog;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
@@ -641,7 +643,15 @@ public class AppRestrictionsFragment extends SettingsPreferenceFragment implemen
} else if (restrictionsIntent != null) {
preference.setRestrictions(restrictions);
if (invokeIfCustom && AppRestrictionsFragment.this.isResumed()) {
- assertSafeToStartCustomActivity(restrictionsIntent);
+ try {
+ assertSafeToStartCustomActivity(restrictionsIntent);
+ } catch (ActivityNotFoundException | SecurityException e) {
+ // return without startActivity
+ Log.e(TAG, "Cannot start restrictionsIntent " + e);
+ EventLog.writeEvent(0x534e4554, "200688991", -1 /* UID */, "");
+ return;
+ }
+
int requestCode = generateCustomActivityRequestCode(
RestrictionsResultReceiver.this.preference);
AppRestrictionsFragment.this.startActivityForResult(
@@ -655,14 +665,14 @@ public class AppRestrictionsFragment extends SettingsPreferenceFragment implemen
if (intent.getPackage() != null && intent.getPackage().equals(packageName)) {
return;
}
- // Activity can be started if intent resolves to multiple activities
- List resolveInfos = AppRestrictionsFragment.this.mPackageManager
- .queryIntentActivities(intent, 0 /* no flags */);
- if (resolveInfos.size() != 1) {
- return;
+ ResolveInfo resolveInfo = mPackageManager.resolveActivity(
+ intent, PackageManager.MATCH_DEFAULT_ONLY);
+
+ if (resolveInfo == null) {
+ throw new ActivityNotFoundException("No result for resolving " + intent);
}
// Prevent potential privilege escalation
- ActivityInfo activityInfo = resolveInfos.get(0).activityInfo;
+ ActivityInfo activityInfo = resolveInfo.activityInfo;
if (!packageName.equals(activityInfo.packageName)) {
throw new SecurityException("Application " + packageName
+ " is not allowed to start activity " + intent);
diff --git a/src/com/android/settings/uwb/UwbPreferenceController.java b/src/com/android/settings/uwb/UwbPreferenceController.java
index 877c9f2f2b4..ad040ed6043 100644
--- a/src/com/android/settings/uwb/UwbPreferenceController.java
+++ b/src/com/android/settings/uwb/UwbPreferenceController.java
@@ -24,6 +24,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
+import android.os.Handler;
import android.provider.Settings;
import android.uwb.UwbManager;
import android.uwb.UwbManager.AdapterStateCallback;
@@ -52,11 +53,13 @@ public class UwbPreferenceController extends TogglePreferenceController implemen
@VisibleForTesting
private final BroadcastReceiver mAirplaneModeChangedReceiver;
private final Executor mExecutor;
+ private final Handler mHandler;
private Preference mPreference;
public UwbPreferenceController(Context context, String key) {
super(context, key);
mExecutor = Executors.newSingleThreadExecutor();
+ mHandler = new Handler(context.getMainLooper());
if (isUwbSupportedOnDevice()) {
mUwbManager = context.getSystemService(UwbManager.class);
}
@@ -65,6 +68,8 @@ public class UwbPreferenceController extends TogglePreferenceController implemen
mAirplaneModeChangedReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
+ mAirplaneModeOn = Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.AIRPLANE_MODE_ON, 0) == 1;
updateState(mPreference);
}
};
@@ -114,6 +119,8 @@ public class UwbPreferenceController extends TogglePreferenceController implemen
@Override
public void onStateChanged(int state, int reason) {
+ Runnable runnable = () -> updateState(mPreference);
+ mHandler.post(runnable);
}
/** Called when activity starts being displayed to user. */
@@ -155,5 +162,10 @@ public class UwbPreferenceController extends TogglePreferenceController implemen
return mContext.getResources().getString(R.string.uwb_settings_summary);
}
}
+
+ @Override
+ public int getSliceHighlightMenuRes() {
+ return R.string.menu_key_connected_devices;
+ }
}
diff --git a/src/com/android/settings/vpn2/AppManagementFragment.java b/src/com/android/settings/vpn2/AppManagementFragment.java
index 0543fee7dbe..d4ee5b9c476 100644
--- a/src/com/android/settings/vpn2/AppManagementFragment.java
+++ b/src/com/android/settings/vpn2/AppManagementFragment.java
@@ -34,11 +34,13 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.text.TextUtils;
import android.util.Log;
+import android.widget.TextView;
import androidx.annotation.VisibleForTesting;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
import androidx.preference.Preference;
+import androidx.preference.PreferenceViewHolder;
import com.android.internal.net.VpnConfig;
import com.android.internal.util.ArrayUtils;
@@ -77,7 +79,6 @@ public class AppManagementFragment extends SettingsPreferenceFragment
private String mVpnLabel;
// UI preference
- private Preference mPreferenceVersion;
private RestrictedSwitchPreference mPreferenceAlwaysOn;
private RestrictedSwitchPreference mPreferenceLockdown;
private RestrictedPreference mPreferenceForget;
@@ -122,7 +123,6 @@ public class AppManagementFragment extends SettingsPreferenceFragment
mDevicePolicyManager = getContext().getSystemService(DevicePolicyManager.class);
mVpnManager = getContext().getSystemService(VpnManager.class);
- mPreferenceVersion = findPreference(KEY_VERSION);
mPreferenceAlwaysOn = (RestrictedSwitchPreference) findPreference(KEY_ALWAYS_ON_VPN);
mPreferenceLockdown = (RestrictedSwitchPreference) findPreference(KEY_LOCKDOWN_VPN);
mPreferenceForget = (RestrictedPreference) findPreference(KEY_FORGET_VPN);
@@ -138,9 +138,52 @@ public class AppManagementFragment extends SettingsPreferenceFragment
boolean isInfoLoaded = loadInfo();
if (isInfoLoaded) {
- mPreferenceVersion.setTitle(
- getPrefContext().getString(R.string.vpn_version, mPackageInfo.versionName));
updateUI();
+
+ Preference version = getPreferenceScreen().findPreference(KEY_VERSION);
+ if (version != null) {
+ // Version field has been added.
+ return;
+ }
+
+ /**
+ * Create version field at runtime, and set max height on the display area.
+ *
+ * When long length of text given within version field, a large text area
+ * might be created and inconvenient to the user (User need to scroll
+ * for a long time in order to get to the Preferences after this field.)
+ */
+ version = new Preference(getPrefContext()) {
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ super.onBindViewHolder(holder);
+
+ TextView titleView =
+ (TextView) holder.findViewById(android.R.id.title);
+ if (titleView != null) {
+ titleView.setTextAppearance(R.style.vpn_app_management_version_title);
+ }
+
+ TextView summaryView =
+ (TextView) holder.findViewById(android.R.id.summary);
+ if (summaryView != null) {
+ summaryView.setTextAppearance(R.style.vpn_app_management_version_summary);
+
+ // Set max height in summary area.
+ int versionMaxHeight = getListView().getHeight();
+ summaryView.setMaxHeight(versionMaxHeight);
+ summaryView.setVerticalScrollBarEnabled(false);
+ summaryView.setHorizontallyScrolling(false);
+ }
+ }
+ };
+ version.setOrder(0); // Set order to 0 in order to be placed
+ // in front of other Preference(s).
+ version.setKey(KEY_VERSION); // Set key to avoid from creating multi instance.
+ version.setTitle(R.string.vpn_version);
+ version.setSummary(mPackageInfo.versionName);
+ version.setSelectable(false);
+ getPreferenceScreen().addPreference(version);
} else {
finish();
}
diff --git a/src/com/android/settings/vpn2/ConfigDialog.java b/src/com/android/settings/vpn2/ConfigDialog.java
index cd6b4ff9604..bf0dfc9c5b8 100644
--- a/src/com/android/settings/vpn2/ConfigDialog.java
+++ b/src/com/android/settings/vpn2/ConfigDialog.java
@@ -41,7 +41,6 @@ import androidx.appcompat.app.AlertDialog;
import com.android.internal.net.VpnProfile;
import com.android.net.module.util.ProxyUtils;
import com.android.settings.R;
-import com.android.settings.Utils;
import com.android.settings.utils.AndroidKeystoreAliasLoader;
import java.net.InetAddress;
@@ -518,36 +517,31 @@ class ConfigDialog extends AlertDialog implements TextWatcher,
String[] types = getContext().getResources().getStringArray(R.array.vpn_types);
mTotalTypes = new ArrayList<>(Arrays.asList(types));
mAllowedTypes = new ArrayList<>(Arrays.asList(types));
+
+ // Although FEATURE_IPSEC_TUNNELS should always be present in android S and beyond,
+ // keep this check here just to be safe.
if (!getContext().getPackageManager().hasSystemFeature(
PackageManager.FEATURE_IPSEC_TUNNELS)) {
- final List typesList = new ArrayList<>(Arrays.asList(types));
+ Log.wtf(TAG, "FEATURE_IPSEC_TUNNELS missing from system");
+ }
+ // If the vpn is new or is not already a legacy type,
+ // don't allow the user to set the type to a legacy option.
- // This must be removed from back to front in order to ensure index consistency
- typesList.remove(VpnProfile.TYPE_IKEV2_IPSEC_RSA);
- typesList.remove(VpnProfile.TYPE_IKEV2_IPSEC_PSK);
- typesList.remove(VpnProfile.TYPE_IKEV2_IPSEC_USER_PASS);
+ // Set the mProfile.type to TYPE_IKEV2_IPSEC_USER_PASS if the VPN not exist
+ if (!mExists) {
+ mProfile.type = VpnProfile.TYPE_IKEV2_IPSEC_USER_PASS;
+ }
- types = typesList.toArray(new String[0]);
- } else if (Utils.isProviderModelEnabled(getContext())) {
- // If the provider mode is enabled and the vpn is new or is not already a legacy type,
- // don't allow the user to set the type to a legacy option.
-
- // Set the mProfile.type to TYPE_IKEV2_IPSEC_USER_PASS if the VPN not exist
- if (!mExists) {
- mProfile.type = VpnProfile.TYPE_IKEV2_IPSEC_USER_PASS;
- }
-
- // Remove all types which are legacy types from the typesList
- if (!VpnProfile.isLegacyType(mProfile.type)) {
- for (int i = mAllowedTypes.size() - 1; i >= 0; i--) {
- // This must be removed from back to front in order to ensure index consistency
- if (VpnProfile.isLegacyType(i)) {
- mAllowedTypes.remove(i);
- }
+ // Remove all types which are legacy types from the typesList
+ if (!VpnProfile.isLegacyType(mProfile.type)) {
+ for (int i = mAllowedTypes.size() - 1; i >= 0; i--) {
+ // This must be removed from back to front in order to ensure index consistency
+ if (VpnProfile.isLegacyType(i)) {
+ mAllowedTypes.remove(i);
}
-
- types = mAllowedTypes.toArray(new String[0]);
}
+
+ types = mAllowedTypes.toArray(new String[0]);
}
final ArrayAdapter adapter = new ArrayAdapter(
getContext(), android.R.layout.simple_spinner_item, types);
diff --git a/src/com/android/settings/vpn2/VpnSettings.java b/src/com/android/settings/vpn2/VpnSettings.java
index cf0e4fa2ca6..e89785fe535 100644
--- a/src/com/android/settings/vpn2/VpnSettings.java
+++ b/src/com/android/settings/vpn2/VpnSettings.java
@@ -59,7 +59,6 @@ import com.android.internal.net.VpnConfig;
import com.android.internal.net.VpnProfile;
import com.android.settings.R;
import com.android.settings.RestrictedSettingsFragment;
-import com.android.settings.Utils;
import com.android.settings.widget.GearPreference;
import com.android.settings.widget.GearPreference.OnGearClickListener;
import com.android.settingslib.RestrictedLockUtilsInternal;
@@ -130,12 +129,11 @@ public class VpnSettings extends RestrictedSettingsFragment implements
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
- // Although FEATURE_IPSEC_TUNNELS should always be present in android S,
+ // Although FEATURE_IPSEC_TUNNELS should always be present in android S and beyond,
// keep this check here just to be safe.
- if (Utils.isProviderModelEnabled(getContext())
- && !getContext().getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_IPSEC_TUNNELS)) {
- Log.w(LOG_TAG, "FEATURE_IPSEC_TUNNELS missing from system, cannot create new VPNs");
+ if (!getContext().getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_IPSEC_TUNNELS)) {
+ Log.wtf(LOG_TAG, "FEATURE_IPSEC_TUNNELS missing from system, cannot create new VPNs");
return;
} else {
// By default, we should inflate this menu.
diff --git a/src/com/android/settings/widget/HighlightablePreferenceGroupAdapter.java b/src/com/android/settings/widget/HighlightablePreferenceGroupAdapter.java
index 6e73382915e..9009b32be9e 100644
--- a/src/com/android/settings/widget/HighlightablePreferenceGroupAdapter.java
+++ b/src/com/android/settings/widget/HighlightablePreferenceGroupAdapter.java
@@ -105,7 +105,7 @@ public class HighlightablePreferenceGroupAdapter extends PreferenceGroupAdapter
context.getTheme().resolveAttribute(android.R.attr.selectableItemBackground,
outValue, true /* resolveRefs */);
mNormalBackgroundRes = outValue.resourceId;
- mHighlightColor = context.getColor(R.color.preference_highligh_color);
+ mHighlightColor = context.getColor(R.color.preference_highlight_color);
}
@Override
diff --git a/src/com/android/settings/widget/HighlightableTopLevelPreferenceAdapter.java b/src/com/android/settings/widget/HighlightableTopLevelPreferenceAdapter.java
new file mode 100644
index 00000000000..ff8f805b5e8
--- /dev/null
+++ b/src/com/android/settings/widget/HighlightableTopLevelPreferenceAdapter.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2021 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.widget;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.SparseArray;
+import android.util.TypedValue;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.PreferenceGroup;
+import androidx.preference.PreferenceGroupAdapter;
+import androidx.preference.PreferenceViewHolder;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.settings.R;
+import com.android.settings.Utils;
+import com.android.settings.activityembedding.ActivityEmbeddingUtils;
+import com.android.settings.homepage.SettingsHomepageActivity;
+
+/**
+ * Adapter for highlighting top level preferences
+ */
+public class HighlightableTopLevelPreferenceAdapter extends PreferenceGroupAdapter implements
+ SettingsHomepageActivity.HomepageLoadedListener {
+
+ private static final String TAG = "HighlightableTopLevelAdapter";
+
+ static final long DELAY_HIGHLIGHT_DURATION_MILLIS = 100L;
+
+ private final int mTitleColorNormal;
+ private final int mTitleColorHighlight;
+ private final int mSummaryColorNormal;
+ private final int mSummaryColorHighlight;
+ private final int mIconColorNormal;
+ private final int mIconColorHighlight;
+
+ private final Context mContext;
+ private final SettingsHomepageActivity mHomepageActivity;
+ private final RecyclerView mRecyclerView;
+ private final int mNormalBackgroundRes;
+ private final int mHighlightBackgroundRes;
+ private String mHighlightKey;
+ private int mHighlightPosition = RecyclerView.NO_POSITION;
+ private int mScrollPosition = RecyclerView.NO_POSITION;
+ private boolean mHighlightNeeded;
+ private boolean mScrolled;
+ private SparseArray mViewHolders;
+
+ public HighlightableTopLevelPreferenceAdapter(SettingsHomepageActivity homepageActivity,
+ PreferenceGroup preferenceGroup, RecyclerView recyclerView, String key) {
+ super(preferenceGroup);
+ mRecyclerView = recyclerView;
+ mHighlightKey = key;
+ mViewHolders = new SparseArray<>();
+ mContext = preferenceGroup.getContext();
+ mHomepageActivity = homepageActivity;
+ final TypedValue outValue = new TypedValue();
+ mContext.getTheme().resolveAttribute(android.R.attr.selectableItemBackground,
+ outValue, true /* resolveRefs */);
+ mNormalBackgroundRes = outValue.resourceId;
+ mHighlightBackgroundRes = R.drawable.homepage_highlighted_item_background;
+ mTitleColorNormal = Utils.getColorAttrDefaultColor(mContext,
+ android.R.attr.textColorPrimary);
+ mTitleColorHighlight = Utils.getColorAttrDefaultColor(mContext,
+ android.R.attr.textColorPrimaryInverse);
+ mSummaryColorNormal = Utils.getColorAttrDefaultColor(mContext,
+ android.R.attr.textColorSecondary);
+ mSummaryColorHighlight = Utils.getColorAttrDefaultColor(mContext,
+ android.R.attr.textColorSecondaryInverse);
+ mIconColorNormal = Utils.getHomepageIconColor(mContext);
+ mIconColorHighlight = Utils.getHomepageIconColorHighlight(mContext);
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder, int position) {
+ super.onBindViewHolder(holder, position);
+ mViewHolders.put(position, holder);
+ updateBackground(holder, position);
+ }
+
+ @VisibleForTesting
+ void updateBackground(PreferenceViewHolder holder, int position) {
+ if (!isHighlightNeeded()) {
+ removeHighlightBackground(holder);
+ return;
+ }
+
+ if (position == mHighlightPosition
+ && mHighlightKey != null
+ && TextUtils.equals(mHighlightKey, getItem(position).getKey())) {
+ // This position should be highlighted.
+ addHighlightBackground(holder);
+ } else {
+ removeHighlightBackground(holder);
+ }
+ }
+
+ /**
+ * A function can highlight a specific setting in recycler view.
+ */
+ public void requestHighlight() {
+ if (mRecyclerView == null) {
+ return;
+ }
+
+ final int previousPosition = mHighlightPosition;
+ if (TextUtils.isEmpty(mHighlightKey)) {
+ // De-highlight previous preference.
+ mHighlightPosition = RecyclerView.NO_POSITION;
+ mScrolled = true;
+ if (previousPosition >= 0) {
+ notifyItemChanged(previousPosition);
+ }
+ return;
+ }
+
+ final int position = getPreferenceAdapterPosition(mHighlightKey);
+ if (position < 0) {
+ return;
+ }
+
+ // Scroll before highlight if needed.
+ final boolean highlightNeeded = isHighlightNeeded();
+ if (highlightNeeded) {
+ mScrollPosition = position;
+ scroll();
+ }
+
+ // Turn on/off highlight when screen split mode is changed.
+ if (highlightNeeded != mHighlightNeeded) {
+ Log.d(TAG, "Highlight needed change: " + highlightNeeded);
+ mHighlightNeeded = highlightNeeded;
+ mHighlightPosition = position;
+ notifyItemChanged(position);
+ if (!highlightNeeded) {
+ // De-highlight to prevent a flicker
+ removeHighlightAt(previousPosition);
+ }
+ return;
+ }
+
+ if (position == mHighlightPosition) {
+ return;
+ }
+
+ mHighlightPosition = position;
+ Log.d(TAG, "Request highlight position " + position);
+ Log.d(TAG, "Is highlight needed: " + highlightNeeded);
+ if (!highlightNeeded) {
+ return;
+ }
+
+ // Highlight preference.
+ notifyItemChanged(position);
+
+ // De-highlight previous preference.
+ if (previousPosition >= 0) {
+ notifyItemChanged(previousPosition);
+ }
+ }
+
+ /**
+ * A function that highlights a setting by specifying a preference key. Usually used whenever a
+ * preference is clicked.
+ */
+ public void highlightPreference(String key, boolean scrollNeeded) {
+ mHighlightKey = key;
+ mScrolled = !scrollNeeded;
+ requestHighlight();
+ }
+
+ @Override
+ public void onHomepageLoaded() {
+ scroll();
+ }
+
+ private void scroll() {
+ if (mScrolled || mScrollPosition < 0) {
+ return;
+ }
+
+ if (mHomepageActivity.addHomepageLoadedListener(this)) {
+ return;
+ }
+
+ // Only when the recyclerView is loaded, it can be scrolled
+ final View view = mRecyclerView.getChildAt(mScrollPosition);
+ if (view == null) {
+ mRecyclerView.postDelayed(() -> scroll(), DELAY_HIGHLIGHT_DURATION_MILLIS);
+ return;
+ }
+
+ mScrolled = true;
+ Log.d(TAG, "Scroll to position " + mScrollPosition);
+ // Scroll to the top to reset the position.
+ mRecyclerView.nestedScrollBy(0, -mRecyclerView.getHeight());
+
+ final int scrollY = view.getTop();
+ if (scrollY > 0) {
+ mRecyclerView.nestedScrollBy(0, scrollY);
+ }
+ }
+
+ private void removeHighlightAt(int position) {
+ if (position >= 0) {
+ // De-highlight the existing preference view holder at an early stage
+ final PreferenceViewHolder holder = mViewHolders.get(position);
+ if (holder != null) {
+ removeHighlightBackground(holder);
+ }
+ notifyItemChanged(position);
+ }
+ }
+
+ private void addHighlightBackground(PreferenceViewHolder holder) {
+ final View v = holder.itemView;
+ v.setBackgroundResource(mHighlightBackgroundRes);
+ ((TextView) v.findViewById(android.R.id.title)).setTextColor(mTitleColorHighlight);
+ ((TextView) v.findViewById(android.R.id.summary)).setTextColor(mSummaryColorHighlight);
+ final Drawable drawable = ((ImageView) v.findViewById(android.R.id.icon)).getDrawable();
+ if (drawable != null) {
+ drawable.setTint(mIconColorHighlight);
+ }
+ }
+
+ private void removeHighlightBackground(PreferenceViewHolder holder) {
+ final View v = holder.itemView;
+ v.setBackgroundResource(mNormalBackgroundRes);
+ ((TextView) v.findViewById(android.R.id.title)).setTextColor(mTitleColorNormal);
+ ((TextView) v.findViewById(android.R.id.summary)).setTextColor(mSummaryColorNormal);
+ final Drawable drawable = ((ImageView) v.findViewById(android.R.id.icon)).getDrawable();
+ if (drawable != null) {
+ drawable.setTint(mIconColorNormal);
+ }
+ }
+
+ private boolean isHighlightNeeded() {
+ return ActivityEmbeddingUtils.isTwoPaneResolution(mHomepageActivity);
+ }
+}
diff --git a/src/com/android/settings/widget/HomepagePreference.java b/src/com/android/settings/widget/HomepagePreference.java
new file mode 100644
index 00000000000..ff4055ee226
--- /dev/null
+++ b/src/com/android/settings/widget/HomepagePreference.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2021 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.widget;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+import androidx.preference.Preference;
+
+import com.android.settings.R;
+
+/** A customized layout for homepage preference. */
+public class HomepagePreference extends Preference {
+ public HomepagePreference(Context context, AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ setLayoutResource(R.layout.homepage_preference);
+ }
+
+ public HomepagePreference(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ setLayoutResource(R.layout.homepage_preference);
+ }
+
+ public HomepagePreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setLayoutResource(R.layout.homepage_preference);
+ }
+
+ public HomepagePreference(Context context) {
+ super(context);
+ setLayoutResource(R.layout.homepage_preference);
+ }
+}
diff --git a/src/com/android/settings/widget/RestrictedHomepagePreference.java b/src/com/android/settings/widget/RestrictedHomepagePreference.java
new file mode 100644
index 00000000000..4667e2ce314
--- /dev/null
+++ b/src/com/android/settings/widget/RestrictedHomepagePreference.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2021 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.widget;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+import com.android.settings.R;
+import com.android.settingslib.RestrictedTopLevelPreference;
+
+/** Homepage preference that can be disabled by a device admin using a user restriction. */
+public class RestrictedHomepagePreference extends RestrictedTopLevelPreference {
+ public RestrictedHomepagePreference(Context context, AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ setLayoutResource(R.layout.homepage_preference);
+ }
+
+ public RestrictedHomepagePreference(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ setLayoutResource(R.layout.homepage_preference);
+ }
+
+ public RestrictedHomepagePreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setLayoutResource(R.layout.homepage_preference);
+ }
+
+ public RestrictedHomepagePreference(Context context) {
+ super(context);
+ setLayoutResource(R.layout.homepage_preference);
+ }
+}
diff --git a/src/com/android/settings/wifi/AddNetworkFragment.java b/src/com/android/settings/wifi/AddNetworkFragment.java
index 4adc6727614..01d5ef1ca4a 100644
--- a/src/com/android/settings/wifi/AddNetworkFragment.java
+++ b/src/com/android/settings/wifi/AddNetworkFragment.java
@@ -109,7 +109,8 @@ public class AddNetworkFragment extends InstrumentedFragment implements WifiConf
final String ssid = ssidEditText.getText().toString();
// Launch QR code scanner to join a network.
- startActivityForResult(WifiDppUtils.getEnrolleeQrCodeScannerIntent(ssid),
+ startActivityForResult(
+ WifiDppUtils.getEnrolleeQrCodeScannerIntent(view.getContext(), ssid),
REQUEST_CODE_WIFI_DPP_ENROLLEE_QR_CODE_SCANNER);
}
}
diff --git a/src/com/android/settings/wifi/AddWifiNetworkPreference.java b/src/com/android/settings/wifi/AddWifiNetworkPreference.java
index 8216f86ff64..ff4d38e6fde 100644
--- a/src/com/android/settings/wifi/AddWifiNetworkPreference.java
+++ b/src/com/android/settings/wifi/AddWifiNetworkPreference.java
@@ -59,7 +59,7 @@ public class AddWifiNetworkPreference extends Preference {
getContext().getString(R.string.wifi_dpp_scan_qr_code));
scanButton.setOnClickListener(view -> {
getContext().startActivity(
- WifiDppUtils.getEnrolleeQrCodeScannerIntent(/* ssid */ null));
+ WifiDppUtils.getEnrolleeQrCodeScannerIntent(getContext(), /* ssid */ null));
});
}
diff --git a/src/com/android/settings/wifi/CellularFallbackPreferenceController.java b/src/com/android/settings/wifi/CellularFallbackPreferenceController.java
index eab50a62e45..59ad44088ec 100644
--- a/src/com/android/settings/wifi/CellularFallbackPreferenceController.java
+++ b/src/com/android/settings/wifi/CellularFallbackPreferenceController.java
@@ -22,6 +22,7 @@ import android.provider.Settings;
import android.telephony.SubscriptionManager;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
/**
@@ -51,6 +52,11 @@ public class CellularFallbackPreferenceController extends TogglePreferenceContro
Settings.Global.NETWORK_AVOID_BAD_WIFI, isChecked ? "1" : null);
}
+ @Override
+ public int getSliceHighlightMenuRes() {
+ return R.string.menu_key_network;
+ }
+
private boolean avoidBadWifiConfig() {
final int activeDataSubscriptionId = getActiveDataSubscriptionId();
if (activeDataSubscriptionId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
diff --git a/src/com/android/settings/wifi/ConfigureWifiSettings.java b/src/com/android/settings/wifi/ConfigureWifiSettings.java
index 4ac2cfcd982..6bb4389bddb 100644
--- a/src/com/android/settings/wifi/ConfigureWifiSettings.java
+++ b/src/com/android/settings/wifi/ConfigureWifiSettings.java
@@ -18,11 +18,16 @@ package com.android.settings.wifi;
import static android.content.Context.WIFI_SERVICE;
import android.app.settings.SettingsEnums;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.util.FeatureFlagUtils;
+import android.util.Log;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
@@ -38,16 +43,37 @@ import java.util.List;
public class ConfigureWifiSettings extends DashboardFragment {
private static final String TAG = "ConfigureWifiSettings";
+ private static final String KEY_INSTALL_CREDENTIALS = "install_credentials";
+ private static final String ACTION_INSTALL_CERTS = "android.credentials.INSTALL";
+ private static final String PACKAGE_INSTALL_CERTS = "com.android.certinstaller";
+ private static final String CLASS_INSTALL_CERTS = "com.android.certinstaller.CertInstallerMain";
+ private static final String KEY_INSTALL_CERTIFICATE = "certificate_install_usage";
+ private static final String INSTALL_CERTIFICATE_VALUE = "wifi";
public static final int WIFI_WAKEUP_REQUEST_CODE = 600;
private WifiWakeupPreferenceController mWifiWakeupPreferenceController;
+ private Preference mCertinstallerPreference;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
- if (FeatureFlagUtils.isEnabled(getContext(), FeatureFlagUtils.SETTINGS_PROVIDER_MODEL)) {
- getActivity().setTitle(R.string.network_and_internet_preferences_title);
+ getActivity().setTitle(R.string.network_and_internet_preferences_title);
+
+ mCertinstallerPreference = findPreference(KEY_INSTALL_CREDENTIALS);
+ if (mCertinstallerPreference != null) {
+ mCertinstallerPreference.setOnPreferenceClickListener(preference -> {
+ Intent intent = new Intent(ACTION_INSTALL_CERTS);
+ intent.setFlags(
+ Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.setComponent(
+ new ComponentName(PACKAGE_INSTALL_CERTS, CLASS_INSTALL_CERTS));
+ intent.putExtra(KEY_INSTALL_CERTIFICATE, INSTALL_CERTIFICATE_VALUE);
+ getContext().startActivity(intent);
+ return true;
+ });
+ } else {
+ Log.d(TAG, "Can not find the preference.");
}
}
diff --git a/src/com/android/settings/wifi/NotifyOpenNetworksPreferenceController.java b/src/com/android/settings/wifi/NotifyOpenNetworksPreferenceController.java
index 6455f5b97cc..4b7506d4606 100644
--- a/src/com/android/settings/wifi/NotifyOpenNetworksPreferenceController.java
+++ b/src/com/android/settings/wifi/NotifyOpenNetworksPreferenceController.java
@@ -26,6 +26,7 @@ import android.provider.Settings;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
+import com.android.settings.R;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.core.TogglePreferenceController;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
@@ -85,6 +86,11 @@ public class NotifyOpenNetworksPreferenceController extends TogglePreferenceCont
return true;
}
+ @Override
+ public int getSliceHighlightMenuRes() {
+ return R.string.menu_key_network;
+ }
+
class SettingObserver extends ContentObserver {
private final Uri NETWORKS_AVAILABLE_URI = Settings.Global.getUriFor(
Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON);
diff --git a/src/com/android/settings/wifi/RequestToggleWiFiActivity.java b/src/com/android/settings/wifi/RequestToggleWiFiActivity.java
index 34ef7cf2705..6887b7802d0 100644
--- a/src/com/android/settings/wifi/RequestToggleWiFiActivity.java
+++ b/src/com/android/settings/wifi/RequestToggleWiFiActivity.java
@@ -19,6 +19,8 @@ package com.android.settings.wifi;
import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.IActivityManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
@@ -29,11 +31,13 @@ import android.content.pm.PackageItemInfo;
import android.content.pm.PackageManager;
import android.net.wifi.WifiManager;
import android.os.Bundle;
+import android.os.RemoteException;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.NonNull;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.AlertActivity;
import com.android.settings.R;
@@ -63,6 +67,8 @@ public class RequestToggleWiFiActivity extends AlertActivity
private @NonNull WifiManager mWiFiManager;
private @NonNull CharSequence mAppLabel;
+ @VisibleForTesting
+ protected IActivityManager mActivityManager = ActivityManager.getService();
private int mState = STATE_UNKNOWN;
private int mLastUpdateState = STATE_UNKNOWN;
@@ -75,20 +81,8 @@ public class RequestToggleWiFiActivity extends AlertActivity
setResult(Activity.RESULT_CANCELED);
- String packageName = getIntent().getStringExtra(Intent.EXTRA_PACKAGE_NAME);
- if (TextUtils.isEmpty(packageName)) {
- finish();
- return;
- }
-
- try {
- ApplicationInfo applicationInfo = getPackageManager().getApplicationInfo(
- packageName, 0);
- mAppLabel = applicationInfo.loadSafeLabel(getPackageManager(),
- PackageItemInfo.DEFAULT_MAX_LABEL_SIZE_PX, PackageItemInfo.SAFE_LABEL_FLAG_TRIM
- | PackageItemInfo.SAFE_LABEL_FLAG_FIRST_LINE);
- } catch (PackageManager.NameNotFoundException e) {
- Log.e(LOG_TAG, "Couldn't find app with package name " + packageName);
+ mAppLabel = getAppLabel();
+ if (TextUtils.isEmpty(mAppLabel)) {
finish();
return;
}
@@ -140,7 +134,6 @@ public class RequestToggleWiFiActivity extends AlertActivity
@Override
protected void onStart() {
super.onStart();
-
mReceiver.register();
final int wifiState = mWiFiManager.getWifiState();
@@ -223,6 +216,32 @@ public class RequestToggleWiFiActivity extends AlertActivity
super.onStop();
}
+ @VisibleForTesting
+ protected CharSequence getAppLabel() {
+ String packageName;
+ try {
+ packageName = mActivityManager.getLaunchedFromPackage(getActivityToken());
+ if (TextUtils.isEmpty(packageName)) {
+ Log.d(LOG_TAG, "Package name is null");
+ return null;
+ }
+ } catch (RemoteException e) {
+ Log.e(LOG_TAG, "Can not get the package from activity manager");
+ return null;
+ }
+
+ try {
+ ApplicationInfo applicationInfo = getPackageManager().getApplicationInfo(
+ packageName, 0);
+ return applicationInfo.loadSafeLabel(getPackageManager(),
+ PackageItemInfo.DEFAULT_MAX_LABEL_SIZE_PX, PackageItemInfo.SAFE_LABEL_FLAG_TRIM
+ | PackageItemInfo.SAFE_LABEL_FLAG_FIRST_LINE);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(LOG_TAG, "Couldn't find app with package name " + packageName);
+ return null;
+ }
+ }
+
private void updateUi() {
if (mLastUpdateState == mState) {
return;
diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java
index 408ffbe5a96..0c063db8a78 100644
--- a/src/com/android/settings/wifi/WifiConfigController.java
+++ b/src/com/android/settings/wifi/WifiConfigController.java
@@ -1503,11 +1503,15 @@ public class WifiConfigController implements TextWatcher,
}
// Shows display name of each active subscription.
- final String[] displayNames = SubscriptionUtil.getUniqueSubscriptionDisplayNames(
- mContext).values().stream().toArray(String[]::new);
- mEapSimSpinner.setAdapter(getSpinnerAdapter(displayNames));
+ final ArrayList displayNames = new ArrayList<>();
+ for (SubscriptionInfo activeSubInfo : mActiveSubscriptionInfos) {
+ displayNames.add(
+ SubscriptionUtil.getUniqueSubscriptionDisplayName(activeSubInfo, mContext));
+ }
+ mEapSimSpinner.setAdapter(
+ getSpinnerAdapter(displayNames.toArray(new String[displayNames.size()])));
mEapSimSpinner.setSelection(0 /* position */);
- if (displayNames.length == 1) {
+ if (displayNames.size() == 1) {
mEapSimSpinner.setEnabled(false);
}
}
diff --git a/src/com/android/settings/wifi/WifiConfigController2.java b/src/com/android/settings/wifi/WifiConfigController2.java
index 011c9709c00..127c882340c 100644
--- a/src/com/android/settings/wifi/WifiConfigController2.java
+++ b/src/com/android/settings/wifi/WifiConfigController2.java
@@ -1482,11 +1482,15 @@ public class WifiConfigController2 implements TextWatcher,
}
// Shows display name of each active subscription.
- final String[] displayNames = SubscriptionUtil.getUniqueSubscriptionDisplayNames(
- mContext).values().stream().toArray(String[]::new);
- mEapSimSpinner.setAdapter(getSpinnerAdapter(displayNames));
+ final ArrayList displayNames = new ArrayList<>();
+ for (SubscriptionInfo activeSubInfo : mActiveSubscriptionInfos) {
+ displayNames.add(
+ SubscriptionUtil.getUniqueSubscriptionDisplayName(activeSubInfo, mContext));
+ }
+ mEapSimSpinner.setAdapter(
+ getSpinnerAdapter(displayNames.toArray(new String[displayNames.size()])));
mEapSimSpinner.setSelection(0 /* position */);
- if (displayNames.length == 1) {
+ if (displayNames.size() == 1) {
mEapSimSpinner.setEnabled(false);
}
}
diff --git a/src/com/android/settings/wifi/WifiDialogActivity.java b/src/com/android/settings/wifi/WifiDialogActivity.java
index 877933edafe..58e9a7b5bb9 100644
--- a/src/com/android/settings/wifi/WifiDialogActivity.java
+++ b/src/com/android/settings/wifi/WifiDialogActivity.java
@@ -190,13 +190,11 @@ public class WifiDialogActivity extends ObservableActivity implements WifiDialog
public void onDestroy() {
if (mIsWifiTrackerLib) {
if (mDialog2 != null && mDialog2.isShowing()) {
- mDialog2.dismiss();
mDialog2 = null;
}
mWorkerThread.quit();
} else {
if (mDialog != null && mDialog.isShowing()) {
- mDialog.dismiss();
mDialog = null;
}
}
@@ -311,7 +309,7 @@ public class WifiDialogActivity extends ObservableActivity implements WifiDialog
@Override
public void onScan(WifiDialog2 dialog, String ssid) {
- Intent intent = WifiDppUtils.getEnrolleeQrCodeScannerIntent(ssid);
+ Intent intent = WifiDppUtils.getEnrolleeQrCodeScannerIntent(dialog.getContext(), ssid);
WizardManagerHelper.copyWizardManagerExtras(mIntent, intent);
// Launch QR code scanner to join a network.
@@ -320,7 +318,7 @@ public class WifiDialogActivity extends ObservableActivity implements WifiDialog
@Override
public void onScan(WifiDialog dialog, String ssid) {
- Intent intent = WifiDppUtils.getEnrolleeQrCodeScannerIntent(ssid);
+ Intent intent = WifiDppUtils.getEnrolleeQrCodeScannerIntent(dialog.getContext(), ssid);
WizardManagerHelper.copyWizardManagerExtras(mIntent, intent);
// Launch QR code scanner to join a network.
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index 0c3b1ae990f..f0ae90e100d 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -59,6 +59,7 @@ import com.android.settings.LinkifyUtils;
import com.android.settings.R;
import com.android.settings.RestrictedSettingsFragment;
import com.android.settings.SettingsActivity;
+import com.android.settings.Utils;
import com.android.settings.core.FeatureFlags;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.datausage.DataUsagePreference;
@@ -88,9 +89,10 @@ import java.util.Optional;
/**
* UI for Wi-Fi settings screen
*
- * TODO(b/167474581): This file will be deprecated at Android S, please merge your WifiSettings
+ * @deprecated This file will be deprecated at Android S, please merge your WifiSettings
* in change in {@link NetworkProviderSettings}.
*/
+@Deprecated
@SearchIndexable
public class WifiSettings extends RestrictedSettingsFragment
implements Indexable, WifiPickerTracker.WifiPickerTrackerCallback,
@@ -98,6 +100,10 @@ public class WifiSettings extends RestrictedSettingsFragment
private static final String TAG = "WifiSettings";
+ // Set the Provider Model is always enabled
+ @VisibleForTesting
+ static Boolean IS_ENABLED_PROVIDER_MODEL = true;
+
// IDs of context menu
static final int MENU_ID_CONNECT = Menu.FIRST + 1;
@VisibleForTesting
@@ -231,7 +237,7 @@ public class WifiSettings extends RestrictedSettingsFragment
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
- if (FeatureFlagUtils.isEnabled(getContext(), FeatureFlagUtils.SETTINGS_PROVIDER_MODEL)) {
+ if (IS_ENABLED_PROVIDER_MODEL) {
final Intent intent = new Intent("android.settings.NETWORK_PROVIDER_SETTINGS");
// Add FLAG_ACTIVITY_NEW_TASK and FLAG_ACTIVITY_CLEAR_TASK to avoid multiple
// instances issue. (e.g. b/191956700)
@@ -1028,7 +1034,8 @@ public class WifiSettings extends RestrictedSettingsFragment
@Override
public void onScan(WifiDialog2 dialog, String ssid) {
// Launch QR code scanner to join a network.
- startActivityForResult(WifiDppUtils.getEnrolleeQrCodeScannerIntent(ssid),
+ startActivityForResult(
+ WifiDppUtils.getEnrolleeQrCodeScannerIntent(dialog.getContext(), ssid),
REQUEST_CODE_WIFI_DPP_ENROLLEE_QR_CODE_SCANNER);
}
@@ -1066,6 +1073,11 @@ public class WifiSettings extends RestrictedSettingsFragment
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.wifi_settings) {
+ @Override
+ protected boolean isPageSearchEnabled(Context context) {
+ return !IS_ENABLED_PROVIDER_MODEL;
+ }
+
@Override
public List getNonIndexableKeys(Context context) {
final List keys = super.getNonIndexableKeys(context);
diff --git a/src/com/android/settings/wifi/WifiWakeupPreferenceController.java b/src/com/android/settings/wifi/WifiWakeupPreferenceController.java
index e9fd35004da..2cc7f8ef5d9 100644
--- a/src/com/android/settings/wifi/WifiWakeupPreferenceController.java
+++ b/src/com/android/settings/wifi/WifiWakeupPreferenceController.java
@@ -135,6 +135,11 @@ public class WifiWakeupPreferenceController extends TogglePreferenceController i
}
}
+ @Override
+ public int getSliceHighlightMenuRes() {
+ return R.string.menu_key_network;
+ }
+
@VisibleForTesting
CharSequence getNoLocationSummary() {
AnnotationSpan.LinkInfo linkInfo = new AnnotationSpan.LinkInfo("link", null);
diff --git a/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivity.java b/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivity.java
index 7b5eaa9ecb1..6bf91040443 100644
--- a/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivity.java
+++ b/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivity.java
@@ -16,9 +16,14 @@
package com.android.settings.wifi.addappnetworks;
+import android.app.ActivityManager;
+import android.app.IActivityManager;
import android.content.Intent;
import android.os.Bundle;
+import android.os.RemoteException;
import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.Log;
import android.view.Gravity;
import android.view.Window;
import android.view.WindowManager;
@@ -48,12 +53,17 @@ public class AddAppNetworksActivity extends FragmentActivity {
@VisibleForTesting
final Bundle mBundle = new Bundle();
+ @VisibleForTesting
+ IActivityManager mActivityManager = ActivityManager.getService();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.settings_panel);
- showAddNetworksFragment();
+ if (!showAddNetworksFragment()) {
+ finish();
+ return;
+ }
getLifecycle().addObserver(new HideNonSystemOverlayMixin(this));
// Move the window to the bottom of screen, and make it take up the entire screen width.
@@ -67,13 +77,22 @@ public class AddAppNetworksActivity extends FragmentActivity {
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
- showAddNetworksFragment();
+ if (!showAddNetworksFragment()) {
+ finish();
+ return;
+ }
}
@VisibleForTesting
- void showAddNetworksFragment() {
+ protected boolean showAddNetworksFragment() {
+ String packageName = getCallingAppPackageName();
+ if (TextUtils.isEmpty(packageName)) {
+ Log.d(TAG, "Package name is null");
+ return false;
+ }
+
// TODO: Check the new intent status.
- mBundle.putString(KEY_CALLING_PACKAGE_NAME, getCallingPackage());
+ mBundle.putString(KEY_CALLING_PACKAGE_NAME, packageName);
mBundle.putParcelableArrayList(Settings.EXTRA_WIFI_NETWORK_LIST,
getIntent().getParcelableArrayListExtra(Settings.EXTRA_WIFI_NETWORK_LIST));
@@ -86,5 +105,19 @@ public class AddAppNetworksActivity extends FragmentActivity {
} else {
((AddAppNetworksFragment) fragment).createContent(mBundle);
}
+
+ return true;
+ }
+
+ @VisibleForTesting
+ protected String getCallingAppPackageName() {
+ String packageName;
+ try {
+ packageName = mActivityManager.getLaunchedFromPackage(getActivityToken());
+ } catch (RemoteException e) {
+ Log.e(TAG, "Can not get the package from activity manager");
+ return null;
+ }
+ return packageName;
}
}
diff --git a/src/com/android/settings/wifi/calling/WifiCallingSliceHelper.java b/src/com/android/settings/wifi/calling/WifiCallingSliceHelper.java
index 36363419dfc..c73bffa7411 100644
--- a/src/com/android/settings/wifi/calling/WifiCallingSliceHelper.java
+++ b/src/com/android/settings/wifi/calling/WifiCallingSliceHelper.java
@@ -179,7 +179,8 @@ public class WifiCallingSliceHelper {
.setTitle(res.getText(R.string.wifi_calling_settings_title))
.addEndItem(
SliceAction.createToggle(
- getBroadcastIntent(ACTION_WIFI_CALLING_CHANGED),
+ getBroadcastIntent(ACTION_WIFI_CALLING_CHANGED,
+ isWifiCallingEnabled),
null /* actionTitle */, isWifiCallingEnabled))
.setPrimaryAction(SliceAction.createDeeplink(
getActivityIntent(ACTION_WIFI_CALLING_SETTINGS_ACTIVITY),
@@ -316,7 +317,7 @@ public class WifiCallingSliceHelper {
final Resources res = getResourcesForSubId(subId);
return new RowBuilder()
.setTitle(res.getText(preferenceTitleResId))
- .setTitleItem(SliceAction.createToggle(getBroadcastIntent(action),
+ .setTitleItem(SliceAction.createToggle(getBroadcastIntent(action, checked),
icon, res.getText(preferenceTitleResId), checked));
}
@@ -370,25 +371,31 @@ public class WifiCallingSliceHelper {
public void handleWifiCallingChanged(Intent intent) {
final int subId = getDefaultVoiceSubId();
- if (SubscriptionManager.isValidSubscriptionId(subId)) {
+ if (SubscriptionManager.isValidSubscriptionId(subId)
+ && intent.hasExtra(EXTRA_TOGGLE_STATE)) {
final WifiCallingQueryImsState queryState = queryImsState(subId);
if (queryState.isWifiCallingProvisioned()) {
- final boolean currentValue = queryState.isEnabledByUser()
- && queryState.isAllowUserControl();
+ final boolean currentValue = isWifiCallingEnabled();
final boolean newValue = intent.getBooleanExtra(EXTRA_TOGGLE_STATE,
currentValue);
final Intent activationAppIntent =
getWifiCallingCarrierActivityIntent(subId);
- if (!newValue || activationAppIntent == null) {
+ if ((newValue == currentValue) && activationAppIntent == null) {
// If either the action is to turn off wifi calling setting
// or there is no activation involved - Update the setting
- if (newValue != currentValue) {
- final ImsMmTelManager imsMmTelManager = getImsMmTelManager(subId);
- imsMmTelManager.setVoWiFiSettingEnabled(newValue);
- }
+ final ImsMmTelManager imsMmTelManager = getImsMmTelManager(subId);
+ imsMmTelManager.setVoWiFiSettingEnabled(!newValue);
+ } else {
+ Log.w(TAG, "action not taken: subId " + subId
+ + " from " + currentValue + " to " + newValue);
}
+ } else {
+ Log.w(TAG, "action not taken: subId " + subId + " needs provision");
}
+ } else {
+ Log.w(TAG, "action not taken: subId " + subId);
}
+
// notify change in slice in any case to get re-queried. This would result in displaying
// appropriate message with the updated setting.
mContext.getContentResolver().notifyChange(WIFI_CALLING_URI, null);
@@ -541,10 +548,20 @@ public class WifiCallingSliceHelper {
PendingIntent.FLAG_IMMUTABLE);
}
- private PendingIntent getBroadcastIntent(String action) {
+ /**
+ * Create PendingIntent for Slice.
+ * Note: SliceAction#createDeeplink() didn't support toggle status so far,
+ * therefore, embedding toggle status within PendingIntent.
+ *
+ * @param action Slice action
+ * @param isChecked Status when Slice created.
+ * @return PendingIntent
+ */
+ private PendingIntent getBroadcastIntent(String action, boolean isChecked) {
final Intent intent = new Intent(action);
intent.setClass(mContext, SliceBroadcastReceiver.class);
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ intent.putExtra(EXTRA_TOGGLE_STATE, isChecked);
return PendingIntent.getBroadcast(mContext, 0 /* requestCode */, intent,
PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
}
diff --git a/src/com/android/settings/wifi/details2/WifiAutoConnectPreferenceController2.java b/src/com/android/settings/wifi/details2/WifiAutoConnectPreferenceController2.java
index ffbb68289b5..8226bc07848 100644
--- a/src/com/android/settings/wifi/details2/WifiAutoConnectPreferenceController2.java
+++ b/src/com/android/settings/wifi/details2/WifiAutoConnectPreferenceController2.java
@@ -18,6 +18,7 @@ package com.android.settings.wifi.details2;
import android.content.Context;
+import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
import com.android.wifitrackerlib.WifiEntry;
@@ -54,4 +55,9 @@ public class WifiAutoConnectPreferenceController2 extends TogglePreferenceContro
mWifiEntry.setAutoJoinEnabled(isChecked);
return true;
}
+
+ @Override
+ public int getSliceHighlightMenuRes() {
+ return R.string.menu_key_network;
+ }
}
diff --git a/src/com/android/settings/wifi/dpp/WifiDppEnrolleeActivity.java b/src/com/android/settings/wifi/dpp/WifiDppEnrolleeActivity.java
index c5f1e81f80d..3ce244cea30 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppEnrolleeActivity.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppEnrolleeActivity.java
@@ -18,11 +18,14 @@ package com.android.settings.wifi.dpp;
import android.app.settings.SettingsEnums;
import android.content.Intent;
+import android.util.EventLog;
import android.util.Log;
+import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.FragmentTransaction;
import com.android.settings.R;
+import com.android.settingslib.wifi.WifiRestrictionsCache;
/**
* To provision "this" device with specified Wi-Fi network.
@@ -37,6 +40,9 @@ public class WifiDppEnrolleeActivity extends WifiDppBaseActivity implements
static final String ACTION_ENROLLEE_QR_CODE_SCANNER =
"android.settings.WIFI_DPP_ENROLLEE_QR_CODE_SCANNER";
+ @VisibleForTesting
+ protected WifiRestrictionsCache mWifiRestrictionsCache;
+
@Override
public int getMetricsCategory() {
return SettingsEnums.SETTINGS_WIFI_DPP_ENROLLEE;
@@ -50,6 +56,14 @@ public class WifiDppEnrolleeActivity extends WifiDppBaseActivity implements
return;
}
+ if (!isWifiConfigAllowed()) {
+ Log.e(TAG, "The user is not allowed to configure Wi-Fi.");
+ finish();
+ EventLog.writeEvent(0x534e4554, "202017876", getApplicationContext().getUserId(),
+ "The user is not allowed to configure Wi-Fi.");
+ return;
+ }
+
switch (action) {
case ACTION_ENROLLEE_QR_CODE_SCANNER:
String ssid = intent.getStringExtra(WifiDppUtils.EXTRA_WIFI_SSID);
@@ -61,7 +75,15 @@ public class WifiDppEnrolleeActivity extends WifiDppBaseActivity implements
}
}
- private void showQrCodeScannerFragment(String ssid) {
+ private boolean isWifiConfigAllowed() {
+ if (mWifiRestrictionsCache == null) {
+ mWifiRestrictionsCache = WifiRestrictionsCache.getInstance(getApplicationContext());
+ }
+ return mWifiRestrictionsCache.isConfigWifiAllowed();
+ }
+
+ @VisibleForTesting
+ protected void showQrCodeScannerFragment(String ssid) {
WifiDppQrCodeScannerFragment fragment =
(WifiDppQrCodeScannerFragment) mFragmentManager.findFragmentByTag(
WifiDppUtils.TAG_FRAGMENT_QR_CODE_SCANNER);
diff --git a/src/com/android/settings/wifi/dpp/WifiDppUtils.java b/src/com/android/settings/wifi/dpp/WifiDppUtils.java
index abf5becfbc3..39a5431e636 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppUtils.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppUtils.java
@@ -114,9 +114,9 @@ public class WifiDppUtils {
* @param ssid The data corresponding to {@code WifiConfiguration} SSID
* @return Intent for launching QR code scanner
*/
- public static Intent getEnrolleeQrCodeScannerIntent(String ssid) {
- final Intent intent = new Intent(
- WifiDppEnrolleeActivity.ACTION_ENROLLEE_QR_CODE_SCANNER);
+ public static Intent getEnrolleeQrCodeScannerIntent(Context context, String ssid) {
+ final Intent intent = new Intent(context, WifiDppEnrolleeActivity.class);
+ intent.setAction(WifiDppEnrolleeActivity.ACTION_ENROLLEE_QR_CODE_SCANNER);
if (!TextUtils.isEmpty(ssid)) {
intent.putExtra(EXTRA_WIFI_SSID, ssid);
}
diff --git a/src/com/android/settings/wifi/slice/WifiSlice.java b/src/com/android/settings/wifi/slice/WifiSlice.java
index f6604dd6f6e..743c7f9815a 100644
--- a/src/com/android/settings/wifi/slice/WifiSlice.java
+++ b/src/com/android/settings/wifi/slice/WifiSlice.java
@@ -44,6 +44,8 @@ import com.android.settings.R;
import com.android.settings.SubSettings;
import com.android.settings.Utils;
import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.network.NetworkProviderSettings;
+import com.android.settings.network.WifiSwitchPreferenceController;
import com.android.settings.slices.CustomSliceable;
import com.android.settings.slices.SliceBackgroundWorker;
import com.android.settings.slices.SliceBuilderUtils;
@@ -269,15 +271,22 @@ public class WifiSlice implements CustomSliceable {
public Intent getIntent() {
final String screenTitle = mContext.getText(R.string.wifi_settings).toString();
final Uri contentUri = new Uri.Builder().appendPath(KEY_WIFI).build();
- final Intent intent = SliceBuilderUtils.buildSearchResultPageIntent(mContext,
- WifiSettings.class.getName(), KEY_WIFI, screenTitle,
- SettingsEnums.DIALOG_WIFI_AP_EDIT)
+ final String className = NetworkProviderSettings.class.getName();
+ final String key = WifiSwitchPreferenceController.KEY;
+
+ final Intent intent = SliceBuilderUtils.buildSearchResultPageIntent(mContext, className,
+ key, screenTitle, SettingsEnums.DIALOG_WIFI_AP_EDIT, this)
.setClassName(mContext.getPackageName(), SubSettings.class.getName())
.setData(contentUri);
return intent;
}
+ @Override
+ public int getSliceHighlightMenuRes() {
+ return R.string.menu_key_network;
+ }
+
private boolean isWifiEnabled() {
switch (mWifiManager.getWifiState()) {
case WifiManager.WIFI_STATE_ENABLED:
diff --git a/src/com/android/settings/wifi/tether/WifiTetherSettings.java b/src/com/android/settings/wifi/tether/WifiTetherSettings.java
index 088356b904e..23601fac5d8 100644
--- a/src/com/android/settings/wifi/tether/WifiTetherSettings.java
+++ b/src/com/android/settings/wifi/tether/WifiTetherSettings.java
@@ -54,7 +54,6 @@ public class WifiTetherSettings extends RestrictedDashboardFragment
private static final String TAG = "WifiTetherSettings";
private static final IntentFilter TETHER_STATE_CHANGE_FILTER;
private static final String KEY_WIFI_TETHER_SCREEN = "wifi_tether_settings_screen";
- private static final int EXPANDED_CHILD_COUNT_DEFAULT = 3;
@VisibleForTesting
static final String KEY_WIFI_TETHER_NETWORK_NAME = "wifi_tether_network_name";
@@ -204,10 +203,6 @@ public class WifiTetherSettings extends RestrictedDashboardFragment
mSwitchBarController.stopTether();
}
mWifiManager.setSoftApConfiguration(config);
-
- if (context instanceof WifiTetherSecurityPreferenceController) {
- reConfigInitialExpandedChildCount();
- }
}
private SoftApConfiguration buildNewConfig() {
@@ -287,11 +282,4 @@ public class WifiTetherSettings extends RestrictedDashboardFragment
}
}
}
-
- private void reConfigInitialExpandedChildCount() {
- final PreferenceGroup screen = getPreferenceScreen();
- if (screen != null) {
- screen.setInitialExpandedChildrenCount(getInitialExpandedChildCount());
- }
- }
}
diff --git a/tests/robotests/Android.bp b/tests/robotests/Android.bp
index 9b2e97f48aa..bc25377ed7d 100644
--- a/tests/robotests/Android.bp
+++ b/tests/robotests/Android.bp
@@ -50,6 +50,7 @@ android_app {
"contextualcards",
"settings-logtags",
"zxing-core-1.7",
+ "windowExtLib",
],
aaptflags: ["--extra-packages com.android.settings"],
@@ -59,6 +60,10 @@ android_app {
"ims-common",
],
uses_libs: ["org.apache.http.legacy"],
+ optional_uses_libs: [
+ "androidx.window.extensions",
+ "androidx.window.sidecar",
+ ],
}
//############################################################
diff --git a/tests/robotests/res/xml-mcc999/location_settings.xml b/tests/robotests/res/xml-mcc999/location_settings.xml
index d2dc132be43..b2a67ab2f9e 100644
--- a/tests/robotests/res/xml-mcc999/location_settings.xml
+++ b/tests/robotests/res/xml-mcc999/location_settings.xml
@@ -24,6 +24,7 @@
android:title="title"
android:icon="@drawable/ic_android"
android:summary="summary"
+ settings:highlightableMenuKey="menu_key"
settings:controller="com.android.settings.slices.FakePreferenceController"
settings:keywords="a, b, c"
settings:unavailableSliceSubtitle="subtitleOfUnavailableSlice"/>
diff --git a/tests/robotests/src/com/android/settings/MainClearTest.java b/tests/robotests/src/com/android/settings/MainClearTest.java
index ec33fadfd02..e2a7ca904e8 100644
--- a/tests/robotests/src/com/android/settings/MainClearTest.java
+++ b/tests/robotests/src/com/android/settings/MainClearTest.java
@@ -55,6 +55,7 @@ import com.android.settingslib.development.DevelopmentSettingsEnabler;
import org.junit.After;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -208,6 +209,7 @@ public class MainClearTest {
}
@Test
+ @Ignore
public void testShowWipeEuicc_euiccEnabled_unprovisioned() {
prepareEuiccState(
true /* isEuiccEnabled */,
@@ -226,6 +228,7 @@ public class MainClearTest {
}
@Test
+ @Ignore
public void testShowWipeEuicc_developerMode_unprovisioned() {
prepareEuiccState(
true /* isEuiccEnabled */,
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonFooterPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonFooterPreferenceControllerTest.java
index 010b444f914..7354555a719 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonFooterPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonFooterPreferenceControllerTest.java
@@ -16,6 +16,7 @@
package com.android.settings.accessibility;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
import static com.google.common.truth.Truth.assertThat;
@@ -46,7 +47,6 @@ public class AccessibilityButtonFooterPreferenceControllerTest {
@Rule
public final MockitoRule mockito = MockitoJUnit.rule();
-
@Spy
private final Context mContext = ApplicationProvider.getApplicationContext();
@Spy
@@ -76,4 +76,15 @@ public class AccessibilityButtonFooterPreferenceControllerTest {
assertThat(mPreference.getTitle()).isEqualTo(
mContext.getText(R.string.accessibility_button_gesture_description));
}
+
+ @Test
+ public void displayPreference_navigationGestureDisabled_setCorrectTitle() {
+ when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
+ .thenReturn(NAV_BAR_MODE_2BUTTON);
+
+ mController.displayPreference(mScreen);
+
+ assertThat(mPreference.getTitle()).isEqualTo(
+ mContext.getText(R.string.accessibility_button_description));
+ }
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonGesturePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonGesturePreferenceControllerTest.java
new file mode 100644
index 00000000000..da442281e9e
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonGesturePreferenceControllerTest.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2021 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.accessibility;
+
+import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU;
+import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_GESTURE;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
+
+import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.res.Resources;
+import android.provider.Settings;
+
+import androidx.preference.ListPreference;
+import androidx.test.core.app.ApplicationProvider;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.robolectric.RobolectricTestRunner;
+
+/** Tests for {@link AccessibilityButtonGesturePreferenceController}. */
+@RunWith(RobolectricTestRunner.class)
+public class AccessibilityButtonGesturePreferenceControllerTest {
+
+ @Rule
+ public final MockitoRule mockito = MockitoJUnit.rule();
+
+ @Spy
+ private final Context mContext = ApplicationProvider.getApplicationContext();
+ @Spy
+ private final Resources mResources = mContext.getResources();
+ private final ContentResolver mContentResolver = mContext.getContentResolver();
+ private final ListPreference mListPreference = new ListPreference(mContext);
+ private AccessibilityButtonGesturePreferenceController mController;
+
+ @Before
+ public void setUp() {
+ mController = new AccessibilityButtonGesturePreferenceController(mContext,
+ "test_key");
+ when(mContext.getResources()).thenReturn(mResources);
+ }
+
+ @Test
+ public void getAvailabilityStatus_navigationGestureEnabled_returnAvailable() {
+ when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
+ .thenReturn(NAV_BAR_MODE_GESTURAL);
+
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+ }
+
+ @Test
+ public void getAvailabilityStatus_navigationGestureDisabled_returnConditionallyUnavailable() {
+ when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
+ .thenReturn(NAV_BAR_MODE_2BUTTON);
+
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
+ }
+
+ @Test
+ public void updateState_a11yBtnModeGesture_navigationBarValue() {
+ Settings.Secure.putInt(mContentResolver, Settings.Secure.ACCESSIBILITY_BUTTON_MODE,
+ ACCESSIBILITY_BUTTON_MODE_GESTURE);
+
+ mController.updateState(mListPreference);
+
+ final String gestureValue = String.valueOf(ACCESSIBILITY_BUTTON_MODE_GESTURE);
+ assertThat(mListPreference.getValue()).isEqualTo(gestureValue);
+ }
+
+ @Test
+ public void onPreferenceChange_a11yBtnModeFloatingMenu_floatingMenuValue() {
+ final String floatingMenuValue = String.valueOf(ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU);
+
+ mController.onPreferenceChange(mListPreference, floatingMenuValue);
+
+ assertThat(mListPreference.getValue()).isEqualTo(floatingMenuValue);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonPreferenceControllerTest.java
new file mode 100644
index 00000000000..03f7887b9d0
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonPreferenceControllerTest.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2021 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.accessibility;
+
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.res.Resources;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.R;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.robolectric.RobolectricTestRunner;
+
+/** Tests for {@link AccessibilityButtonPreferenceController}. */
+@RunWith(RobolectricTestRunner.class)
+public class AccessibilityButtonPreferenceControllerTest {
+
+ @Rule
+ public final MockitoRule mockito = MockitoJUnit.rule();
+ @Spy
+ private final Context mContext = ApplicationProvider.getApplicationContext();
+ @Spy
+ private final Resources mResources = mContext.getResources();
+ @Mock
+ private PreferenceScreen mScreen;
+ private Preference mPreference;
+ private AccessibilityButtonPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ mController = new AccessibilityButtonPreferenceController(mContext, "test_key");
+ mPreference = new Preference(mContext);
+ mPreference.setKey("test_key");
+
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+ when(mContext.getResources()).thenReturn(mResources);
+ }
+
+ @Test
+ public void displayPreference_navigationGestureEnabled_setCorrectTitle() {
+ when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
+ .thenReturn(NAV_BAR_MODE_GESTURAL);
+
+ mController.displayPreference(mScreen);
+
+ assertThat(mPreference.getTitle()).isEqualTo(
+ mContext.getText(R.string.accessibility_button_gesture_title));
+ }
+
+ @Test
+ public void displayPreference_navigationGestureDisabled_setCorrectTitle() {
+ when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
+ .thenReturn(NAV_BAR_MODE_2BUTTON);
+
+ mController.displayPreference(mScreen);
+
+ assertThat(mPreference.getTitle()).isEqualTo(
+ mContext.getText(R.string.accessibility_button_title));
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonPreviewPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonPreviewPreferenceControllerTest.java
index 306503040ce..05aba99d452 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonPreviewPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonPreviewPreferenceControllerTest.java
@@ -19,6 +19,8 @@ package com.android.settings.accessibility;
import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU;
import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR;
+import static com.android.settings.testutils.ImageTestUtils.drawableToBitmap;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.verify;
@@ -28,12 +30,11 @@ import android.content.ContentResolver;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.provider.Settings;
-import android.widget.ImageView;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
-import com.android.settings.testutils.ImageTestUtils;
+import com.android.settingslib.widget.IllustrationPreference;
import org.junit.Before;
import org.junit.Rule;
@@ -62,7 +63,7 @@ public class AccessibilityButtonPreviewPreferenceControllerTest {
public void setUp() {
when(mContext.getContentResolver()).thenReturn(mContentResolver);
mController = new AccessibilityButtonPreviewPreferenceController(mContext, "test_key");
- mController.mPreview = new ImageView(mContext);
+ mController.mIllustrationPreference = new IllustrationPreference(mContext);
}
@Test
@@ -74,8 +75,8 @@ public class AccessibilityButtonPreviewPreferenceControllerTest {
final Drawable navigationBarDrawable = mContext.getDrawable(
R.drawable.accessibility_button_navigation);
- assertThat(ImageTestUtils.drawableToBitmap(mController.mPreview.getDrawable()).sameAs(
- ImageTestUtils.drawableToBitmap(navigationBarDrawable))).isTrue();
+ assertThat(drawableToBitmap(mController.mIllustrationPreference.getImageDrawable()).sameAs(
+ drawableToBitmap(navigationBarDrawable))).isTrue();
}
@Test
@@ -90,10 +91,11 @@ public class AccessibilityButtonPreviewPreferenceControllerTest {
mController.mContentObserver.onChange(false);
final Drawable smallFloatingMenuWithTenOpacityDrawable =
- FloatingMenuLayerDrawable.createLayerDrawable(mContext,
+ AccessibilityLayerDrawable.createLayerDrawable(mContext,
R.drawable.accessibility_button_preview_small_floating_menu, 10);
- assertThat(mController.mPreview.getDrawable().getConstantState()).isEqualTo(
- smallFloatingMenuWithTenOpacityDrawable.getConstantState());
+ assertThat(
+ mController.mIllustrationPreference.getImageDrawable().getConstantState())
+ .isEqualTo(smallFloatingMenuWithTenOpacityDrawable.getConstantState());
}
@Test
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityDialogUtilsTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityDialogUtilsTest.java
new file mode 100644
index 00000000000..83bba142f78
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityDialogUtilsTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2021 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.accessibility;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+
+import androidx.appcompat.app.AlertDialog;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.R;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+/** Tests for {@link AccessibilityDialogUtils} */
+@RunWith(RobolectricTestRunner.class)
+public class AccessibilityDialogUtilsTest {
+
+ private final Context mContext = ApplicationProvider.getApplicationContext();
+
+ @Before
+ public void setUp() {
+ mContext.setTheme(R.style.Theme_AppCompat);
+ }
+
+ @Test
+ public void updateSoftwareShortcutInDialog_correctDialogType_success() {
+ final AlertDialog dialog = AccessibilityDialogUtils.showEditShortcutDialog(
+ mContext, AccessibilityDialogUtils.DialogType.EDIT_SHORTCUT_GENERIC, "Title",
+ null);
+
+ assertThat(
+ AccessibilityDialogUtils.updateSoftwareShortcutInDialog(mContext, dialog)).isTrue();
+ }
+
+ @Test
+ public void updateSoftwareShortcutInDialog_useNotSupportedDialog_fail() {
+ final AlertDialog dialog = new AlertDialog.Builder(mContext).setTitle("Title").show();
+
+ assertThat(AccessibilityDialogUtils.updateSoftwareShortcutInDialog(mContext,
+ dialog)).isFalse();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityFooterPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityFooterPreferenceControllerTest.java
new file mode 100644
index 00000000000..cc8520b9745
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityFooterPreferenceControllerTest.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2021 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.accessibility;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.preference.PreferenceScreen;
+import androidx.preference.PreferenceViewHolder;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.R;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.robolectric.RobolectricTestRunner;
+
+/**
+ * Tests for {@link AccessibilityFooterPreferenceController}.
+ */
+@RunWith(RobolectricTestRunner.class)
+public class AccessibilityFooterPreferenceControllerTest {
+
+ private static final String TEST_KEY = "test_pref_key";
+ private static final String TEST_TITLE = "test_title";
+ private static final String TEST_INTRODUCTION_TITLE = "test_introduction_title";
+ private static final String TEST_CONTENT_DESCRIPTION = "test_content_description";
+ private static final int TEST_HELP_ID = 12345;
+
+ @Rule
+ public final MockitoRule mockito = MockitoJUnit.rule();
+
+ @Spy
+ private final Context mContext = ApplicationProvider.getApplicationContext();
+ @Mock
+ private PreferenceScreen mScreen;
+ private AccessibilityFooterPreferenceController mController;
+ private AccessibilityFooterPreference mPreference;
+ private PreferenceViewHolder mPreferenceViewHolder;
+
+ @Before
+ public void setUp() {
+ mController = new AccessibilityFooterPreferenceController(mContext, TEST_KEY);
+ mPreference = new AccessibilityFooterPreference(mContext);
+ mPreference.setKey(TEST_KEY);
+ mPreference.setTitle(TEST_TITLE);
+
+ final LayoutInflater inflater = LayoutInflater.from(mContext);
+ final View view = inflater.inflate(R.layout.preference_footer, null);
+ mPreferenceViewHolder = PreferenceViewHolder.createInstanceForTests(view);
+ mPreference.onBindViewHolder(mPreferenceViewHolder);
+
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+ }
+
+ @Test
+ public void setIntroductionTitle_setCorrectIntroductionTitle() {
+ mController.setIntroductionTitle(TEST_INTRODUCTION_TITLE);
+
+ assertThat(mController.getIntroductionTitle()).isEqualTo(TEST_INTRODUCTION_TITLE);
+ }
+
+ @Test
+ public void onBindViewHolder_setIntroductionTitle_setCorrectIntroductionTitle() {
+ mController.setIntroductionTitle(TEST_INTRODUCTION_TITLE);
+ mController.displayPreference(mScreen);
+
+ mPreference.onBindViewHolder(mPreferenceViewHolder);
+
+ final TextView summaryView = (TextView) mPreferenceViewHolder
+ .findViewById(android.R.id.title);
+ assertThat(summaryView.getContentDescription().toString())
+ .contains(TEST_INTRODUCTION_TITLE);
+ }
+
+ @Test
+ public void setupHelpLink_setCorrectHelpLinkAndContentDescription() {
+ mController.setupHelpLink(TEST_HELP_ID, TEST_CONTENT_DESCRIPTION);
+
+ assertThat(mController.getHelpResource()).isEqualTo(TEST_HELP_ID);
+ assertThat(mController.getLearnMoreContentDescription())
+ .isEqualTo(TEST_CONTENT_DESCRIPTION);
+ }
+
+ @Test
+ public void onBindViewHolder_setHelpResource_emptyString_notVisible() {
+ mController.setupHelpLink(R.string.help_url_timeout, TEST_CONTENT_DESCRIPTION);
+ mController.displayPreference(mScreen);
+
+ mPreference.onBindViewHolder(mPreferenceViewHolder);
+
+ final TextView learnMoreView = (TextView) mPreferenceViewHolder
+ .findViewById(com.android.settingslib.R.id.settingslib_learn_more);
+ assertThat(learnMoreView.getContentDescription()).isNull();
+ assertThat(learnMoreView.getVisibility()).isEqualTo(View.GONE);
+ assertThat(mPreference.isLinkEnabled()).isFalse();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/FloatingMenuLayerDrawableTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityLayerDrawableTest.java
similarity index 83%
rename from tests/robotests/src/com/android/settings/accessibility/FloatingMenuLayerDrawableTest.java
rename to tests/robotests/src/com/android/settings/accessibility/AccessibilityLayerDrawableTest.java
index 45cefe482b0..915c788c3bd 100644
--- a/tests/robotests/src/com/android/settings/accessibility/FloatingMenuLayerDrawableTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityLayerDrawableTest.java
@@ -30,9 +30,9 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
-/** Tests for {@link FloatingMenuLayerDrawable}. */
+/** Tests for {@link AccessibilityLayerDrawable}. */
@RunWith(RobolectricTestRunner.class)
-public class FloatingMenuLayerDrawableTest {
+public class AccessibilityLayerDrawableTest {
private static final int TEST_RES_ID =
com.android.internal.R.drawable.ic_accessibility_magnification;
@@ -46,8 +46,8 @@ public class FloatingMenuLayerDrawableTest {
R.drawable.accessibility_button_preview_base);
final Drawable expected2ndDrawable = mContext.getDrawable(TEST_RES_ID);
- final FloatingMenuLayerDrawable actualDrawable =
- FloatingMenuLayerDrawable.createLayerDrawable(mContext, TEST_RES_ID,
+ final AccessibilityLayerDrawable actualDrawable =
+ AccessibilityLayerDrawable.createLayerDrawable(mContext, TEST_RES_ID,
/* opacity= */ 27);
final Drawable actual1stDrawable = actualDrawable.getDrawable(0);
@@ -60,14 +60,14 @@ public class FloatingMenuLayerDrawableTest {
@Test
public void updateLayerDrawable_expectedFloatingMenuLayerDrawableState() {
- final FloatingMenuLayerDrawable originalDrawable =
- FloatingMenuLayerDrawable.createLayerDrawable(mContext, TEST_RES_ID, /* opacity= */
+ final AccessibilityLayerDrawable originalDrawable =
+ AccessibilityLayerDrawable.createLayerDrawable(mContext, TEST_RES_ID, /* opacity= */
72);
originalDrawable.updateLayerDrawable(mContext, TEST_RES_ID_2, /* opacity= */ 27);
assertThat(originalDrawable.getConstantState()).isEqualTo(
- new FloatingMenuLayerDrawable.FloatingMenuLayerDrawableState(mContext,
+ new AccessibilityLayerDrawable.AccessibilityLayerDrawableState(mContext,
TEST_RES_ID_2, /* opacity= */ 27));
}
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityScreenSizeForSetupWizardActivityTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityScreenSizeForSetupWizardActivityTest.java
new file mode 100644
index 00000000000..4f1edba01e0
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityScreenSizeForSetupWizardActivityTest.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2021 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.accessibility;
+
+import static com.android.settings.accessibility.AccessibilityScreenSizeForSetupWizardActivity.VISION_FRAGMENT_NO;
+import static com.android.settings.core.SettingsBaseActivity.EXTRA_PAGE_TRANSITION_TYPE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.robolectric.Shadows.shadowOf;
+
+import android.content.Context;
+import android.content.Intent;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.R;
+import com.android.settings.accessibility.AccessibilityScreenSizeForSetupWizardActivity.FragmentType;
+import com.android.settingslib.transition.SettingsTransitionHelper.TransitionType;
+
+import com.google.android.setupcompat.template.FooterBarMixin;
+import com.google.android.setupdesign.GlifLayout;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+import org.robolectric.RobolectricTestRunner;
+
+/** Tests for {@link AccessibilityScreenSizeForSetupWizardActivity} */
+@RunWith(RobolectricTestRunner.class)
+public class AccessibilityScreenSizeForSetupWizardActivityTest {
+
+ private Context mContext = ApplicationProvider.getApplicationContext();
+
+ private AccessibilityScreenSizeForSetupWizardActivity setupActivity(int fragmentType) {
+ final Intent intent = new Intent();
+ intent.putExtra(VISION_FRAGMENT_NO, fragmentType);
+ return Robolectric.buildActivity(AccessibilityScreenSizeForSetupWizardActivity.class,
+ intent).create().get();
+ }
+
+ private AccessibilityScreenSizeForSetupWizardActivity setupActivity(int fragmentType,
+ int transitionType) {
+ final Intent intent = new Intent();
+ intent.putExtra(VISION_FRAGMENT_NO, fragmentType);
+ intent.putExtra(EXTRA_PAGE_TRANSITION_TYPE, transitionType);
+ return Robolectric.buildActivity(AccessibilityScreenSizeForSetupWizardActivity.class,
+ intent).create().get();
+ }
+
+ @Test
+ public void setupActivity_fontSizePage_returnFontSizeTitle() {
+ final AccessibilityScreenSizeForSetupWizardActivity activity =
+ setupActivity(FragmentType.FONT_SIZE, TransitionType.TRANSITION_FADE);
+
+ final GlifLayout layout = activity.findViewById(R.id.setup_wizard_layout);
+ assertThat(layout.getHeaderText()).isEqualTo(mContext.getText(R.string.title_font_size));
+ }
+
+ @Test
+ public void setupActivity_generateDoneButton() {
+ final AccessibilityScreenSizeForSetupWizardActivity activity =
+ setupActivity(FragmentType.FONT_SIZE, TransitionType.TRANSITION_FADE);
+
+ final GlifLayout layout = activity.findViewById(R.id.setup_wizard_layout);
+ final FooterBarMixin mixin = layout.getMixin(FooterBarMixin.class);
+ assertThat(mixin.getPrimaryButton().getText()).isEqualTo(mContext.getText(R.string.done));
+ }
+
+ @Test
+ public void onPause_getPendingTransitionEnterAnimationResourceId_transitionFade_should() {
+ final AccessibilityScreenSizeForSetupWizardActivity activity =
+ setupActivity(FragmentType.FONT_SIZE, TransitionType.TRANSITION_FADE);
+
+ activity.onPause();
+
+ assertThat(shadowOf(activity).getPendingTransitionEnterAnimationResourceId())
+ .isEqualTo(R.anim.sud_stay);
+ }
+
+ @Test
+ public void onPause_getPendingTransitionExitAnimationResourceId_transitionFade_should() {
+ final AccessibilityScreenSizeForSetupWizardActivity activity =
+ setupActivity(FragmentType.FONT_SIZE, TransitionType.TRANSITION_FADE);
+
+ activity.onPause();
+
+ assertThat(shadowOf(activity).getPendingTransitionExitAnimationResourceId())
+ .isEqualTo(android.R.anim.fade_out);
+ }
+
+ @Test
+ public void onPause_getPendingTransitionEnterAnimationResourceId_transitionNone_should() {
+ final AccessibilityScreenSizeForSetupWizardActivity activity =
+ setupActivity(FragmentType.FONT_SIZE);
+
+ activity.onPause();
+
+ assertThat(shadowOf(activity).getPendingTransitionEnterAnimationResourceId())
+ .isNotEqualTo(R.anim.sud_stay);
+ }
+
+ @Test
+ public void onPause_getPendingTransitionExitAnimationResourceId_transitionNone_should() {
+ final AccessibilityScreenSizeForSetupWizardActivity activity =
+ setupActivity(FragmentType.FONT_SIZE);
+
+ activity.onPause();
+
+ assertThat(shadowOf(activity).getPendingTransitionExitAnimationResourceId())
+ .isNotEqualTo(android.R.anim.fade_out);
+ }
+
+ @Test
+ public void updateHeaderLayout_displaySizePage_returnDisplaySizeTitle() {
+ final Intent intent = new Intent();
+ intent.putExtra(VISION_FRAGMENT_NO, FragmentType.SCREEN_SIZE);
+ intent.putExtra(EXTRA_PAGE_TRANSITION_TYPE, TransitionType.TRANSITION_FADE);
+ final AccessibilityScreenSizeForSetupWizardActivity activity = Robolectric.buildActivity(
+ AccessibilityScreenSizeForSetupWizardActivity.class, intent).get();
+ activity.setContentView(R.layout.accessibility_screen_size_setup_wizard);
+ activity.updateHeaderLayout();
+ final GlifLayout layout = activity.findViewById(R.id.setup_wizard_layout);
+ assertThat(layout.getHeaderText()).isEqualTo(mContext.getText(R.string.screen_zoom_title));
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizardActivityTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizardActivityTest.java
index c3a630b0670..0849eb2bd1f 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizardActivityTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizardActivityTest.java
@@ -16,6 +16,7 @@
package com.android.settings.accessibility;
+import static com.android.settings.accessibility.AccessibilityScreenSizeForSetupWizardActivity.VISION_FRAGMENT_NO;
import static com.android.settings.accessibility.AccessibilitySettingsForSetupWizardActivity.CLASS_NAME_FONT_SIZE_SETTINGS_FOR_SUW;
import static com.google.common.truth.Truth.assertThat;
@@ -26,8 +27,7 @@ import android.content.Intent;
import androidx.test.filters.SmallTest;
import com.android.settings.R;
-import com.android.settings.SettingsActivity;
-import com.android.settings.display.FontSizePreferenceFragmentForSetupWizard;
+import com.android.settings.accessibility.AccessibilityScreenSizeForSetupWizardActivity.FragmentType;
import com.google.android.setupcompat.util.WizardManagerHelper;
@@ -42,45 +42,47 @@ import org.robolectric.Shadows;
@SmallTest
public class AccessibilitySettingsForSetupWizardActivityTest {
- @Test
- public void createSetupAccessibilityActivity_shouldBeSUWTheme() {
- final Intent intent = new Intent();
- AccessibilitySettingsForSetupWizardActivity activity =
- Robolectric.buildActivity(AccessibilitySettingsForSetupWizardActivity.class, intent).get();
+ @Test
+ public void createSetupAccessibilityActivity_shouldBeSUWTheme() {
+ final Intent intent = new Intent();
+ AccessibilitySettingsForSetupWizardActivity activity =
+ Robolectric.buildActivity(AccessibilitySettingsForSetupWizardActivity.class,
+ intent).get();
- assertThat(activity.getThemeResId()).isEqualTo(R.style.GlifV3Theme_Light);
- }
+ assertThat(activity.getThemeResId()).isEqualTo(R.style.GlifV3Theme_Light);
+ }
- @Test
- public void onCreate_hasFontSizeComponent_shouldGoToFontSizePreferenceDirectly() {
- AccessibilitySettingsForSetupWizardActivity activity =
- Robolectric.buildActivity(AccessibilitySettingsForSetupWizardActivity.class,
- new Intent(Intent.ACTION_MAIN).setComponent(new ComponentName(
- RuntimeEnvironment.application, CLASS_NAME_FONT_SIZE_SETTINGS_FOR_SUW)).
- putExtra(WizardManagerHelper.EXTRA_IS_FIRST_RUN, true).
- putExtra(WizardManagerHelper.EXTRA_IS_SETUP_FLOW, true)).get();
+ @Test
+ public void onCreate_hasFontSizeComponent_shouldGoToFontSizePreferenceDirectly() {
+ AccessibilitySettingsForSetupWizardActivity activity =
+ Robolectric.buildActivity(AccessibilitySettingsForSetupWizardActivity.class,
+ new Intent(Intent.ACTION_MAIN).setComponent(new ComponentName(
+ RuntimeEnvironment.application,
+ CLASS_NAME_FONT_SIZE_SETTINGS_FOR_SUW))
+ .putExtra(WizardManagerHelper.EXTRA_IS_FIRST_RUN, true)
+ .putExtra(WizardManagerHelper.EXTRA_IS_SETUP_FLOW, true)).get();
- activity.tryLaunchFontSizeSettings();
+ activity.tryLaunchFontSizeSettings();
- final Intent launchIntent = Shadows.shadowOf(activity).getNextStartedActivity();
- assertThat(launchIntent).isNotNull();
- assertThat(launchIntent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT)).isEqualTo(
- FontSizePreferenceFragmentForSetupWizard.class.getName());
- assertThat(activity.isFinishing()).isTrue();
- }
+ final Intent launchIntent = Shadows.shadowOf(activity).getNextStartedActivity();
+ assertThat(launchIntent).isNotNull();
+ assertThat(launchIntent.getIntExtra(VISION_FRAGMENT_NO, -1)).isEqualTo(
+ FragmentType.FONT_SIZE);
+ assertThat(activity.isFinishing()).isTrue();
+ }
- @Test
- public void onCreate_noFontSizeComponent_shouldNotFinishCurrentActivity() {
- AccessibilitySettingsForSetupWizardActivity activity =
- Robolectric.buildActivity(AccessibilitySettingsForSetupWizardActivity.class,
- new Intent(Intent.ACTION_MAIN).
- putExtra(WizardManagerHelper.EXTRA_IS_FIRST_RUN, true).
- putExtra(WizardManagerHelper.EXTRA_IS_SETUP_FLOW, true)).get();
+ @Test
+ public void onCreate_noFontSizeComponent_shouldNotFinishCurrentActivity() {
+ AccessibilitySettingsForSetupWizardActivity activity =
+ Robolectric.buildActivity(AccessibilitySettingsForSetupWizardActivity.class,
+ new Intent(Intent.ACTION_MAIN)
+ .putExtra(WizardManagerHelper.EXTRA_IS_FIRST_RUN, true)
+ .putExtra(WizardManagerHelper.EXTRA_IS_SETUP_FLOW, true)).get();
- activity.tryLaunchFontSizeSettings();
+ activity.tryLaunchFontSizeSettings();
- final Intent launchIntent = Shadows.shadowOf(activity).getNextStartedActivity();
- assertThat(launchIntent).isNull();
- assertThat(activity.isFinishing()).isFalse();
- }
+ final Intent launchIntent = Shadows.shadowOf(activity).getNextStartedActivity();
+ assertThat(launchIntent).isNull();
+ assertThat(activity.isFinishing()).isFalse();
+ }
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySetupWizardUtilsTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySetupWizardUtilsTest.java
new file mode 100644
index 00000000000..e79b12231c9
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySetupWizardUtilsTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2021 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.accessibility;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import com.google.android.setupdesign.GlifPreferenceLayout;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+/** Tests for {@link AccessibilitySetupWizardUtils} */
+@RunWith(RobolectricTestRunner.class)
+public class AccessibilitySetupWizardUtilsTest {
+
+ private final Context mContext = ApplicationProvider.getApplicationContext();
+
+ @Test
+ public void setupGlifPreferenceLayout_assignValueToVariable() {
+ final String title = "title";
+ final String description = "description";
+ final Drawable icon = mock(Drawable.class);
+ GlifPreferenceLayout layout = mock(GlifPreferenceLayout.class);
+
+ AccessibilitySetupWizardUtils.updateGlifPreferenceLayout(mContext, layout, title,
+ description, icon);
+
+ verify(layout).setHeaderText(title);
+ verify(layout).setDescriptionText(description);
+ verify(layout).setIcon(icon);
+ verify(layout).setHeaderText(title);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragmentTest.java
index 6d70bf74cca..48d344a65ea 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragmentTest.java
@@ -180,8 +180,8 @@ public class AccessibilityShortcutPreferenceFragmentTest {
savedInstanceState.putInt(KEY_SAVED_USER_SHORTCUT_TYPE,
AccessibilityUtil.UserShortcutType.SOFTWARE
| AccessibilityUtil.UserShortcutType.HARDWARE);
- mFragment.onCreate(savedInstanceState);
mFragment.onAttach(mContext);
+ mFragment.onCreate(savedInstanceState);
mFragment.setupEditShortcutDialog(dialog);
final int value = mFragment.getShortcutTypeCheckBoxValue();
mFragment.saveNonEmptyUserShortcutType(value);
@@ -195,9 +195,11 @@ public class AccessibilityShortcutPreferenceFragmentTest {
}
@Test
+ @Config(shadows = ShadowFragment.class)
public void showGeneralCategory_shouldInitCategory() {
final Bundle savedInstanceState = new Bundle();
when(mFragment.showGeneralCategory()).thenReturn(true);
+ mFragment.onAttach(mContext);
mFragment.onCreate(savedInstanceState);
verify(mFragment).initGeneralCategory();
diff --git a/tests/robotests/src/com/android/settings/accessibility/FontSizePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/FontSizePreferenceControllerTest.java
new file mode 100644
index 00000000000..a52c0fe0e0b
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/FontSizePreferenceControllerTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2021 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.accessibility;
+
+import static com.android.settings.accessibility.AccessibilityScreenSizeForSetupWizardActivity.VISION_FRAGMENT_NO;
+import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+import static com.android.settings.core.SettingsBaseActivity.EXTRA_PAGE_TRANSITION_TYPE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.robolectric.Shadows.shadowOf;
+
+import android.app.Activity;
+import android.content.Intent;
+
+import androidx.preference.Preference;
+
+import com.android.settings.accessibility.AccessibilityScreenSizeForSetupWizardActivity.FragmentType;
+import com.android.settingslib.transition.SettingsTransitionHelper.TransitionType;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
+import org.robolectric.RobolectricTestRunner;
+
+/** Tests for {@link FontSizePreferenceController}. */
+@RunWith(RobolectricTestRunner.class)
+public class FontSizePreferenceControllerTest {
+ private static final String TEST_KEY = "test_key";
+
+ private Activity mActivity;
+ private FontSizePreferenceController mController;
+ Preference mPreference;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mActivity = Robolectric.setupActivity(Activity.class);
+ mController = new FontSizePreferenceController(mActivity, TEST_KEY);
+ mPreference = new Preference(mActivity);
+ mPreference.setKey(TEST_KEY);
+ }
+
+ @Test
+ public void getAvailabilityStatus_returnAvailable() {
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+ }
+
+ @Test
+ public void handlePreferenceTreeClick_launchActivityWithExpectedValues() {
+ mController.handlePreferenceTreeClick(mPreference);
+
+ final Intent nextActivity = shadowOf(mActivity).getNextStartedActivity();
+ assertThat(nextActivity.getIntExtra(VISION_FRAGMENT_NO, /* defaultValue= */-1))
+ .isEqualTo(FragmentType.FONT_SIZE);
+ assertThat(nextActivity.getIntExtra(EXTRA_PAGE_TRANSITION_TYPE, /* defaultValue= */-1))
+ .isEqualTo(TransitionType.TRANSITION_FADE);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/ScreenSizePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/ScreenSizePreferenceControllerTest.java
new file mode 100644
index 00000000000..1cbf78ea84c
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/ScreenSizePreferenceControllerTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2021 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.accessibility;
+
+import static com.android.settings.accessibility.AccessibilityScreenSizeForSetupWizardActivity.VISION_FRAGMENT_NO;
+import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+import static com.android.settings.core.SettingsBaseActivity.EXTRA_PAGE_TRANSITION_TYPE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.robolectric.Shadows.shadowOf;
+
+import android.app.Activity;
+import android.content.Intent;
+
+import androidx.preference.Preference;
+
+import com.android.settings.accessibility.AccessibilityScreenSizeForSetupWizardActivity.FragmentType;
+import com.android.settingslib.transition.SettingsTransitionHelper.TransitionType;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
+import org.robolectric.RobolectricTestRunner;
+
+/** Tests for {@link ScreenSizePreferenceController}. */
+@RunWith(RobolectricTestRunner.class)
+public class ScreenSizePreferenceControllerTest {
+ private static final String TEST_KEY = "test_key";
+
+ private Activity mActivity;
+ private ScreenSizePreferenceController mController;
+ Preference mPreference;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mActivity = Robolectric.setupActivity(Activity.class);
+ mController = new ScreenSizePreferenceController(mActivity, TEST_KEY);
+ mPreference = new Preference(mActivity);
+ mPreference.setKey(TEST_KEY);
+ }
+
+ @Test
+ public void getAvailabilityStatus_returnAvailable() {
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+ }
+
+ @Test
+ public void handlePreferenceTreeClick_launchActivityWithExpectedValues() {
+ mController.handlePreferenceTreeClick(mPreference);
+
+ final Intent nextActivity = shadowOf(mActivity).getNextStartedActivity();
+ assertThat(nextActivity.getIntExtra(VISION_FRAGMENT_NO, /* defaultValue= */-1))
+ .isEqualTo(FragmentType.SCREEN_SIZE);
+ assertThat(nextActivity.getIntExtra(EXTRA_PAGE_TRANSITION_TYPE, /* defaultValue= */-1))
+ .isEqualTo(TransitionType.TRANSITION_FADE);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/accounts/AccountDetailDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/accounts/AccountDetailDashboardFragmentTest.java
index a827284a088..cccca9c9ea5 100644
--- a/tests/robotests/src/com/android/settings/accounts/AccountDetailDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/AccountDetailDashboardFragmentTest.java
@@ -43,7 +43,6 @@ import android.os.UserManager;
import androidx.fragment.app.FragmentActivity;
import androidx.preference.Preference;
-import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.dashboard.DashboardFeatureProviderImpl;
import com.android.settings.testutils.shadow.ShadowAccountManager;
import com.android.settings.testutils.shadow.ShadowUserManager;
@@ -151,9 +150,9 @@ public class AccountDetailDashboardFragmentTest {
final FragmentActivity activity = Robolectric.setupActivity(FragmentActivity.class);
final Preference preference = new Preference(mContext);
- dashboardFeatureProvider.bindPreferenceToTileAndGetObservers(activity,
- false /* forceRoundedIcon */, MetricsProto.MetricsEvent.DASHBOARD_SUMMARY,
- preference, tile, null /* key */, Preference.DEFAULT_ORDER);
+ dashboardFeatureProvider.bindPreferenceToTileAndGetObservers(activity, mFragment,
+ false /* forceRoundedIcon */, preference, tile, null /* key */,
+ Preference.DEFAULT_ORDER);
assertThat(preference.getKey()).isEqualTo(tile.getKey(mContext));
preference.performClick();
diff --git a/tests/robotests/src/com/android/settings/applications/managedomainurls/DomainAppPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/managedomainurls/DomainAppPreferenceControllerTest.java
index 5e5239d6a88..9db75a2ec68 100644
--- a/tests/robotests/src/com/android/settings/applications/managedomainurls/DomainAppPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/managedomainurls/DomainAppPreferenceControllerTest.java
@@ -18,8 +18,17 @@ package com.android.settings.applications.managedomainurls;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.anyString;
+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.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.verify.domain.DomainVerificationManager;
+import android.content.pm.verify.domain.DomainVerificationUserState;
import android.util.IconDrawableFactory;
import com.android.settings.R;
@@ -28,6 +37,8 @@ import com.android.settingslib.applications.ApplicationsState;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
@@ -40,16 +51,30 @@ public class DomainAppPreferenceControllerTest {
private Context mContext;
private IconDrawableFactory mIconDrawableFactory;
+ @Mock
+ private DomainVerificationManager mDomainVerificationManager;
+ @Mock
+ private DomainVerificationUserState mDomainVerificationUserState;
+
@Before
public void setUp() {
- mContext = RuntimeEnvironment.application;
+ MockitoAnnotations.initMocks(this);
+ mContext = spy(RuntimeEnvironment.application);
mIconDrawableFactory = IconDrawableFactory.newInstance(mContext);
mAppEntry = new ApplicationsState.AppEntry(
mContext, createApplicationInfo(mContext.getPackageName()), 0);
+ when(mContext.getSystemService(DomainVerificationManager.class)).thenReturn(
+ mDomainVerificationManager);
}
@Test
- public void getLayoutResource_shouldUseAppPreferenceLayout() {
+ public void getLayoutResource_shouldUseAppPreferenceLayout()
+ throws PackageManager.NameNotFoundException {
+ final DomainVerificationUserState domainVerificationUserState = mock(
+ DomainVerificationUserState.class);
+ doReturn(domainVerificationUserState).when(
+ mDomainVerificationManager).getDomainVerificationUserState(anyString());
+ doReturn(true).when(domainVerificationUserState).isLinkHandlingAllowed();
final DomainAppPreference pref = new DomainAppPreference(
mContext, mIconDrawableFactory, mAppEntry);
diff --git a/tests/robotests/src/com/android/settings/biometrics/combination/CombinedBiometricStatusPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/biometrics/combination/CombinedBiometricStatusPreferenceControllerTest.java
index 3a973879bda..02bca3e1e83 100644
--- a/tests/robotests/src/com/android/settings/biometrics/combination/CombinedBiometricStatusPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/biometrics/combination/CombinedBiometricStatusPreferenceControllerTest.java
@@ -104,12 +104,16 @@ public class CombinedBiometricStatusPreferenceControllerTest {
RestrictedLockUtils.EnforcedAdmin admin = mock(RestrictedLockUtils.EnforcedAdmin.class);
mController.mPreference = restrictedPreference;
- mController.updateStateInternal(admin);
+ mController.updateStateInternal(admin, true, true);
verify(restrictedPreference).setDisabledByAdmin(eq(admin));
- reset(admin);
+ mController.updateStateInternal(admin, true, false);
+ verify(restrictedPreference).setDisabledByAdmin(eq(null));
- mController.updateStateInternal(null /* enforcedAdmin */);
- verify(restrictedPreference, never()).setDisabledByAdmin(any());
+ mController.updateStateInternal(admin, false, true);
+ verify(restrictedPreference).setDisabledByAdmin(eq(null));
+
+ mController.updateStateInternal(admin, false, false);
+ verify(restrictedPreference).setDisabledByAdmin(eq(null));
}
}
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothFilesPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothFilesPreferenceControllerTest.java
deleted file mode 100644
index 40489983acc..00000000000
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothFilesPreferenceControllerTest.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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.bluetooth;
-
-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.content.Intent;
-import android.content.pm.PackageManager;
-import android.os.Bundle;
-
-import androidx.preference.Preference;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.shadows.ShadowApplication;
-
-@RunWith(RobolectricTestRunner.class)
-public class BluetoothFilesPreferenceControllerTest {
-
- private Context mContext;
- private BluetoothFilesPreferenceController mController;
- private Preference mPreference;
- @Mock
- private PackageManager mPackageManager;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mContext = spy(RuntimeEnvironment.application);
- mController = new BluetoothFilesPreferenceController(mContext);
- mPreference = new Preference(mContext);
- mPreference.setKey(BluetoothFilesPreferenceController.KEY_RECEIVED_FILES);
- doReturn(mPackageManager).when(mContext).getPackageManager();
- doReturn(true).when(mPackageManager).hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);
- }
-
- @Test
- public void testHandlePreferenceTreeClick_sendBroadcast() {
- mController.handlePreferenceTreeClick(mPreference);
-
- final Intent intent = ShadowApplication.getInstance().getNextStartedActivity();
- assertThat(intent).isNotNull();
- assertThat(intent.getAction())
- .isEqualTo(BluetoothFilesPreferenceController.ACTION_OPEN_FILES);
-
- final Bundle bundle = intent.getExtras();
- assertThat(bundle.getInt(BluetoothFilesPreferenceController.EXTRA_DIRECTION)).isEqualTo(1);
- assertThat(bundle.getBoolean(BluetoothFilesPreferenceController.EXTRA_SHOW_ALL_FILES))
- .isTrue();
- }
-}
diff --git a/tests/robotests/src/com/android/settings/bluetooth/ForgetDeviceDialogFragmentTest.java b/tests/robotests/src/com/android/settings/bluetooth/ForgetDeviceDialogFragmentTest.java
index b4f4f97f228..5c232386121 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/ForgetDeviceDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/ForgetDeviceDialogFragmentTest.java
@@ -98,20 +98,6 @@ public class ForgetDeviceDialogFragmentTest {
assertThat(mActivity.isFinishing()).isTrue();
}
- @Test
- public void createDialog_untetheredDevice_showUntetheredMessage() {
- when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET))
- .thenReturn("true".getBytes());
-
- FragmentController.setupFragment(mFragment, FragmentActivity.class,
- 0 /* containerViewId */, null /* bundle */);
- final AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
- ShadowAlertDialogCompat shadowDialog = ShadowAlertDialogCompat.shadowOf(dialog);
-
- assertThat(shadowDialog.getMessage()).isEqualTo(
- mContext.getString(R.string.bluetooth_untethered_unpair_dialog_body, DEVICE_NAME));
- }
-
@Test
public void createDialog_normalDevice_showNormalMessage() {
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET))
diff --git a/tests/robotests/src/com/android/settings/core/PreferenceXmlParserUtilsTest.java b/tests/robotests/src/com/android/settings/core/PreferenceXmlParserUtilsTest.java
index 4cde04b94b4..23ade9d14ab 100644
--- a/tests/robotests/src/com/android/settings/core/PreferenceXmlParserUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/core/PreferenceXmlParserUtilsTest.java
@@ -174,18 +174,36 @@ public class PreferenceXmlParserUtilsTest {
assertThat(entries).isNull();
}
+ @Test
+ public void extractHomepageMetadata_shouldContainKeyAndHighlightableMenuKey()
+ throws IOException, XmlPullParserException {
+ List metadata = PreferenceXmlParserUtils.extractMetadata(mContext,
+ R.xml.top_level_settings,
+ MetadataFlag.FLAG_NEED_KEY | MetadataFlag.FLAG_NEED_HIGHLIGHTABLE_MENU_KEY);
+
+ assertThat(metadata).isNotEmpty();
+ for (Bundle bundle : metadata) {
+ assertThat(bundle.getString(PreferenceXmlParserUtils.METADATA_KEY)).isNotNull();
+ assertThat(bundle.getString(PreferenceXmlParserUtils.METADATA_HIGHLIGHTABLE_MENU_KEY))
+ .isNotNull();
+ }
+ }
+
@Test
@Config(qualifiers = "mcc999")
- public void extractMetadata_shouldContainKeyAndControllerName()
+ public void extractMetadata_shouldContainKeyAndControllerNameAndHighlightableMenuKey()
throws IOException, XmlPullParserException {
List metadata = PreferenceXmlParserUtils.extractMetadata(mContext,
R.xml.location_settings,
- MetadataFlag.FLAG_NEED_KEY | MetadataFlag.FLAG_NEED_PREF_CONTROLLER);
+ MetadataFlag.FLAG_NEED_KEY | MetadataFlag.FLAG_NEED_PREF_CONTROLLER
+ | MetadataFlag.FLAG_NEED_HIGHLIGHTABLE_MENU_KEY);
assertThat(metadata).isNotEmpty();
for (Bundle bundle : metadata) {
assertThat(bundle.getString(PreferenceXmlParserUtils.METADATA_KEY)).isNotNull();
assertThat(bundle.getString(PreferenceXmlParserUtils.METADATA_CONTROLLER)).isNotNull();
+ assertThat(bundle.getString(PreferenceXmlParserUtils.METADATA_HIGHLIGHTABLE_MENU_KEY))
+ .isNotNull();
}
}
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java
index 6ef6b18ec68..e7c99c873b1 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java
@@ -114,6 +114,7 @@ public class DashboardFeatureProviderImplTest {
private Bundle mSwitchMetaData;
private DashboardFeatureProviderImpl mImpl;
private boolean mForceRoundedIcon;
+ private DashboardFragment mFragment;
@Before
public void setUp() {
@@ -144,6 +145,7 @@ public class DashboardFeatureProviderImplTest {
.thenReturn(new ResolveInfo());
mFeatureFactory = FakeFeatureFactory.setupForTest();
mImpl = new DashboardFeatureProviderImpl(mContext);
+ mFragment = new TestFragment();
}
@Test
@@ -159,8 +161,8 @@ public class DashboardFeatureProviderImplTest {
doReturn(Icon.createWithBitmap(Bitmap.createBitmap(1, 1, Bitmap.Config.RGB_565)))
.when(tile).getIcon(any(Context.class));
mActivityInfo.metaData.putString(SettingsActivity.META_DATA_KEY_FRAGMENT_CLASS, "HI");
- mImpl.bindPreferenceToTileAndGetObservers(mActivity, mForceRoundedIcon,
- MetricsEvent.SETTINGS_GESTURES, preference, tile, "123", Preference.DEFAULT_ORDER);
+ mImpl.bindPreferenceToTileAndGetObservers(mActivity, mFragment, mForceRoundedIcon,
+ preference, tile, "123", Preference.DEFAULT_ORDER);
assertThat(preference.getTitle()).isEqualTo(mContext.getText(R.string.settings_label));
assertThat(preference.getSummary())
@@ -180,8 +182,8 @@ public class DashboardFeatureProviderImplTest {
doReturn(Icon.createWithBitmap(Bitmap.createBitmap(1, 1, Bitmap.Config.RGB_565)))
.when(tile).getIcon(any(Context.class));
final List observers = mImpl.bindPreferenceToTileAndGetObservers(
- mActivity, mForceRoundedIcon, MetricsEvent.SETTINGS_GESTURES, preference, tile,
- null /* key*/, Preference.DEFAULT_ORDER);
+ mActivity, mFragment, mForceRoundedIcon, preference, tile, null /* key*/,
+ Preference.DEFAULT_ORDER);
assertThat(preference.getTitle()).isEqualTo(mContext.getText(R.string.settings_label));
assertThat(preference.getSummary())
@@ -198,8 +200,8 @@ public class DashboardFeatureProviderImplTest {
mActivityInfo.metaData.putInt(META_DATA_KEY_ORDER, 10);
final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE);
- mImpl.bindPreferenceToTileAndGetObservers(mActivity, mForceRoundedIcon,
- MetricsEvent.SETTINGS_GESTURES, preference, tile, "123", Preference.DEFAULT_ORDER);
+ mImpl.bindPreferenceToTileAndGetObservers(mActivity, mFragment, mForceRoundedIcon,
+ preference, tile, "123", Preference.DEFAULT_ORDER);
assertThat(preference.getFragment()).isNull();
assertThat(preference.getOnPreferenceClickListener()).isNotNull();
@@ -214,8 +216,8 @@ public class DashboardFeatureProviderImplTest {
tile.userHandle.add(mock(UserHandle.class));
tile.userHandle.add(mock(UserHandle.class));
- mImpl.bindPreferenceToTileAndGetObservers(mActivity, mForceRoundedIcon,
- MetricsEvent.SETTINGS_GESTURES, preference, tile, "123", Preference.DEFAULT_ORDER);
+ mImpl.bindPreferenceToTileAndGetObservers(mActivity, mFragment, mForceRoundedIcon,
+ preference, tile, "123", Preference.DEFAULT_ORDER);
preference.getOnPreferenceClickListener().onPreferenceClick(null);
verify(mActivity).getSupportFragmentManager();
@@ -231,15 +233,15 @@ public class DashboardFeatureProviderImplTest {
when(mActivity.getSystemService(Context.USER_SERVICE))
.thenReturn(mUserManager);
- mImpl.bindPreferenceToTileAndGetObservers(mActivity, mForceRoundedIcon,
- MetricsEvent.SETTINGS_GESTURES, preference, tile, "123", Preference.DEFAULT_ORDER);
+ mImpl.bindPreferenceToTileAndGetObservers(mActivity, mFragment, mForceRoundedIcon,
+ preference, tile, "123", Preference.DEFAULT_ORDER);
preference.getOnPreferenceClickListener().onPreferenceClick(null);
verify(mFeatureFactory.metricsFeatureProvider).logStartedIntent(
any(Intent.class),
eq(MetricsEvent.SETTINGS_GESTURES));
verify(mActivity)
- .startActivityForResultAsUser(any(Intent.class), anyInt(), any(UserHandle.class));
+ .startActivityAsUser(any(Intent.class), any(UserHandle.class));
}
@Test
@@ -250,21 +252,21 @@ public class DashboardFeatureProviderImplTest {
tile.userHandle = new ArrayList<>();
tile.userHandle.add(mock(UserHandle.class));
- mImpl.bindPreferenceToTileAndGetObservers(mActivity, mForceRoundedIcon,
- MetricsEvent.SETTINGS_GESTURES, preference, tile, "123", Preference.DEFAULT_ORDER);
+ mImpl.bindPreferenceToTileAndGetObservers(mActivity, mFragment, mForceRoundedIcon,
+ preference, tile, "123", Preference.DEFAULT_ORDER);
preference.getOnPreferenceClickListener().onPreferenceClick(null);
verify(mFeatureFactory.metricsFeatureProvider).logStartedIntent(
any(Intent.class),
anyInt());
verify(mActivity)
- .startActivityForResultAsUser(any(Intent.class), anyInt(), any(UserHandle.class));
+ .startActivityAsUser(any(Intent.class), any(UserHandle.class));
}
@Test
public void bindPreference_nullPreference_shouldIgnore() {
final Tile tile = mock(Tile.class);
- mImpl.bindPreferenceToTileAndGetObservers(mActivity, mForceRoundedIcon,
- MetricsEvent.VIEW_UNKNOWN, null, tile, "123", Preference.DEFAULT_ORDER);
+ mImpl.bindPreferenceToTileAndGetObservers(mActivity, mFragment, mForceRoundedIcon,
+ null /* keys */, tile, "123", Preference.DEFAULT_ORDER);
verifyZeroInteractions(tile);
}
@@ -273,8 +275,8 @@ public class DashboardFeatureProviderImplTest {
public void bindPreference_withNullKeyNullPriority_shouldGenerateKeyAndPriority() {
final Preference preference = new Preference(RuntimeEnvironment.application);
final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE);
- mImpl.bindPreferenceToTileAndGetObservers(mActivity, mForceRoundedIcon,
- MetricsEvent.VIEW_UNKNOWN, preference, tile, null /*key */,
+ mImpl.bindPreferenceToTileAndGetObservers(mActivity, mFragment, mForceRoundedIcon,
+ preference, tile, null /* key */,
Preference.DEFAULT_ORDER);
assertThat(preference.getKey()).isNotNull();
@@ -288,9 +290,8 @@ public class DashboardFeatureProviderImplTest {
final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE);
- mImpl.bindPreferenceToTileAndGetObservers(mActivity, mForceRoundedIcon,
- MetricsEvent.VIEW_UNKNOWN, preference, tile, null /*key */,
- Preference.DEFAULT_ORDER);
+ mImpl.bindPreferenceToTileAndGetObservers(mActivity, mFragment, mForceRoundedIcon,
+ preference, tile, null /* key */, Preference.DEFAULT_ORDER);
assertThat(preference.getSummary()).isNull();
}
@@ -304,8 +305,8 @@ public class DashboardFeatureProviderImplTest {
mActivityInfo.metaData.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY_URI, uriString);
final List observers = mImpl.bindPreferenceToTileAndGetObservers(
- mActivity, mForceRoundedIcon, MetricsEvent.VIEW_UNKNOWN, preference, tile,
- null /*key */, Preference.DEFAULT_ORDER);
+ mActivity, mFragment, mForceRoundedIcon, preference, tile, null /* key */,
+ Preference.DEFAULT_ORDER);
assertThat(preference.getSummary()).isEqualTo(ShadowTileUtils.MOCK_SUMMARY);
assertThat(observers.get(0).getUri().toString()).isEqualTo(uriString);
@@ -320,8 +321,8 @@ public class DashboardFeatureProviderImplTest {
mActivityInfo.metaData.putString(TileUtils.META_DATA_PREFERENCE_TITLE_URI, uriString);
final List observers = mImpl.bindPreferenceToTileAndGetObservers(
- mActivity, mForceRoundedIcon, MetricsEvent.VIEW_UNKNOWN, preference, tile,
- null /*key */, Preference.DEFAULT_ORDER);
+ mActivity, mFragment, mForceRoundedIcon, preference, tile, null /* key */,
+ Preference.DEFAULT_ORDER);
assertThat(preference.getTitle()).isEqualTo(ShadowTileUtils.MOCK_SUMMARY);
assertThat(observers.get(0).getUri().toString()).isEqualTo(uriString);
@@ -336,9 +337,8 @@ public class DashboardFeatureProviderImplTest {
final Bundle bundle = new Bundle();
bundle.putBoolean(EXTRA_SWITCH_SET_CHECKED_ERROR, false);
ShadowTileUtils.setResultBundle(bundle);
- mImpl.bindPreferenceToTileAndGetObservers(mActivity, mForceRoundedIcon,
- MetricsEvent.VIEW_UNKNOWN, preference, tile, null /*key */,
- Preference.DEFAULT_ORDER);
+ mImpl.bindPreferenceToTileAndGetObservers(mActivity, mFragment, mForceRoundedIcon,
+ preference, tile, null /* key */, Preference.DEFAULT_ORDER);
preference.callChangeListener(false);
@@ -358,9 +358,8 @@ public class DashboardFeatureProviderImplTest {
final Bundle bundle = new Bundle();
bundle.putBoolean(EXTRA_SWITCH_SET_CHECKED_ERROR, true);
ShadowTileUtils.setResultBundle(bundle);
- mImpl.bindPreferenceToTileAndGetObservers(mActivity, mForceRoundedIcon,
- MetricsEvent.VIEW_UNKNOWN, preference, tile, null /*key */,
- Preference.DEFAULT_ORDER);
+ mImpl.bindPreferenceToTileAndGetObservers(mActivity, mFragment, mForceRoundedIcon,
+ preference, tile, null /* key */, Preference.DEFAULT_ORDER);
preference.callChangeListener(true);
@@ -378,8 +377,8 @@ public class DashboardFeatureProviderImplTest {
final Tile tile = new ProviderTile(mProviderInfo, CategoryKey.CATEGORY_HOMEPAGE,
mSwitchMetaData);
final List observers = mImpl.bindPreferenceToTileAndGetObservers(
- mActivity, mForceRoundedIcon, MetricsEvent.VIEW_UNKNOWN, preference, tile,
- null /*key */, Preference.DEFAULT_ORDER);
+ mActivity, mFragment, mForceRoundedIcon, preference, tile, null /* key */,
+ Preference.DEFAULT_ORDER);
ShadowTileUtils.setProviderChecked(false);
observers.get(0).onDataChanged();
@@ -397,9 +396,8 @@ public class DashboardFeatureProviderImplTest {
final Preference preference = new Preference(RuntimeEnvironment.application);
mActivityInfo.metaData.putString(META_DATA_PREFERENCE_KEYHINT, "key");
final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE);
- mImpl.bindPreferenceToTileAndGetObservers(mActivity, mForceRoundedIcon,
- MetricsEvent.VIEW_UNKNOWN, preference, tile, null /* key */,
- Preference.DEFAULT_ORDER);
+ mImpl.bindPreferenceToTileAndGetObservers(mActivity, mFragment, mForceRoundedIcon,
+ preference, tile, null /* key */, Preference.DEFAULT_ORDER);
assertThat(preference.getKey()).isEqualTo(tile.getKey(mContext));
}
@@ -483,8 +481,8 @@ public class DashboardFeatureProviderImplTest {
mActivityInfo.metaData.putInt(META_DATA_KEY_ORDER, 10);
final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE);
- mImpl.bindPreferenceToTileAndGetObservers(mActivity, mForceRoundedIcon,
- MetricsEvent.VIEW_UNKNOWN, preference, tile, "123", baseOrder);
+ mImpl.bindPreferenceToTileAndGetObservers(mActivity, mFragment, mForceRoundedIcon,
+ preference, tile, "123", baseOrder);
assertThat(preference.getOrder()).isEqualTo(tile.getOrder() + baseOrder);
}
@@ -496,8 +494,8 @@ public class DashboardFeatureProviderImplTest {
mActivityInfo.metaData.putInt(META_DATA_KEY_ORDER, 10);
final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE);
mActivityInfo.metaData.putInt(META_DATA_KEY_ORDER, testOrder);
- mImpl.bindPreferenceToTileAndGetObservers(mActivity, mForceRoundedIcon,
- MetricsEvent.VIEW_UNKNOWN, preference, tile, "123", Preference.DEFAULT_ORDER);
+ mImpl.bindPreferenceToTileAndGetObservers(mActivity, mFragment, mForceRoundedIcon,
+ preference, tile, "123", Preference.DEFAULT_ORDER);
assertThat(preference.getOrder()).isEqualTo(testOrder);
}
@@ -508,8 +506,8 @@ public class DashboardFeatureProviderImplTest {
final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE);
mActivityInfo.metaData.putString(META_DATA_KEY_ORDER, "hello");
- mImpl.bindPreferenceToTileAndGetObservers(mActivity, mForceRoundedIcon,
- MetricsEvent.VIEW_UNKNOWN, preference, tile, "123", Preference.DEFAULT_ORDER);
+ mImpl.bindPreferenceToTileAndGetObservers(mActivity, mFragment, mForceRoundedIcon,
+ preference, tile, "123", Preference.DEFAULT_ORDER);
assertThat(preference.getOrder()).isEqualTo(Preference.DEFAULT_ORDER);
}
@@ -522,8 +520,8 @@ public class DashboardFeatureProviderImplTest {
mActivityInfo.metaData.putString(META_DATA_PREFERENCE_KEYHINT, "key");
mActivityInfo.metaData.putString("com.android.settings.intent.action", "TestAction");
tile.userHandle = null;
- mImpl.bindPreferenceToTileAndGetObservers(activity, mForceRoundedIcon,
- MetricsEvent.SETTINGS_GESTURES, preference, tile, "123", Preference.DEFAULT_ORDER);
+ mImpl.bindPreferenceToTileAndGetObservers(activity, mFragment, mForceRoundedIcon,
+ preference, tile, "123", Preference.DEFAULT_ORDER);
preference.performClick();
ShadowActivity shadowActivity = Shadows.shadowOf(activity);
@@ -546,8 +544,8 @@ public class DashboardFeatureProviderImplTest {
mActivityInfo.metaData.putString("com.android.settings.intent.action", "TestAction");
tile.userHandle = null;
- mImpl.bindPreferenceToTileAndGetObservers(activity, mForceRoundedIcon,
- MetricsEvent.SETTINGS_GESTURES, preference, tile, "123", Preference.DEFAULT_ORDER);
+ mImpl.bindPreferenceToTileAndGetObservers(activity, mFragment, mForceRoundedIcon,
+ preference, tile, "123", Preference.DEFAULT_ORDER);
preference.performClick();
final ShadowActivity.IntentForResult launchIntent =
@@ -568,7 +566,7 @@ public class DashboardFeatureProviderImplTest {
mImpl.openTileIntent(mActivity, tile);
verify(mActivity, never())
- .startActivityForResult(any(Intent.class), eq(0));
+ .startActivity(any(Intent.class));
verify(mActivity).getSupportFragmentManager();
}
@@ -585,7 +583,7 @@ public class DashboardFeatureProviderImplTest {
mImpl.openTileIntent(mActivity, tile);
verify(mActivity, never())
- .startActivityForResult(any(Intent.class), eq(0));
+ .startActivity(any(Intent.class));
verify(mActivity).getSupportFragmentManager();
}
@@ -602,7 +600,7 @@ public class DashboardFeatureProviderImplTest {
mImpl.openTileIntent(mActivity, tile);
verify(mActivity)
- .startActivityForResult(any(Intent.class), eq(0));
+ .startActivity(any(Intent.class));
verify(mActivity, never()).getSupportFragmentManager();
}
@@ -623,7 +621,7 @@ public class DashboardFeatureProviderImplTest {
final ArgumentCaptor argument = ArgumentCaptor.forClass(UserHandle.class);
verify(mActivity)
- .startActivityForResultAsUser(any(Intent.class), anyInt(), argument.capture());
+ .startActivityAsUser(any(Intent.class), argument.capture());
assertThat(argument.getValue().getIdentifier()).isEqualTo(userId);
verify(mActivity, never()).getSupportFragmentManager();
}
@@ -642,7 +640,7 @@ public class DashboardFeatureProviderImplTest {
mImpl.openTileIntent(mActivity, tile);
verify(mActivity, never())
- .startActivityForResultAsUser(any(Intent.class), anyInt(), any(UserHandle.class));
+ .startActivityAsUser(any(Intent.class), any(UserHandle.class));
verify(mActivity).getSupportFragmentManager();
}
@@ -665,8 +663,26 @@ public class DashboardFeatureProviderImplTest {
final ArgumentCaptor argument = ArgumentCaptor.forClass(UserHandle.class);
verify(mActivity)
- .startActivityForResultAsUser(any(Intent.class), anyInt(), argument.capture());
+ .startActivityAsUser(any(Intent.class), argument.capture());
assertThat(argument.getValue().getIdentifier()).isEqualTo(0);
verify(mActivity, never()).getSupportFragmentManager();
}
+
+ private static class TestFragment extends DashboardFragment {
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsEvent.SETTINGS_GESTURES;
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.gestures;
+ }
+
+ @Override
+ protected String getLogTag() {
+ return "TestFragment";
+ }
+ }
}
diff --git a/tests/robotests/src/com/android/settings/display/LockscreenClockPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/LockscreenClockPreferenceControllerTest.java
new file mode 100644
index 00000000000..94f2dc66555
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/display/LockscreenClockPreferenceControllerTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2021 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.display;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.provider.Settings;
+
+import androidx.preference.Preference;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class LockscreenClockPreferenceControllerTest {
+
+ private static final String TEST_KEY = "test_key";
+ private static final String SETTING_KEY = Settings.Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK;
+
+ private Context mContext;
+ private ContentResolver mContentResolver;
+ private LockscreenClockPreferenceController mController;
+
+ @Mock
+ private Preference mPreference;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = RuntimeEnvironment.application;
+ mContentResolver = mContext.getContentResolver();
+ mController = new LockscreenClockPreferenceController(mContext, TEST_KEY);
+ }
+
+ @Test
+ public void isChecked_SettingIs1_returnTrue() {
+ Settings.Secure.putInt(mContentResolver, SETTING_KEY, 1);
+
+ assertThat(mController.isChecked()).isTrue();
+ }
+
+ @Test
+ public void isChecked_SettingIs0_returnFalse() {
+ Settings.Secure.putInt(mContentResolver, SETTING_KEY, 0);
+
+ assertThat(mController.isChecked()).isFalse();
+ }
+
+ @Test
+ public void isChecked_SettingIsNotSet_returnTrue() {
+ Settings.Secure.putString(mContentResolver, SETTING_KEY, null);
+
+ assertThat(mController.isChecked()).isTrue();
+ }
+
+ @Test
+ public void setChecked_true_SettingIsNot0() {
+ mController.setChecked(true);
+
+ assertThat(Settings.Secure.getInt(mContentResolver, SETTING_KEY, 0)).isNotEqualTo(0);
+ }
+
+ @Test
+ public void setChecked_false_SettingIs0() {
+ mController.setChecked(false);
+
+ assertThat(Settings.Secure.getInt(mContentResolver, SETTING_KEY, 0)).isEqualTo(0);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/display/TopLevelWallpaperPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/TopLevelWallpaperPreferenceControllerTest.java
index 6ad99745748..62b34e26546 100644
--- a/tests/robotests/src/com/android/settings/display/TopLevelWallpaperPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/TopLevelWallpaperPreferenceControllerTest.java
@@ -29,6 +29,7 @@ import androidx.preference.Preference;
import com.android.settings.R;
import com.android.settings.testutils.shadow.SettingsShadowResources;
+import com.android.settings.testutils.shadow.ShadowActivityEmbeddingUtils;
import com.google.common.collect.Lists;
@@ -43,7 +44,7 @@ import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowPackageManager;
@RunWith(RobolectricTestRunner.class)
-@Config(shadows = {SettingsShadowResources.class})
+@Config(shadows = {SettingsShadowResources.class, ShadowActivityEmbeddingUtils.class})
public class TopLevelWallpaperPreferenceControllerTest {
private static final String TEST_KEY = "test_key";
@@ -204,18 +205,32 @@ public class TopLevelWallpaperPreferenceControllerTest {
}
@Test
- public void handlePreferenceTreeClick_launchClearTask() {
- mShadowPackageManager.setResolveInfosForIntent(
- mWallpaperIntent, Lists.newArrayList());
+ public void handlePreferenceTreeClick_embeddingActivityDisabled_launchWithTaskFlag() {
+ ShadowActivityEmbeddingUtils.setIsEmbeddingActivityEnabled(false);
mShadowPackageManager.setResolveInfosForIntent(
mStylesAndWallpaperIntent, Lists.newArrayList(mock(ResolveInfo.class)));
-
Preference preference = new Preference(mContext);
preference.setKey(TEST_KEY);
mController.handlePreferenceTreeClick(preference);
- assertThat((Shadows.shadowOf(mContext).getNextStartedActivityForResult()
- .intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_TASK) != 0).isTrue();
+ int flags = Shadows.shadowOf(mContext).getNextStartedActivityForResult().intent.getFlags();
+ assertThat((flags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0).isTrue();
+ assertThat((flags & Intent.FLAG_ACTIVITY_CLEAR_TASK) != 0).isTrue();
+ }
+
+ @Test
+ public void handlePreferenceTreeClick_embeddingActivityEnabled_launchWithoutTaskFlag() {
+ ShadowActivityEmbeddingUtils.setIsEmbeddingActivityEnabled(true);
+ mShadowPackageManager.setResolveInfosForIntent(
+ mStylesAndWallpaperIntent, Lists.newArrayList(mock(ResolveInfo.class)));
+ Preference preference = new Preference(mContext);
+ preference.setKey(TEST_KEY);
+
+ mController.handlePreferenceTreeClick(preference);
+
+ int flags = Shadows.shadowOf(mContext).getNextStartedActivityForResult().intent.getFlags();
+ assertThat((flags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0).isFalse();
+ assertThat((flags & Intent.FLAG_ACTIVITY_CLEAR_TASK) != 0).isFalse();
}
}
diff --git a/tests/robotests/src/com/android/settings/dream/StartNowPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/dream/StartNowPreferenceControllerTest.java
index 6c8a8f60cbd..98ba1ce2b31 100644
--- a/tests/robotests/src/com/android/settings/dream/StartNowPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/dream/StartNowPreferenceControllerTest.java
@@ -16,17 +16,18 @@
package com.android.settings.dream;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
+import android.widget.Button;
import androidx.preference.PreferenceScreen;
+import com.android.settings.R;
import com.android.settingslib.dream.DreamBackend;
-import com.android.settingslib.widget.MainSwitchPreference;
+import com.android.settingslib.widget.LayoutPreference;
import org.junit.Before;
import org.junit.Test;
@@ -46,7 +47,9 @@ public class StartNowPreferenceControllerTest {
@Mock
private PreferenceScreen mScreen;
@Mock
- private MainSwitchPreference mPref;
+ private LayoutPreference mLayoutPref;
+ @Mock
+ private Button mButton;
@Mock
private DreamBackend mBackend;
@@ -56,36 +59,29 @@ public class StartNowPreferenceControllerTest {
mContext = spy(RuntimeEnvironment.application);
mController = new StartNowPreferenceController(mContext, "key");
- mPref = mock(MainSwitchPreference.class);
- when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPref);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mLayoutPref);
+ when(mLayoutPref.findViewById(R.id.dream_start_now_button)).thenReturn(mButton);
ReflectionHelpers.setField(mController, "mBackend", mBackend);
}
@Test
- public void displayPreference_shouldAddOnSwitchChangeListener() {
- mController.displayPreference(mScreen);
-
- verify(mPref).addOnSwitchChangeListener(mController);
- }
-
- @Test
- public void updateState_neverDreaming_preferenceShouldDidabled() {
+ public void updateState_neverDreaming_buttonShouldDidabled() {
when(mBackend.getWhenToDreamSetting()).thenReturn(DreamBackend.NEVER);
mController.displayPreference(mScreen);
- mController.updateState(mPref);
+ mController.updateState(mLayoutPref);
- verify(mPref).setEnabled(false);
+ verify(mButton).setEnabled(false);
}
@Test
- public void updateState_dreamIsAvailable_preferenceShouldEnabled() {
+ public void updateState_dreamIsAvailable_buttonShouldEnabled() {
when(mBackend.getWhenToDreamSetting()).thenReturn(DreamBackend.EITHER);
mController.displayPreference(mScreen);
- mController.updateState(mPref);
+ mController.updateState(mLayoutPref);
- verify(mPref).setEnabled(true);
+ verify(mButton).setEnabled(true);
}
}
diff --git a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java
index e3cd5d201b8..e3f58f4e4af 100644
--- a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java
@@ -356,7 +356,7 @@ public class EnterprisePrivacyFeatureProviderImplTest {
addWorkPolicyInfoIntent(mOwner.getPackageName(), true, false);
assertThat(mProvider.hasWorkPolicyInfo()).isFalse();
- assertThat(mProvider.showWorkPolicyInfo()).isFalse();
+ assertThat(mProvider.showWorkPolicyInfo(mContext)).isFalse();
verify(mContext, never()).startActivity(any());
}
@@ -365,12 +365,12 @@ public class EnterprisePrivacyFeatureProviderImplTest {
// If the intent is not resolved, then there's no info to show for DO
when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn(mOwner);
assertThat(mProvider.hasWorkPolicyInfo()).isFalse();
- assertThat(mProvider.showWorkPolicyInfo()).isFalse();
+ assertThat(mProvider.showWorkPolicyInfo(mContext)).isFalse();
// If the intent is resolved, then we can use it to launch the activity
Intent intent = addWorkPolicyInfoIntent(mOwner.getPackageName(), true, false);
assertThat(mProvider.hasWorkPolicyInfo()).isTrue();
- assertThat(mProvider.showWorkPolicyInfo()).isTrue();
+ assertThat(mProvider.showWorkPolicyInfo(mContext)).isTrue();
verify(mContext).startActivity(intentEquals(intent));
}
@@ -382,12 +382,12 @@ public class EnterprisePrivacyFeatureProviderImplTest {
// If the intent is not resolved, then there's no info to show for PO
assertThat(mProvider.hasWorkPolicyInfo()).isFalse();
- assertThat(mProvider.showWorkPolicyInfo()).isFalse();
+ assertThat(mProvider.showWorkPolicyInfo(mContext)).isFalse();
// If the intent is resolved, then we can use it to launch the activity in managed profile
Intent intent = addWorkPolicyInfoIntent(mOwner.getPackageName(), false, true);
assertThat(mProvider.hasWorkPolicyInfo()).isTrue();
- assertThat(mProvider.showWorkPolicyInfo()).isTrue();
+ assertThat(mProvider.showWorkPolicyInfo(mContext)).isTrue();
verify(mContext)
.startActivityAsUser(
intentEquals(intent),
@@ -402,12 +402,12 @@ public class EnterprisePrivacyFeatureProviderImplTest {
// If the intent is not resolved, then there's no info to show for COMP
assertThat(mProvider.hasWorkPolicyInfo()).isFalse();
- assertThat(mProvider.showWorkPolicyInfo()).isFalse();
+ assertThat(mProvider.showWorkPolicyInfo(mContext)).isFalse();
// If the intent is resolved, then we can use it to launch the activity for device owner
Intent intent = addWorkPolicyInfoIntent(mOwner.getPackageName(), true, true);
assertThat(mProvider.hasWorkPolicyInfo()).isTrue();
- assertThat(mProvider.showWorkPolicyInfo()).isTrue();
+ assertThat(mProvider.showWorkPolicyInfo(mContext)).isTrue();
verify(mContext).startActivity(intentEquals(intent));
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
index b50e0832ec0..0a48cd1b12f 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
@@ -30,9 +30,11 @@ 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.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import android.app.AppOpsManager;
+import android.app.backup.BackupManager;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.Intent;
@@ -123,6 +125,9 @@ public class AdvancedPowerUsageDetailTest {
private BatteryUtils mBatteryUtils;
@Mock
private BatteryOptimizeUtils mBatteryOptimizeUtils;
+ @Mock
+ private BackupManager mBackupManager;
+
private Context mContext;
private Preference mForegroundPreference;
private Preference mBackgroundPreference;
@@ -180,9 +185,10 @@ public class AdvancedPowerUsageDetailTest {
mFragment.mHeaderPreference = mHeaderPreference;
mFragment.mState = mState;
- mFragment.enableTriState = true;
+ mFragment.mEnableTriState = true;
mFragment.mBatteryUtils = new BatteryUtils(RuntimeEnvironment.application);
mFragment.mBatteryOptimizeUtils = mBatteryOptimizeUtils;
+ mFragment.mBackupManager = mBackupManager;
mAppEntry.info = mock(ApplicationInfo.class);
mTestActivity = spy(new SettingsActivity());
@@ -231,7 +237,7 @@ public class AdvancedPowerUsageDetailTest {
@Test
public void testGetPreferenceScreenResId_disableTriState_returnLegacyLayout() {
- mFragment.enableTriState = false;
+ mFragment.mEnableTriState = false;
assertThat(mFragment.getPreferenceScreenResId()).isEqualTo(R.xml.power_usage_detail_legacy);
}
@@ -431,6 +437,21 @@ public class AdvancedPowerUsageDetailTest {
.isEqualTo("No usage for past 24 hr");
}
+ @Test
+ public void testInitHeader_noUsageTimeButConsumedPower_hasEmptySummary() {
+ Bundle bundle = new Bundle(3);
+ bundle.putLong(AdvancedPowerUsageDetail.EXTRA_BACKGROUND_TIME, /* value */ 0);
+ bundle.putLong(AdvancedPowerUsageDetail.EXTRA_FOREGROUND_TIME, /* value */ 0);
+ bundle.putInt(AdvancedPowerUsageDetail.EXTRA_POWER_USAGE_AMOUNT, /* value */ 10);
+ when(mFragment.getArguments()).thenReturn(bundle);
+
+ mFragment.initHeader();
+
+ ArgumentCaptor captor = ArgumentCaptor.forClass(CharSequence.class);
+ verify(mEntityHeaderController).setSummary(captor.capture());
+ assertThat(captor.getValue().toString()).isEmpty();
+ }
+
@Test
public void testInitHeader_backgroundTwoMinForegroundZero_hasCorrectSummary() {
final long backgroundTimeTwoMinutes = 120000;
@@ -771,13 +792,71 @@ public class AdvancedPowerUsageDetailTest {
assertThat(mOptimizePreference.isChecked()).isTrue();
assertThat(mRestrictedPreference.isChecked()).isFalse();
assertThat(mUnrestrictedPreference.isChecked()).isFalse();
+ }
+
+ @Test
+ public void testOnPause_optimizationModeChanged_logPreference() {
+ final int mode = BatteryOptimizeUtils.MODE_RESTRICTED;
+ mFragment.mOptimizationMode = mode;
+ when(mBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(mode);
+ mOptimizePreference.setKey(KEY_PREF_OPTIMIZED);
+
+ mFragment.onRadioButtonClicked(mOptimizePreference);
+ mFragment.onPause();
+
verify(mMetricsFeatureProvider)
- .action(
- mContext,
- SettingsEnums.ACTION_APP_BATTERY_USAGE_OPTIMIZED,
- (Pair[]) new Pair[] {
- new Pair(ConvertUtils.METRIC_KEY_PACKAGE, null),
- new Pair(ConvertUtils.METRIC_KEY_BATTERY_USAGE, "app label")
- });
+ .action(
+ SettingsEnums.OPEN_APP_BATTERY_USAGE,
+ SettingsEnums.ACTION_APP_BATTERY_USAGE_OPTIMIZED,
+ SettingsEnums.OPEN_APP_BATTERY_USAGE,
+ /* package name*/ "none",
+ /* consumed battery */ 0);
+ }
+
+ @Test
+ public void testOnPause_optimizationModeIsNotChanged_notInvokeLogging() {
+ final int mode = BatteryOptimizeUtils.MODE_OPTIMIZED;
+ mFragment.mOptimizationMode = mode;
+ when(mBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(mode);
+ mOptimizePreference.setKey(KEY_PREF_OPTIMIZED);
+
+ mFragment.onRadioButtonClicked(mOptimizePreference);
+ mFragment.onPause();
+
+ verifyZeroInteractions(mMetricsFeatureProvider);
+ }
+
+ @Test
+ public void notifyBackupManager_optimizationModeIsNotChanged_notInvokeDataChanged() {
+ final int mode = BatteryOptimizeUtils.MODE_RESTRICTED;
+ mFragment.mOptimizationMode = mode;
+ when(mBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(mode);
+
+ mFragment.notifyBackupManager();
+
+ verifyZeroInteractions(mBackupManager);
+ }
+
+ @Test
+ public void notifyBackupManager_optimizationModeIsChanged_invokeDataChanged() {
+ mFragment.mOptimizationMode = BatteryOptimizeUtils.MODE_RESTRICTED;
+ when(mBatteryOptimizeUtils.getAppOptimizationMode())
+ .thenReturn(BatteryOptimizeUtils.MODE_UNRESTRICTED);
+
+ mFragment.notifyBackupManager();
+
+ verify(mBackupManager).dataChanged();
+ }
+
+ @Test
+ public void notifyBackupManager_triStateIsNotEnabled_notInvokeDataChanged() {
+ mFragment.mOptimizationMode = BatteryOptimizeUtils.MODE_RESTRICTED;
+ when(mBatteryOptimizeUtils.getAppOptimizationMode())
+ .thenReturn(BatteryOptimizeUtils.MODE_UNRESTRICTED);
+ mFragment.mEnableTriState = false;
+
+ mFragment.onPause();
+
+ verifyZeroInteractions(mBackupManager);
}
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryAppListPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryAppListPreferenceControllerTest.java
index c3b3075612f..5e69b8fb05b 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryAppListPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryAppListPreferenceControllerTest.java
@@ -67,11 +67,13 @@ public class BatteryAppListPreferenceControllerTest {
private Context mContext;
private PowerGaugePreference mPreference;
private BatteryAppListPreferenceController mPreferenceController;
+ private FakeFeatureFactory mFeatureFactory;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
+ mFeatureFactory = FakeFeatureFactory.setupForTest();
mContext = spy(RuntimeEnvironment.application);
final Resources resources = spy(mContext.getResources());
when(mContext.getResources()).thenReturn(resources);
@@ -79,9 +81,8 @@ public class BatteryAppListPreferenceControllerTest {
when(mContext.getApplicationContext()).thenReturn(mContext);
when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager);
when(mUserManager.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[] {});
- when(resources.getTextArray(R.array.allowlist_hide_summary_in_battery_usage))
+ when(mFeatureFactory.powerUsageFeatureProvider.getHideApplicationSummary(mContext))
.thenReturn(new String[] {"com.android.googlequicksearchbox"});
- FakeFeatureFactory.setupForTest();
mPreference = new PowerGaugePreference(mContext);
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryBackupHelperTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryBackupHelperTest.java
new file mode 100644
index 00000000000..0f178e02ffe
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryBackupHelperTest.java
@@ -0,0 +1,407 @@
+/*
+ * Copyright (C) 2021 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.fuelgauge;
+
+import static com.android.settings.fuelgauge.BatteryBackupHelper.DELIMITER;
+import static com.android.settings.fuelgauge.BatteryBackupHelper.DELIMITER_MODE;
+import static com.android.settings.fuelgauge.BatteryOptimizeUtils.MODE_RESTRICTED;
+import static com.android.settings.fuelgauge.BatteryOptimizeUtils.MODE_UNRESTRICTED;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+import android.app.AppOpsManager;
+import android.app.backup.BackupDataInputStream;
+import android.app.backup.BackupDataOutput;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
+import android.content.pm.ParceledListSlice;
+import android.content.pm.UserInfo;
+import android.os.IDeviceIdleController;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.os.UserManager;
+
+import com.android.settingslib.fuelgauge.PowerAllowlistBackend;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.Resetter;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(shadows = {BatteryBackupHelperTest.ShadowUserHandle.class})
+public final class BatteryBackupHelperTest {
+ private static final String PACKAGE_NAME1 = "com.android.testing.1";
+ private static final String PACKAGE_NAME2 = "com.android.testing.2";
+ private static final String PACKAGE_NAME3 = "com.android.testing.3";
+
+ private Context mContext;
+ private BatteryBackupHelper mBatteryBackupHelper;
+
+ @Mock
+ private PackageManager mPackageManager;
+ @Mock
+ private BackupDataOutput mBackupDataOutput;
+ @Mock
+ private BackupDataInputStream mBackupDataInputStream;
+ @Mock
+ private IDeviceIdleController mDeviceController;
+ @Mock
+ private IPackageManager mIPackageManager;
+ @Mock
+ private AppOpsManager mAppOpsManager;
+ @Mock
+ private UserManager mUserManager;
+ @Mock
+ private PowerAllowlistBackend mPowerAllowlistBackend;
+ @Mock
+ private BatteryOptimizeUtils mBatteryOptimizeUtils;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ mContext = spy(RuntimeEnvironment.application);
+ doReturn(mContext).when(mContext).getApplicationContext();
+ doReturn(mAppOpsManager).when(mContext).getSystemService(AppOpsManager.class);
+ doReturn(mUserManager).when(mContext).getSystemService(UserManager.class);
+ doReturn(mPackageManager).when(mContext).getPackageManager();
+ mBatteryBackupHelper = new BatteryBackupHelper(mContext);
+ mBatteryBackupHelper.mIDeviceIdleController = mDeviceController;
+ mBatteryBackupHelper.mIPackageManager = mIPackageManager;
+ mBatteryBackupHelper.mPowerAllowlistBackend = mPowerAllowlistBackend;
+ mBatteryBackupHelper.mBatteryOptimizeUtils = mBatteryOptimizeUtils;
+ mockUid(1001 /*fake uid*/, PACKAGE_NAME1);
+ mockUid(1002 /*fake uid*/, PACKAGE_NAME2);
+ mockUid(BatteryUtils.UID_NULL, PACKAGE_NAME3);
+ }
+
+ @After
+ public void resetShadows() {
+ ShadowUserHandle.reset();
+ }
+
+ @Test
+ public void performBackup_nullPowerList_notBackupPowerList() throws Exception {
+ doReturn(null).when(mDeviceController).getFullPowerWhitelist();
+ mBatteryBackupHelper.performBackup(null, mBackupDataOutput, null);
+
+ verify(mBackupDataOutput, never()).writeEntityHeader(anyString(), anyInt());
+ }
+
+ @Test
+ public void performBackup_emptyPowerList_notBackupPowerList() throws Exception {
+ doReturn(new String[0]).when(mDeviceController).getFullPowerWhitelist();
+ mBatteryBackupHelper.performBackup(null, mBackupDataOutput, null);
+
+ verify(mBackupDataOutput, never()).writeEntityHeader(anyString(), anyInt());
+ }
+
+ @Test
+ public void performBackup_remoteException_notBackupPowerList() throws Exception {
+ doThrow(new RemoteException()).when(mDeviceController).getFullPowerWhitelist();
+ mBatteryBackupHelper.performBackup(null, mBackupDataOutput, null);
+
+ verify(mBackupDataOutput, never()).writeEntityHeader(anyString(), anyInt());
+ }
+
+ @Test
+ public void performBackup_oneFullPowerListElement_backupFullPowerListData()
+ throws Exception {
+ final String[] fullPowerList = {"com.android.package"};
+ doReturn(fullPowerList).when(mDeviceController).getFullPowerWhitelist();
+
+ mBatteryBackupHelper.performBackup(null, mBackupDataOutput, null);
+
+ final byte[] expectedBytes = fullPowerList[0].getBytes();
+ verify(mBackupDataOutput).writeEntityHeader(
+ BatteryBackupHelper.KEY_FULL_POWER_LIST, expectedBytes.length);
+ verify(mBackupDataOutput).writeEntityData(expectedBytes, expectedBytes.length);
+ }
+
+ @Test
+ public void performBackup_backupFullPowerListData() throws Exception {
+ final String[] fullPowerList = {"com.android.package1", "com.android.package2"};
+ doReturn(fullPowerList).when(mDeviceController).getFullPowerWhitelist();
+
+ mBatteryBackupHelper.performBackup(null, mBackupDataOutput, null);
+
+ final String expectedResult = fullPowerList[0] + DELIMITER + fullPowerList[1];
+ final byte[] expectedBytes = expectedResult.getBytes();
+ verify(mBackupDataOutput).writeEntityHeader(
+ BatteryBackupHelper.KEY_FULL_POWER_LIST, expectedBytes.length);
+ verify(mBackupDataOutput).writeEntityData(expectedBytes, expectedBytes.length);
+ }
+
+ @Test
+ public void performBackup_nonOwner_ignoreAllBackupAction() throws Exception {
+ ShadowUserHandle.setUid(1);
+ final String[] fullPowerList = {"com.android.package"};
+ doReturn(fullPowerList).when(mDeviceController).getFullPowerWhitelist();
+
+ mBatteryBackupHelper.performBackup(null, mBackupDataOutput, null);
+
+ verify(mBackupDataOutput, never()).writeEntityHeader(anyString(), anyInt());
+ }
+
+ @Test
+ public void backupOptimizationMode_nullInstalledApps_ignoreBackupOptimization()
+ throws Exception {
+ final UserInfo userInfo =
+ new UserInfo(/*userId=*/ 0, /*userName=*/ "google", /*flag=*/ 0);
+ doReturn(Arrays.asList(userInfo)).when(mUserManager).getProfiles(anyInt());
+ doThrow(new RuntimeException())
+ .when(mIPackageManager)
+ .getInstalledApplications(anyInt(), anyInt());
+
+ mBatteryBackupHelper.backupOptimizationMode(mBackupDataOutput, null);
+
+ verify(mBackupDataOutput, never()).writeEntityHeader(anyString(), anyInt());
+ }
+
+ @Test
+ public void backupOptimizationMode_backupOptimizationMode() throws Exception {
+ final List allowlistedApps = Arrays.asList(PACKAGE_NAME1);
+ createTestingData(PACKAGE_NAME1, PACKAGE_NAME2, PACKAGE_NAME3);
+
+ mBatteryBackupHelper.backupOptimizationMode(mBackupDataOutput, allowlistedApps);
+
+ // 2 for UNRESTRICTED mode and 1 for RESTRICTED mode.
+ final String expectedResult = PACKAGE_NAME1 + ":2," + PACKAGE_NAME2 + ":1,";
+ verifyBackupData(expectedResult);
+ }
+
+ @Test
+ public void backupOptimizationMode_backupOptimizationModeAndIgnoreSystemApp()
+ throws Exception {
+ final List allowlistedApps = Arrays.asList(PACKAGE_NAME1);
+ createTestingData(PACKAGE_NAME1, PACKAGE_NAME2, PACKAGE_NAME3);
+ // Sets "com.android.testing.1" as system app.
+ doReturn(true).when(mPowerAllowlistBackend).isSysAllowlisted(PACKAGE_NAME1);
+ doReturn(false).when(mPowerAllowlistBackend).isDefaultActiveApp(anyString());
+
+ mBatteryBackupHelper.backupOptimizationMode(mBackupDataOutput, allowlistedApps);
+
+ // "com.android.testing.2" for RESTRICTED mode.
+ final String expectedResult = PACKAGE_NAME2 + ":1,";
+ verifyBackupData(expectedResult);
+ }
+
+ @Test
+ public void backupOptimizationMode_backupOptimizationModeAndIgnoreDefaultApp()
+ throws Exception {
+ final List allowlistedApps = Arrays.asList(PACKAGE_NAME1);
+ createTestingData(PACKAGE_NAME1, PACKAGE_NAME2, PACKAGE_NAME3);
+ // Sets "com.android.testing.1" as device default app.
+ doReturn(true).when(mPowerAllowlistBackend).isDefaultActiveApp(PACKAGE_NAME1);
+ doReturn(false).when(mPowerAllowlistBackend).isSysAllowlisted(anyString());
+
+ mBatteryBackupHelper.backupOptimizationMode(mBackupDataOutput, allowlistedApps);
+
+ // "com.android.testing.2" for RESTRICTED mode.
+ final String expectedResult = PACKAGE_NAME2 + ":1,";
+ verifyBackupData(expectedResult);
+ }
+
+ @Test
+ public void restoreEntity_nonOwner_notReadBackupData() throws Exception {
+ ShadowUserHandle.setUid(1);
+ mockBackupData(30 /*dataSize*/, BatteryBackupHelper.KEY_OPTIMIZATION_LIST);
+
+ mBatteryBackupHelper.restoreEntity(mBackupDataInputStream);
+
+ verifyZeroInteractions(mBackupDataInputStream);
+ }
+
+ @Test
+ public void restoreEntity_zeroDataSize_notReadBackupData() throws Exception {
+ final int zeroDataSize = 0;
+ mockBackupData(zeroDataSize, BatteryBackupHelper.KEY_OPTIMIZATION_LIST);
+
+ mBatteryBackupHelper.restoreEntity(mBackupDataInputStream);
+
+ verify(mBackupDataInputStream, never()).read(any(), anyInt(), anyInt());
+ }
+
+ @Test
+ public void restoreEntity_incorrectDataKey_notReadBackupData() throws Exception {
+ final String incorrectDataKey = BatteryBackupHelper.KEY_FULL_POWER_LIST;
+ mockBackupData(30 /*dataSize*/, incorrectDataKey);
+
+ mBatteryBackupHelper.restoreEntity(mBackupDataInputStream);
+
+ verify(mBackupDataInputStream, never()).read(any(), anyInt(), anyInt());
+ }
+
+ @Test
+ public void restoreEntity_readExpectedDataFromBackupData() throws Exception {
+ final int dataSize = 30;
+ mockBackupData(dataSize, BatteryBackupHelper.KEY_OPTIMIZATION_LIST);
+
+ mBatteryBackupHelper.restoreEntity(mBackupDataInputStream);
+
+ final ArgumentCaptor captor = ArgumentCaptor.forClass(byte[].class);
+ verify(mBackupDataInputStream).read(captor.capture(), eq(0), eq(dataSize));
+ assertThat(captor.getValue().length).isEqualTo(dataSize);
+ }
+
+ @Test
+ public void restoreOptimizationMode_nullBytesData_skipRestore() throws Exception {
+ mBatteryBackupHelper.restoreOptimizationMode(new byte[0]);
+ verifyZeroInteractions(mBatteryOptimizeUtils);
+
+ mBatteryBackupHelper.restoreOptimizationMode("invalid data format".getBytes());
+ verifyZeroInteractions(mBatteryOptimizeUtils);
+
+ mBatteryBackupHelper.restoreOptimizationMode(DELIMITER.getBytes());
+ verifyZeroInteractions(mBatteryOptimizeUtils);
+ }
+
+ @Test
+ public void restoreOptimizationMode_invalidModeFormat_skipRestore() throws Exception {
+ final String invalidNumberFormat = "google";
+ final String packageModes =
+ PACKAGE_NAME1 + DELIMITER_MODE + MODE_RESTRICTED + DELIMITER +
+ PACKAGE_NAME2 + DELIMITER_MODE + invalidNumberFormat;
+
+ mBatteryBackupHelper.restoreOptimizationMode(packageModes.getBytes());
+ TimeUnit.SECONDS.sleep(1);
+
+ final InOrder inOrder = inOrder(mBatteryOptimizeUtils);
+ inOrder.verify(mBatteryOptimizeUtils).setAppUsageState(MODE_RESTRICTED);
+ inOrder.verify(mBatteryOptimizeUtils, never()).setAppUsageState(anyInt());
+ }
+
+ @Test
+ public void restoreOptimizationMode_restoreExpectedModes() throws Exception {
+ final String packageModes =
+ PACKAGE_NAME1 + DELIMITER_MODE + MODE_RESTRICTED + DELIMITER +
+ PACKAGE_NAME2 + DELIMITER_MODE + MODE_UNRESTRICTED + DELIMITER +
+ PACKAGE_NAME3 + DELIMITER_MODE + MODE_RESTRICTED + DELIMITER;
+
+ mBatteryBackupHelper.restoreOptimizationMode(packageModes.getBytes());
+ TimeUnit.SECONDS.sleep(1);
+
+ final InOrder inOrder = inOrder(mBatteryOptimizeUtils);
+ inOrder.verify(mBatteryOptimizeUtils).setAppUsageState(MODE_RESTRICTED);
+ inOrder.verify(mBatteryOptimizeUtils).setAppUsageState(MODE_UNRESTRICTED);
+ inOrder.verify(mBatteryOptimizeUtils, never()).setAppUsageState(MODE_RESTRICTED);
+ }
+
+ private void mockUid(int uid, String packageName) throws Exception {
+ doReturn(uid).when(mPackageManager)
+ .getPackageUid(packageName, PackageManager.GET_META_DATA);
+ }
+
+ private void mockBackupData(int dataSize, String dataKey) {
+ doReturn(dataSize).when(mBackupDataInputStream).size();
+ doReturn(dataKey).when(mBackupDataInputStream).getKey();
+ }
+
+ private void verifyBackupData(String expectedResult) throws Exception {
+ final byte[] expectedBytes = expectedResult.getBytes();
+ verify(mBackupDataOutput).writeEntityHeader(
+ BatteryBackupHelper.KEY_OPTIMIZATION_LIST, expectedBytes.length);
+ verify(mBackupDataOutput).writeEntityData(expectedBytes, expectedBytes.length);
+ }
+
+ private void createTestingData(
+ String packageName1, String packageName2, String packageName3) throws Exception {
+ // Sets the getInstalledApplications() method for testing.
+ final UserInfo userInfo =
+ new UserInfo(/*userId=*/ 0, /*userName=*/ "google", /*flag=*/ 0);
+ doReturn(Arrays.asList(userInfo)).when(mUserManager).getProfiles(anyInt());
+ final ApplicationInfo applicationInfo1 = new ApplicationInfo();
+ applicationInfo1.enabled = true;
+ applicationInfo1.uid = 1;
+ applicationInfo1.packageName = packageName1;
+ final ApplicationInfo applicationInfo2 = new ApplicationInfo();
+ applicationInfo2.enabled = false;
+ applicationInfo2.uid = 2;
+ applicationInfo2.packageName = packageName2;
+ applicationInfo2.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
+ final ApplicationInfo applicationInfo3 = new ApplicationInfo();
+ applicationInfo3.enabled = false;
+ applicationInfo3.uid = 3;
+ applicationInfo3.packageName = packageName3;
+ applicationInfo3.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
+ doReturn(new ParceledListSlice(
+ Arrays.asList(applicationInfo1, applicationInfo2, applicationInfo3)))
+ .when(mIPackageManager)
+ .getInstalledApplications(anyInt(), anyInt());
+ // Sets the AppOpsManager for checkOpNoThrow() method.
+ doReturn(AppOpsManager.MODE_ALLOWED)
+ .when(mAppOpsManager)
+ .checkOpNoThrow(
+ AppOpsManager.OP_RUN_ANY_IN_BACKGROUND,
+ applicationInfo1.uid,
+ applicationInfo1.packageName);
+ doReturn(AppOpsManager.MODE_IGNORED)
+ .when(mAppOpsManager)
+ .checkOpNoThrow(
+ AppOpsManager.OP_RUN_ANY_IN_BACKGROUND,
+ applicationInfo2.uid,
+ applicationInfo2.packageName);
+ }
+
+ @Implements(UserHandle.class)
+ public static class ShadowUserHandle {
+ // Sets the default as thte OWNER role.
+ private static int sUid = 0;
+
+ public static void setUid(int uid) {
+ sUid = uid;
+ }
+
+ @Implementation
+ public static int myUserId() {
+ return sUid;
+ }
+
+ @Resetter
+ public static void reset() {
+ sUid = 0;
+ }
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryChartPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryChartPreferenceControllerTest.java
index 43fbe81a3a1..1d74491a0e1 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryChartPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryChartPreferenceControllerTest.java
@@ -103,7 +103,11 @@ public final class BatteryChartPreferenceControllerTest {
resources.getConfiguration().setLocales(new LocaleList(new Locale("en_US")));
doReturn(resources).when(mContext).getResources();
doReturn(new String[] {"com.android.googlequicksearchbox"})
- .when(resources).getTextArray(R.array.allowlist_hide_summary_in_battery_usage);
+ .when(mFeatureFactory.powerUsageFeatureProvider)
+ .getHideApplicationSummary(mContext);
+ doReturn(new String[] {"com.android.gms.persistent"})
+ .when(mFeatureFactory.powerUsageFeatureProvider)
+ .getHideApplicationEntries(mContext);
mBatteryChartPreferenceController = createController();
mBatteryChartPreferenceController.mPrefContext = mContext;
mBatteryChartPreferenceController.mAppListPrefGroup = mAppListGroup;
@@ -339,14 +343,12 @@ public final class BatteryChartPreferenceControllerTest {
assertThat(mBatteryChartPreferenceController.handlePreferenceTreeClick(
mPowerGaugePreference)).isTrue();
verify(mMetricsFeatureProvider)
- .action(
- mContext,
- SettingsEnums.ACTION_BATTERY_USAGE_SYSTEM_ITEM,
- (Pair[]) new Pair[] {
- new Pair(ConvertUtils.METRIC_KEY_PACKAGE, null),
- new Pair(ConvertUtils.METRIC_KEY_BATTERY_LEVEL, 0),
- new Pair(ConvertUtils.METRIC_KEY_BATTERY_USAGE, null)
- });
+ .action(
+ SettingsEnums.OPEN_BATTERY_USAGE,
+ SettingsEnums.ACTION_BATTERY_USAGE_SYSTEM_ITEM,
+ SettingsEnums.OPEN_BATTERY_USAGE,
+ /* package name */ "none",
+ /* percentage of total */ 0);
}
@Test
@@ -358,14 +360,12 @@ public final class BatteryChartPreferenceControllerTest {
assertThat(mBatteryChartPreferenceController.handlePreferenceTreeClick(
mPowerGaugePreference)).isTrue();
verify(mMetricsFeatureProvider)
- .action(
- mContext,
- SettingsEnums.ACTION_BATTERY_USAGE_APP_ITEM,
- (Pair[]) new Pair[] {
- new Pair(ConvertUtils.METRIC_KEY_PACKAGE, null),
- new Pair(ConvertUtils.METRIC_KEY_BATTERY_LEVEL, 0),
- new Pair(ConvertUtils.METRIC_KEY_BATTERY_USAGE, null)
- });
+ .action(
+ SettingsEnums.OPEN_BATTERY_USAGE,
+ SettingsEnums.ACTION_BATTERY_USAGE_APP_ITEM,
+ SettingsEnums.OPEN_BATTERY_USAGE,
+ /* package name */ "none",
+ /* percentage of total */ 0);
}
@Test
@@ -660,7 +660,7 @@ public final class BatteryChartPreferenceControllerTest {
// Verifies the items which are defined in the array list.
assertThat(mBatteryChartPreferenceController
- .isValidToShowEntry("com.google.android.gms.persistent"))
+ .isValidToShowEntry("com.android.gms.persistent"))
.isFalse();
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryDiffEntryTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryDiffEntryTest.java
index 85ac9413041..b1d8f0d5a6d 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryDiffEntryTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryDiffEntryTest.java
@@ -17,6 +17,7 @@ package com.android.settings.fuelgauge;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.doReturn;
@@ -28,6 +29,7 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Drawable.ConstantState;
import android.os.BatteryConsumer;
import android.os.UserHandle;
import android.os.UserManager;
@@ -41,6 +43,10 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.Resetter;
import java.util.ArrayList;
import java.util.Collections;
@@ -48,6 +54,7 @@ import java.util.List;
import java.util.Locale;
@RunWith(RobolectricTestRunner.class)
+@Config(shadows = {BatteryDiffEntryTest.ShadowUserHandle.class})
public final class BatteryDiffEntryTest {
private Context mContext;
@@ -60,10 +67,12 @@ public final class BatteryDiffEntryTest {
@Mock private Drawable mockBadgedDrawable;
@Mock private BatteryHistEntry mBatteryHistEntry;
@Mock private PackageInfo mockPackageInfo;
+ @Mock private ConstantState mockConstantState;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
+ ShadowUserHandle.reset();
mContext = spy(RuntimeEnvironment.application);
doReturn(mContext).when(mContext).getApplicationContext();
doReturn(mockUserManager).when(mContext).getSystemService(UserManager.class);
@@ -229,6 +238,7 @@ public final class BatteryDiffEntryTest {
final ContentValues values = getContentValuesWithType(
ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY);
final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
+ mockConstantState(mockDrawable);
final BatteryDiffEntry entry = createBatteryDiffEntry(10, batteryHistEntry);
@@ -239,20 +249,32 @@ public final class BatteryDiffEntryTest {
}
@Test
- public void testGetAppIcon_uidConsumerWithNullIcon_returnDefaultActivityIcon()
+ public void testGetAppIcon_uidConsumerForNonOwner_returnDefaultActivityIconWithBadge()
throws Exception {
+ ShadowUserHandle.setUid(10);
final BatteryDiffEntry entry = createBatteryDiffEntry(mockDrawable);
- final int userId = UserHandle.getUserId(1001);
+ mockConstantState(mockDrawable);
+ mockConstantState(mockBadgedDrawable);
doReturn(mockBadgedDrawable).when(mockUserManager)
- .getBadgedIconForUser(mockDrawable, new UserHandle(userId));
+ .getBadgedIconForUser(eq(mockDrawable), any());
entry.mAppIcon = null;
assertThat(entry.getAppIcon()).isEqualTo(mockBadgedDrawable);
+ }
+
+ @Test
+ public void testGetAppIcon_uidConsumerWithNullIcon_returnDefaultActivityIcon()
+ throws Exception {
+ final BatteryDiffEntry entry = createBatteryDiffEntry(mockDrawable);
+ mockConstantState(mockDrawable);
+
+ entry.mAppIcon = null;
+ assertThat(entry.getAppIcon()).isEqualTo(mockDrawable);
assertThat(BatteryDiffEntry.sResourceCache).hasSize(1);
// Verifies the app label in the cache.
final BatteryEntry.NameAndIcon nameAndIcon =
BatteryDiffEntry.sResourceCache.get(entry.getKey());
- assertThat(nameAndIcon.icon).isEqualTo(mockBadgedDrawable);
+ assertThat(nameAndIcon.icon).isEqualTo(mockDrawable);
}
@Test
@@ -272,19 +294,17 @@ public final class BatteryDiffEntryTest {
@Test
public void testClearCache_switchLocale_clearCacheIconAndLabel() throws Exception {
final int userId = UserHandle.getUserId(1001);
- doReturn(mockBadgedDrawable).when(mockUserManager)
- .getBadgedIconForUser(mockDrawable, new UserHandle(userId));
- doReturn(mockDrawable2).when(mockUserManager)
- .getBadgedIconForUser(mockDrawable2, new UserHandle(userId));
Locale.setDefault(new Locale("en_US"));
final BatteryDiffEntry entry1 = createBatteryDiffEntry(mockDrawable);
- assertThat(entry1.getAppIcon()).isEqualTo(mockBadgedDrawable);
+ mockConstantState(mockDrawable);
+ assertThat(entry1.getAppIcon()).isEqualTo(mockDrawable);
// Switch the locale into another one.
Locale.setDefault(new Locale("zh_TW"));
final BatteryDiffEntry entry2 = createBatteryDiffEntry(mockDrawable2);
// We should get new drawable without caching.
+ mockConstantState(mockDrawable2);
assertThat(entry2.getAppIcon()).isEqualTo(mockDrawable2);
// Verifies the cache is updated into the new drawable.
final BatteryEntry.NameAndIcon nameAndIcon =
@@ -440,4 +460,34 @@ public final class BatteryDiffEntryTest {
.getPackagesForUid(1001);
return createBatteryDiffEntry(10, batteryHistEntry);
}
+
+ private void mockConstantState(Drawable drawable) {
+ doReturn(mockConstantState).when(drawable).getConstantState();
+ doReturn(drawable).when(mockConstantState).newDrawable();
+ }
+
+ @Implements(UserHandle.class)
+ public static class ShadowUserHandle {
+ // Sets the default as thte OWNER role.
+ private static int sUid = 0;
+
+ public static void setUid(int uid) {
+ sUid = uid;
+ }
+
+ @Implementation
+ public static int myUserId() {
+ return sUid;
+ }
+
+ @Implementation
+ public static int getUserId(int userId) {
+ return sUid;
+ }
+
+ @Resetter
+ public static void reset() {
+ sUid = 0;
+ }
+ }
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryOptimizeUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryOptimizeUtilsTest.java
index 89d66be187b..c154f426b30 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryOptimizeUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryOptimizeUtilsTest.java
@@ -16,9 +16,9 @@
package com.android.settings.fuelgauge;
-import static com.android.settings.fuelgauge.BatteryOptimizeUtils.AppUsageState.OPTIMIZED;
-import static com.android.settings.fuelgauge.BatteryOptimizeUtils.AppUsageState.RESTRICTED;
-import static com.android.settings.fuelgauge.BatteryOptimizeUtils.AppUsageState.UNRESTRICTED;
+import static com.android.settings.fuelgauge.BatteryOptimizeUtils.MODE_OPTIMIZED;
+import static com.android.settings.fuelgauge.BatteryOptimizeUtils.MODE_RESTRICTED;
+import static com.android.settings.fuelgauge.BatteryOptimizeUtils.MODE_UNRESTRICTED;
import static com.google.common.truth.Truth.assertThat;
@@ -26,6 +26,7 @@ import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import android.app.AppOpsManager;
@@ -41,15 +42,17 @@ import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
+import java.util.concurrent.TimeUnit;
+
@RunWith(RobolectricTestRunner.class)
public class BatteryOptimizeUtilsTest {
private static final int UID = 12345;
private static final String PACKAGE_NAME = "com.android.app";
- @Mock BatteryUtils mockBatteryUtils;
- @Mock AppOpsManager mockAppOpsManager;
- @Mock PowerAllowlistBackend mockBackend;
+ @Mock BatteryUtils mMockBatteryUtils;
+ @Mock AppOpsManager mMockAppOpsManager;
+ @Mock PowerAllowlistBackend mMockBackend;
private Context mContext;
private BatteryOptimizeUtils mBatteryOptimizeUtils;
@@ -59,42 +62,48 @@ public class BatteryOptimizeUtilsTest {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
mBatteryOptimizeUtils = spy(new BatteryOptimizeUtils(mContext, UID, PACKAGE_NAME));
- mBatteryOptimizeUtils.mAppOpsManager = mockAppOpsManager;
- mBatteryOptimizeUtils.mBatteryUtils = mockBatteryUtils;
- mBatteryOptimizeUtils.mPowerAllowListBackend = mockBackend;
+ mBatteryOptimizeUtils.mAppOpsManager = mMockAppOpsManager;
+ mBatteryOptimizeUtils.mBatteryUtils = mMockBatteryUtils;
+ mBatteryOptimizeUtils.mPowerAllowListBackend = mMockBackend;
+ // Sets the default mode as MODE_RESTRICTED.
+ mBatteryOptimizeUtils.mMode = AppOpsManager.MODE_IGNORED;
+ mBatteryOptimizeUtils.mAllowListed = false;
}
@Test
- public void testGetAppUsageState_returnRestricted() {
- when(mockBackend.isAllowlisted(anyString())).thenReturn(false);
- when(mockAppOpsManager.checkOpNoThrow(anyInt(), anyInt(), anyString()))
+ public void testGetAppOptimizationMode_returnRestricted() {
+ when(mMockBackend.isAllowlisted(anyString())).thenReturn(false);
+ when(mMockAppOpsManager.checkOpNoThrow(anyInt(), anyInt(), anyString()))
.thenReturn(AppOpsManager.MODE_IGNORED);
- assertThat(mBatteryOptimizeUtils.getAppUsageState()).isEqualTo(RESTRICTED);
+ assertThat(mBatteryOptimizeUtils.getAppOptimizationMode())
+ .isEqualTo(MODE_RESTRICTED);
}
@Test
- public void testGetAppUsageState_returnUnrestricted() {
- when(mockBackend.isAllowlisted(anyString())).thenReturn(true);
- when(mockAppOpsManager.checkOpNoThrow(anyInt(), anyInt(), anyString()))
+ public void testGetAppOptimizationMode_returnUnrestricted() {
+ when(mMockBackend.isAllowlisted(anyString())).thenReturn(true);
+ when(mMockAppOpsManager.checkOpNoThrow(anyInt(), anyInt(), anyString()))
.thenReturn(AppOpsManager.MODE_ALLOWED);
- assertThat(mBatteryOptimizeUtils.getAppUsageState()).isEqualTo(UNRESTRICTED);
+ assertThat(mBatteryOptimizeUtils.getAppOptimizationMode())
+ .isEqualTo(MODE_UNRESTRICTED);
}
@Test
- public void testGetAppUsageState_returnOptimized() {
- when(mockBackend.isAllowlisted(anyString())).thenReturn(false);
- when(mockAppOpsManager.checkOpNoThrow(anyInt(), anyInt(), anyString()))
+ public void testGetAppOptimizationMode_returnOptimized() {
+ when(mMockBackend.isAllowlisted(anyString())).thenReturn(false);
+ when(mMockAppOpsManager.checkOpNoThrow(anyInt(), anyInt(), anyString()))
.thenReturn(AppOpsManager.MODE_ALLOWED);
- assertThat(mBatteryOptimizeUtils.getAppUsageState()).isEqualTo(OPTIMIZED);
+ assertThat(mBatteryOptimizeUtils.getAppOptimizationMode())
+ .isEqualTo(MODE_OPTIMIZED);
}
@Test
public void testIsSystemOrDefaultApp_isSystemOrDefaultApp_returnTrue() {
- when(mockBackend.isAllowlisted(anyString())).thenReturn(true);
- when(mockBackend.isDefaultActiveApp(anyString())).thenReturn(true);
+ when(mMockBackend.isAllowlisted(anyString())).thenReturn(true);
+ when(mMockBackend.isDefaultActiveApp(anyString())).thenReturn(true);
assertThat(mBatteryOptimizeUtils.isSystemOrDefaultApp()).isTrue();
}
@@ -118,29 +127,49 @@ public class BatteryOptimizeUtilsTest {
}
@Test
- public void testSetAppUsageState_Restricted_verifyAction() {
- mBatteryOptimizeUtils.setAppUsageState(RESTRICTED);
+ public void testSetAppUsageState_Restricted_verifyAction() throws Exception {
+ // Sets the current mode as MODE_UNRESTRICTED.
+ mBatteryOptimizeUtils.mAllowListed = false;
+ mBatteryOptimizeUtils.mMode = AppOpsManager.MODE_ALLOWED;
- verify(mockBatteryUtils).setForceAppStandby(UID,
+ mBatteryOptimizeUtils.setAppUsageState(MODE_RESTRICTED);
+ TimeUnit.SECONDS.sleep(1);
+
+ verify(mMockBatteryUtils).setForceAppStandby(UID,
PACKAGE_NAME, AppOpsManager.MODE_IGNORED);
- verify(mockBackend).removeApp(PACKAGE_NAME);
+ verify(mMockBackend).removeApp(PACKAGE_NAME);
}
@Test
- public void testSetAppUsageState_Unrestricted_verifyAction() {
- mBatteryOptimizeUtils.setAppUsageState(UNRESTRICTED);
+ public void testSetAppUsageState_Unrestricted_verifyAction() throws Exception {
+ mBatteryOptimizeUtils.setAppUsageState(MODE_UNRESTRICTED);
+ TimeUnit.SECONDS.sleep(1);
- verify(mockBatteryUtils).setForceAppStandby(UID,
+ verify(mMockBatteryUtils).setForceAppStandby(UID,
PACKAGE_NAME, AppOpsManager.MODE_ALLOWED);
- verify(mockBackend).addApp(PACKAGE_NAME);
+ verify(mMockBackend).addApp(PACKAGE_NAME);
}
@Test
- public void testSetAppUsageState_Optimized_verifyAction() {
- mBatteryOptimizeUtils.setAppUsageState(OPTIMIZED);
+ public void testSetAppUsageState_Optimized_verifyAction() throws Exception {
+ mBatteryOptimizeUtils.setAppUsageState(MODE_OPTIMIZED);
+ TimeUnit.SECONDS.sleep(1);
- verify(mockBatteryUtils).setForceAppStandby(UID,
+ verify(mMockBatteryUtils).setForceAppStandby(UID,
PACKAGE_NAME, AppOpsManager.MODE_ALLOWED);
- verify(mockBackend).removeApp(PACKAGE_NAME);
+ verify(mMockBackend).removeApp(PACKAGE_NAME);
+ }
+
+ @Test
+ public void testSetAppUsageState_sameUnrestrictedMode_verifyNoAction() throws Exception {
+ // Sets the current mode as MODE_UNRESTRICTED.
+ mBatteryOptimizeUtils.mAllowListed = true;
+ mBatteryOptimizeUtils.mMode = AppOpsManager.MODE_ALLOWED;
+
+ mBatteryOptimizeUtils.setAppUsageState(MODE_UNRESTRICTED);
+ TimeUnit.SECONDS.sleep(1);
+
+ verifyZeroInteractions(mMockBackend);
+ verifyZeroInteractions(mMockBatteryUtils);
}
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatterySaverControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatterySaverControllerTest.java
index cee11603d43..ddb9860838e 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatterySaverControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatterySaverControllerTest.java
@@ -29,9 +29,6 @@ import android.util.Pair;
import androidx.preference.Preference;
-import com.android.settings.testutils.FakeFeatureFactory;
-import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
-
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -51,16 +48,12 @@ public class BatterySaverControllerTest {
private BatterySaverController mBatterySaverController;
private Context mContext;
- private FakeFeatureFactory mFeatureFactory;
- private MetricsFeatureProvider mMetricsFeatureProvider;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
- mFeatureFactory = FakeFeatureFactory.setupForTest();
- mMetricsFeatureProvider = mFeatureFactory.metricsFeatureProvider;
mBatterySaverController = spy(new BatterySaverController(mContext));
ReflectionHelpers.setField(mBatterySaverController, "mPowerManager", mPowerManager);
ReflectionHelpers.setField(mBatterySaverController, "mBatterySaverPref", mBatterySaverPref);
@@ -81,49 +74,6 @@ public class BatterySaverControllerTest {
verify(mBatterySaverPref).setSummary("Off");
}
- @Test
- public void onPreferenceChange_onPowerSaveModeChanged_manualTrigger_logsType() {
- when(mPowerManager.isPowerSaveMode()).thenReturn(true);
- Settings.Global.putInt(mContext.getContentResolver(),
- Settings.Global.AUTOMATIC_POWER_SAVE_MODE, -1);
-
- mBatterySaverController.onPowerSaveModeChanged();
- verify(mMetricsFeatureProvider).action(mContext, SettingsEnums.FUELGAUGE_BATTERY_SAVER,
- Pair.create(SettingsEnums.FIELD_BATTERY_SAVER_SCHEDULE_TYPE,
- SettingsEnums.BATTERY_SAVER_SCHEDULE_TYPE_NO_SCHEDULE));
- }
-
- @Test
- public void onPreferenceChange_onPowerSaveModeChanged_triggerPercent_logsTypeAndPercentage() {
- when(mPowerManager.isPowerSaveMode()).thenReturn(true);
- Settings.Global.putInt(mContext.getContentResolver(),
- Settings.Global.AUTOMATIC_POWER_SAVE_MODE,
- PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
- final int percentageVal = 15;
- Settings.Global.putInt(mContext.getContentResolver(),
- Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, percentageVal);
-
- mBatterySaverController.onPowerSaveModeChanged();
- verify(mMetricsFeatureProvider).action(mContext, SettingsEnums.FUELGAUGE_BATTERY_SAVER,
- Pair.create(SettingsEnums.FIELD_BATTERY_SAVER_SCHEDULE_TYPE,
- SettingsEnums.BATTERY_SAVER_SCHEDULE_TYPE_BASED_ON_PERCENTAGE),
- Pair.create(SettingsEnums.FIELD_BATTERY_SAVER_PERCENTAGE_VALUE,
- percentageVal));
- }
-
- @Test
- public void onPreferenceChange_onPowerSaveModeChanged_triggerDynamic_logsType() {
- when(mPowerManager.isPowerSaveMode()).thenReturn(true);
- Settings.Global.putInt(mContext.getContentResolver(),
- Settings.Global.AUTOMATIC_POWER_SAVE_MODE,
- PowerManager.POWER_SAVE_MODE_TRIGGER_DYNAMIC);
-
- mBatterySaverController.onPowerSaveModeChanged();
- verify(mMetricsFeatureProvider).action(mContext, SettingsEnums.FUELGAUGE_BATTERY_SAVER,
- Pair.create(SettingsEnums.FIELD_BATTERY_SAVER_SCHEDULE_TYPE,
- SettingsEnums.BATTERY_SAVER_SCHEDULE_TYPE_BASED_ON_ROUTINE));
- }
-
@Test
public void getSummary_batterySaverOn_showSummaryOn() {
when(mPowerManager.isPowerSaveMode()).thenReturn(true);
@@ -167,4 +117,10 @@ public class BatterySaverControllerTest {
assertThat(mBatterySaverController.getSummary()).isEqualTo("Off");
}
+
+ @Test
+ public void getAvailabilityStatus_returnAvailable() {
+ assertThat(mBatterySaverController.getAvailabilityStatus())
+ .isEqualTo(BatterySaverController.AVAILABLE);
+ }
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/ConvertUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/ConvertUtilsTest.java
index b04f053624a..ff0f25c3388 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/ConvertUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/ConvertUtilsTest.java
@@ -40,6 +40,7 @@ import org.robolectric.RuntimeEnvironment;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -67,7 +68,7 @@ public final class ConvertUtilsTest {
}
@Test
- public void testConvert_returnsExpectedContentValues() {
+ public void convert_returnsExpectedContentValues() {
final int expectedType = 3;
when(mockBatteryEntry.getUid()).thenReturn(1001);
when(mockBatteryEntry.getLabel()).thenReturn("Settings");
@@ -124,7 +125,7 @@ public final class ConvertUtilsTest {
}
@Test
- public void testConvert_nullBatteryEntry_returnsExpectedContentValues() {
+ public void convert_nullBatteryEntry_returnsExpectedContentValues() {
final ContentValues values =
ConvertUtils.convert(
/*entry=*/ null,
@@ -151,7 +152,7 @@ public final class ConvertUtilsTest {
}
@Test
- public void testGetIndexedUsageMap_nullOrEmptyHistoryMap_returnEmptyCollection() {
+ public void getIndexedUsageMap_nullOrEmptyHistoryMap_returnEmptyCollection() {
final int timeSlotSize = 2;
final long[] batteryHistoryKeys = new long[] {101L, 102L, 103L, 104L, 105L};
@@ -166,7 +167,7 @@ public final class ConvertUtilsTest {
.isEmpty();
}
@Test
- public void testGetIndexedUsageMap_returnsExpectedResult() {
+ public void getIndexedUsageMap_returnsExpectedResult() {
// Creates the fake testing data.
final int timeSlotSize = 2;
final long[] batteryHistoryKeys = new long[] {101L, 102L, 103L, 104L, 105L};
@@ -278,7 +279,7 @@ public final class ConvertUtilsTest {
}
@Test
- public void testGetIndexedUsageMap_usageTimeExceed_returnsExpectedResult() {
+ public void getIndexedUsageMap_usageTimeExceed_returnsExpectedResult() {
final int timeSlotSize = 1;
final long[] batteryHistoryKeys = new long[] {101L, 102L, 103L};
final Map> batteryHistoryMap =
@@ -320,7 +321,7 @@ public final class ConvertUtilsTest {
}
@Test
- public void testGetIndexedUsageMap_hideBackgroundUsageTime_returnsExpectedResult() {
+ public void getIndexedUsageMap_hideBackgroundUsageTime_returnsExpectedResult() {
final long[] batteryHistoryKeys = new long[] {101L, 102L, 103L};
final Map> batteryHistoryMap = new HashMap<>();
final BatteryHistEntry fakeEntry = createBatteryHistEntry(
@@ -339,8 +340,8 @@ public final class ConvertUtilsTest {
"package3", "label3", 500, 5L, 3600000L, 7200000L);
entryMap.put(entry.getKey(), entry);
batteryHistoryMap.put(Long.valueOf(batteryHistoryKeys[2]), entryMap);
- when(mPowerUsageFeatureProvider.getHideBackgroundUsageTimeList(mContext))
- .thenReturn(Arrays.asList((CharSequence) "package3"));
+ when(mPowerUsageFeatureProvider.getHideBackgroundUsageTimeSet(mContext))
+ .thenReturn(new HashSet(Arrays.asList((CharSequence) "package3")));
final Map> purgedResultMap =
ConvertUtils.getIndexedUsageMap(
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/ExpandDividerPreferenceTest.java b/tests/robotests/src/com/android/settings/fuelgauge/ExpandDividerPreferenceTest.java
index 97af2827e6f..9e32da4bea0 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/ExpandDividerPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/ExpandDividerPreferenceTest.java
@@ -18,11 +18,7 @@ package com.android.settings.fuelgauge;
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-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;
@@ -36,8 +32,6 @@ import com.android.settings.R;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
@@ -52,7 +46,6 @@ public final class ExpandDividerPreferenceTest {
@Before
public void setUp() {
- MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
mImageView = spy(new ImageView(mContext));
mTextView = spy(new TextView(mContext));
@@ -64,9 +57,9 @@ public final class ExpandDividerPreferenceTest {
@Test
public void testConstructor_returnExpectedResult() {
assertThat(mExpandDividerPreference.getKey())
- .isEqualTo(ExpandDividerPreference.PREFERENCE_KEY);
+ .isEqualTo(ExpandDividerPreference.PREFERENCE_KEY);
assertThat(mExpandDividerPreference.getLayoutResource())
- .isEqualTo(R.layout.preference_expand_divider);
+ .isEqualTo(R.layout.preference_expand_divider);
}
@Test
@@ -75,9 +68,7 @@ public final class ExpandDividerPreferenceTest {
mExpandDividerPreference.mTextView = mTextView;
mExpandDividerPreference.setTitle(titleContent);
- final ArgumentCaptor