diff --git a/res/drawable/ic_radio_button_checked_black_24dp.xml b/res/drawable/ic_radio_button_checked_black_24dp.xml
new file mode 100644
index 00000000000..3be6f9962e3
--- /dev/null
+++ b/res/drawable/ic_radio_button_checked_black_24dp.xml
@@ -0,0 +1,24 @@
+
+
+
+
diff --git a/res/drawable/ic_radio_button_unchecked_black_24dp.xml b/res/drawable/ic_radio_button_unchecked_black_24dp.xml
new file mode 100644
index 00000000000..a864f7b07b4
--- /dev/null
+++ b/res/drawable/ic_radio_button_unchecked_black_24dp.xml
@@ -0,0 +1,24 @@
+
+
+
+
diff --git a/res/drawable/radio_button_check.xml b/res/drawable/radio_button_check.xml
new file mode 100644
index 00000000000..e7884d71731
--- /dev/null
+++ b/res/drawable/radio_button_check.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index c3faa20a623..1646b7016d6 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -7256,7 +7256,7 @@
You will see notifications on your screen
When notifications arrive, your phone won\u2019t make a sound or vibrate.
-
+
No visuals or sound from notifications
You won\u2019t see or hear notifications
diff --git a/src/com/android/settings/mobilenetwork/Enhanced4gLteSliceHelper.java b/src/com/android/settings/mobilenetwork/Enhanced4gLteSliceHelper.java
new file mode 100644
index 00000000000..de542ace95c
--- /dev/null
+++ b/src/com/android/settings/mobilenetwork/Enhanced4gLteSliceHelper.java
@@ -0,0 +1,295 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.mobilenetwork;
+
+import static android.app.slice.Slice.EXTRA_TOGGLE_STATE;
+
+import android.app.PendingIntent;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.net.Uri;
+import android.os.PersistableBundle;
+import androidx.core.graphics.drawable.IconCompat;
+import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionManager;
+import android.util.Log;
+
+import androidx.slice.Slice;
+import androidx.slice.builders.ListBuilder;
+import androidx.slice.builders.SliceAction;
+
+import com.android.ims.ImsManager;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.settings.R;
+import com.android.settings.Utils;
+import com.android.settings.slices.SettingsSliceProvider;
+import com.android.settings.slices.SliceBroadcastReceiver;
+import com.android.settings.slices.SliceBuilderUtils;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * Helper class to control slices for enhanced 4g LTE settings.
+ */
+public class Enhanced4gLteSliceHelper {
+
+ private static final String TAG = "Enhanced4gLteSliceHelper";
+
+ /**
+ * Settings slice path to enhanced 4g LTE setting.
+ */
+ public static final String PATH_ENHANCED_4G_LTE = "enhanced_4g_lte";
+
+ /**
+ * Action passed for changes to enhanced 4g LTE slice (toggle).
+ */
+ public static final String ACTION_ENHANCED_4G_LTE_CHANGED =
+ "com.android.settings.mobilenetwork.action.ENHANCED_4G_LTE_CHANGED";
+
+ /**
+ * Slice Uri for Enhanced 4G slice
+ */
+ public static final Uri SLICE_URI = new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+ .appendPath(PATH_ENHANCED_4G_LTE)
+ .build();
+ /**
+ * Action for mobile network settings activity which
+ * allows setting configuration for Enhanced 4G LTE
+ * related settings
+ */
+ public static final String ACTION_MOBILE_NETWORK_SETTINGS_ACTIVITY =
+ "android.settings.NETWORK_OPERATOR_SETTINGS";
+
+ /**
+ * Timeout for querying enhanced 4g lte setting from ims manager.
+ */
+ private static final int TIMEOUT_MILLIS = 2000;
+
+ private final Context mContext;
+
+ /**
+ * Phone package name
+ */
+ private static final String PACKAGE_PHONE = "com.android.phone";
+
+ /**
+ * String resource type
+ */
+ private static final String RESOURCE_TYPE_STRING = "string";
+
+ /**
+ * Enhanced 4g lte mode title variant resource name
+ */
+ private static final String RESOURCE_ENHANCED_4G_LTE_MODE_TITLE_VARIANT =
+ "enhanced_4g_lte_mode_title_variant";
+
+ @VisibleForTesting
+ public Enhanced4gLteSliceHelper(Context context) {
+ mContext = context;
+ }
+
+ /**
+ * Returns Slice object for enhanced_4g_lte settings.
+ *
+ * If enhanced 4g LTE is not supported for the current carrier, this method will return slice
+ * with not supported message.
+ *
+ * If enhanced 4g LTE is not editable for the current carrier, this method will return slice
+ * with not editable message.
+ *
+ * If enhanced 4g LTE setting can be changed, this method will return the slice to toggle
+ * enhanced 4g LTE option with ACTION_ENHANCED_4G_LTE_CHANGED as endItem.
+ */
+ public Slice createEnhanced4gLteSlice(Uri sliceUri) {
+ final int subId = getDefaultVoiceSubId();
+
+ if (subId <= SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ Log.d(TAG, "Invalid subscription Id");
+ return null;
+ }
+
+ final ImsManager imsManager = getImsManager(subId);
+
+ if (!imsManager.isVolteEnabledByPlatform()
+ || !imsManager.isVolteProvisionedOnDevice()) {
+ Log.d(TAG, "Setting is either not provisioned or not enabled by Platform");
+ return null;
+ }
+
+ if (isCarrierConfigManagerKeyEnabled(
+ CarrierConfigManager.KEY_HIDE_ENHANCED_4G_LTE_BOOL, subId, false)
+ || !isCarrierConfigManagerKeyEnabled(
+ CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL, subId,
+ true)) {
+ Log.d(TAG, "Setting is either hidden or not editable");
+ return null;
+ }
+
+ try {
+ return getEnhanced4gLteSlice(sliceUri,
+ isEnhanced4gLteModeEnabled(imsManager), subId);
+ } catch (InterruptedException | TimeoutException | ExecutionException e) {
+ Log.e(TAG, "Unable to read the current Enhanced 4g LTE status", e);
+ return null;
+ }
+ }
+
+ private boolean isEnhanced4gLteModeEnabled(ImsManager imsManager)
+ throws InterruptedException, ExecutionException, TimeoutException {
+ final FutureTask isEnhanced4gLteOnTask = new FutureTask<>(new Callable() {
+ @Override
+ public Boolean call() {
+ return imsManager.isEnhanced4gLteModeSettingEnabledByUser();
+ }
+ });
+ final ExecutorService executor = Executors.newSingleThreadExecutor();
+ executor.execute(isEnhanced4gLteOnTask);
+
+ return isEnhanced4gLteOnTask.get(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+ }
+
+ /**
+ * Builds a toggle slice where the intent takes you to the Enhanced 4G LTE page and the toggle
+ * enables/disables Enhanced 4G LTE mode setting.
+ */
+ private Slice getEnhanced4gLteSlice(Uri sliceUri, boolean isEnhanced4gLteEnabled, int subId) {
+ final IconCompat icon = IconCompat.createWithResource(mContext,
+ R.drawable.ic_launcher_settings);
+
+ return new ListBuilder(mContext, sliceUri, ListBuilder.INFINITY)
+ .setAccentColor(Utils.getColorAccentDefaultColor(mContext))
+ .addRow(b -> b
+ .setTitle(getEnhanced4glteModeTitle(subId))
+ .addEndItem(
+ new SliceAction(
+ getBroadcastIntent(ACTION_ENHANCED_4G_LTE_CHANGED),
+ null /* actionTitle */, isEnhanced4gLteEnabled))
+ .setPrimaryAction(new SliceAction(
+ getActivityIntent(ACTION_MOBILE_NETWORK_SETTINGS_ACTIVITY),
+ icon,
+ getEnhanced4glteModeTitle(subId))))
+ .build();
+ }
+
+ protected ImsManager getImsManager(int subId) {
+ return ImsManager.getInstance(mContext, SubscriptionManager.getPhoneId(subId));
+ }
+
+ /**
+ * Handles Enhanced 4G LTE mode setting change from Enhanced 4G LTE slice and posts
+ * notification. Should be called when intent action is ACTION_ENHANCED_4G_LTE_CHANGED
+ *
+ * @param intent action performed
+ */
+ public void handleEnhanced4gLteChanged(Intent intent) {
+ final int subId = getDefaultVoiceSubId();
+
+ if (subId > SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ final ImsManager imsManager = getImsManager(subId);
+ if (imsManager.isVolteEnabledByPlatform()
+ && imsManager.isVolteProvisionedOnDevice()) {
+ final boolean currentValue = imsManager.isEnhanced4gLteModeSettingEnabledByUser()
+ && imsManager.isNonTtyOrTtyOnVolteEnabled();
+ final boolean newValue = intent.getBooleanExtra(EXTRA_TOGGLE_STATE,
+ currentValue);
+ if (newValue != currentValue) {
+ imsManager.setEnhanced4gLteModeSetting(newValue);
+ }
+ }
+ }
+ // notify change in slice in any case to get re-queried. This would result in displaying
+ // appropriate message with the updated setting.
+ final Uri uri = SliceBuilderUtils.getUri(PATH_ENHANCED_4G_LTE, false /*isPlatformSlice*/);
+ mContext.getContentResolver().notifyChange(uri, null);
+ }
+
+ private CharSequence getEnhanced4glteModeTitle(int subId) {
+ CharSequence ret = mContext.getText(R.string.enhanced_4g_lte_mode_title);
+ try {
+ if (isCarrierConfigManagerKeyEnabled(
+ CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_BOOL,
+ subId,
+ false)) {
+ final PackageManager manager = mContext.getPackageManager();
+ final Resources resources = manager.getResourcesForApplication(
+ PACKAGE_PHONE);
+ final int resId = resources.getIdentifier(
+ RESOURCE_ENHANCED_4G_LTE_MODE_TITLE_VARIANT,
+ RESOURCE_TYPE_STRING, PACKAGE_PHONE);
+ ret = resources.getText(resId);
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(TAG, "package name not found");
+ }
+ return ret;
+ }
+
+ /**
+ * Returns {@code true} when the key is enabled for the carrier, and {@code false} otherwise.
+ */
+ private boolean isCarrierConfigManagerKeyEnabled(String key,
+ int subId, boolean defaultValue) {
+ final CarrierConfigManager configManager = getCarrierConfigManager();
+ boolean ret = defaultValue;
+ if (configManager != null) {
+ final PersistableBundle bundle = configManager.getConfigForSubId(subId);
+ if (bundle != null) {
+ ret = bundle.getBoolean(key, defaultValue);
+ }
+ }
+ return ret;
+ }
+
+ protected CarrierConfigManager getCarrierConfigManager() {
+ return mContext.getSystemService(CarrierConfigManager.class);
+ }
+
+ private PendingIntent getBroadcastIntent(String action) {
+ final Intent intent = new Intent(action);
+ intent.setClass(mContext, SliceBroadcastReceiver.class);
+ return PendingIntent.getBroadcast(mContext, 0 /* requestCode */, intent,
+ PendingIntent.FLAG_CANCEL_CURRENT);
+ }
+
+ /**
+ * Returns the current default voice subId obtained from SubscriptionManager
+ */
+ protected int getDefaultVoiceSubId() {
+ return SubscriptionManager.getDefaultVoiceSubscriptionId();
+ }
+
+ /**
+ * Returns PendingIntent to start activity specified by action
+ */
+ private PendingIntent getActivityIntent(String action) {
+ final Intent intent = new Intent(action);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ return PendingIntent.getActivity(mContext, 0 /* requestCode */, intent, 0 /* flags */);
+ }
+}
+
diff --git a/src/com/android/settings/nfc/PaymentSettings.java b/src/com/android/settings/nfc/PaymentSettings.java
index 82335814581..6e03842634f 100644
--- a/src/com/android/settings/nfc/PaymentSettings.java
+++ b/src/com/android/settings/nfc/PaymentSettings.java
@@ -20,12 +20,15 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
+import android.os.UserHandle;
+import android.os.UserManager;
import android.provider.SearchIndexableResource;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
+import android.content.pm.UserInfo;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
@@ -111,6 +114,11 @@ public class PaymentSettings extends DashboardFragment {
@Override
protected boolean isPageSearchEnabled(Context context) {
+ final UserManager userManager = context.getSystemService(UserManager.class);
+ final UserInfo myUserInfo = userManager.getUserInfo(UserHandle.myUserId());
+ if (myUserInfo.isGuest()) {
+ return false;
+ }
final PackageManager pm = context.getPackageManager();
return pm.hasSystemFeature(PackageManager.FEATURE_NFC);
}
diff --git a/src/com/android/settings/notification/ZenModeStarredContactsPreferenceController.java b/src/com/android/settings/notification/ZenModeStarredContactsPreferenceController.java
index 0996534b9d9..28475b6b5e3 100644
--- a/src/com/android/settings/notification/ZenModeStarredContactsPreferenceController.java
+++ b/src/com/android/settings/notification/ZenModeStarredContactsPreferenceController.java
@@ -117,6 +117,7 @@ public class ZenModeStarredContactsPreferenceController extends
}
}
+ // values in displayContacts must not be null
mPreference.setSummary(ListFormatter.getInstance().format(displayContacts));
}
@@ -130,22 +131,32 @@ public class ZenModeStarredContactsPreferenceController extends
return true;
}
- private List getStarredContacts() {
+ @VisibleForTesting
+ List getStarredContacts(Cursor cursor) {
List starredContacts = new ArrayList<>();
- Cursor cursor = mContext.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,
- new String[]{ContactsContract.Contacts.DISPLAY_NAME_PRIMARY},
- ContactsContract.Data.STARRED + "=1", null,
- ContactsContract.Data.TIMES_CONTACTED);
-
if (cursor.moveToFirst()) {
do {
- starredContacts.add(cursor.getString(0));
+ String contact = cursor.getString(0);
+ if (contact != null) {
+ starredContacts.add(contact);
+ }
} while (cursor.moveToNext());
}
return starredContacts;
}
+ private List getStarredContacts() {
+ return getStarredContacts(queryData());
+ }
+
+ private Cursor queryData() {
+ return mContext.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,
+ new String[]{ContactsContract.Contacts.DISPLAY_NAME_PRIMARY},
+ ContactsContract.Data.STARRED + "=1", null,
+ ContactsContract.Data.TIMES_CONTACTED);
+ }
+
private boolean isIntentValid() {
return mStarredContactsIntent.resolveActivity(mPackageManager) != null
|| mFallbackIntent.resolveActivity(mPackageManager) != null;
diff --git a/src/com/android/settings/slices/SettingsSliceProvider.java b/src/com/android/settings/slices/SettingsSliceProvider.java
index f4dfd6ee71d..db09a378e1b 100644
--- a/src/com/android/settings/slices/SettingsSliceProvider.java
+++ b/src/com/android/settings/slices/SettingsSliceProvider.java
@@ -36,6 +36,7 @@ import com.android.settings.bluetooth.BluetoothSliceBuilder;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.location.LocationSliceBuilder;
import com.android.settings.notification.ZenModeSliceBuilder;
+import com.android.settings.mobilenetwork.Enhanced4gLteSliceHelper;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.wifi.WifiSliceBuilder;
import com.android.settings.wifi.calling.WifiCallingSliceHelper;
@@ -190,23 +191,32 @@ public class SettingsSliceProvider extends SliceProvider {
Log.e(TAG, "Requested blocked slice with Uri: " + sliceUri);
return null;
}
-
- // If adding a new Slice, do not directly match Slice URIs.
- // Use {@link SlicesDatabaseAccessor}.
- if (WifiCallingSliceHelper.WIFI_CALLING_URI.equals(sliceUri)) {
- return FeatureFactory.getFactory(getContext())
- .getSlicesFeatureProvider()
- .getNewWifiCallingSliceHelper(getContext())
- .createWifiCallingSlice(sliceUri);
- } else if (WifiSliceBuilder.WIFI_URI.equals(sliceUri)) {
- return WifiSliceBuilder.getSlice(getContext());
- } else if (ZenModeSliceBuilder.ZEN_MODE_URI.equals(sliceUri)) {
- return ZenModeSliceBuilder.getSlice(getContext());
- } else if (BluetoothSliceBuilder.BLUETOOTH_URI.equals(sliceUri)) {
- return BluetoothSliceBuilder.getSlice(getContext());
- } else if (LocationSliceBuilder.LOCATION_URI.equals(sliceUri)) {
- return LocationSliceBuilder.getSlice(getContext());
- }
+ // If adding a new Slice, do not directly match Slice URIs.
+ // Use {@link SlicesDatabaseAccessor}.
+ if (WifiCallingSliceHelper.WIFI_CALLING_URI.equals(sliceUri)) {
+ return FeatureFactory.getFactory(getContext())
+ .getSlicesFeatureProvider()
+ .getNewWifiCallingSliceHelper(getContext())
+ .createWifiCallingSlice(sliceUri);
+ } else if (WifiSliceBuilder.WIFI_URI.equals(sliceUri)) {
+ return WifiSliceBuilder.getSlice(getContext());
+ } else if (ZenModeSliceBuilder.ZEN_MODE_URI.equals(sliceUri)) {
+ return ZenModeSliceBuilder.getSlice(getContext());
+ } else if (BluetoothSliceBuilder.BLUETOOTH_URI.equals(sliceUri)) {
+ return BluetoothSliceBuilder.getSlice(getContext());
+ } else if (LocationSliceBuilder.LOCATION_URI.equals(sliceUri)) {
+ return LocationSliceBuilder.getSlice(getContext());
+ } else if (Enhanced4gLteSliceHelper.SLICE_URI.equals(sliceUri)) {
+ return FeatureFactory.getFactory(getContext())
+ .getSlicesFeatureProvider()
+ .getNewEnhanced4gLteSliceHelper(getContext())
+ .createEnhanced4gLteSlice(sliceUri);
+ } else if (WifiCallingSliceHelper.WIFI_CALLING_PREFERENCE_URI.equals(sliceUri)) {
+ return FeatureFactory.getFactory(getContext())
+ .getSlicesFeatureProvider()
+ .getNewWifiCallingSliceHelper(getContext())
+ .createWifiCallingPreferenceSlice(sliceUri);
+ }
SliceData cachedSliceData = mSliceWeakDataCache.get(sliceUri);
if (cachedSliceData == null) {
diff --git a/src/com/android/settings/slices/SliceBroadcastReceiver.java b/src/com/android/settings/slices/SliceBroadcastReceiver.java
index d81734a974d..9f1ef769d7d 100644
--- a/src/com/android/settings/slices/SliceBroadcastReceiver.java
+++ b/src/com/android/settings/slices/SliceBroadcastReceiver.java
@@ -24,6 +24,10 @@ import static com.android.settings.slices.SettingsSliceProvider.EXTRA_SLICE_KEY;
import static com.android.settings.slices.SettingsSliceProvider.EXTRA_SLICE_PLATFORM_DEFINED;
import static com.android.settings.wifi.calling.WifiCallingSliceHelper.ACTION_WIFI_CALLING_CHANGED;
import static com.android.settings.wifi.WifiSliceBuilder.ACTION_WIFI_SLICE_CHANGED;
+import static com.android.settings.mobilenetwork.Enhanced4gLteSliceHelper.ACTION_ENHANCED_4G_LTE_CHANGED;
+import static com.android.settings.wifi.calling.WifiCallingSliceHelper.ACTION_WIFI_CALLING_PREFERENCE_WIFI_ONLY;
+import static com.android.settings.wifi.calling.WifiCallingSliceHelper.ACTION_WIFI_CALLING_PREFERENCE_WIFI_PREFERRED;
+import static com.android.settings.wifi.calling.WifiCallingSliceHelper.ACTION_WIFI_CALLING_PREFERENCE_CELLULAR_PREFERRED;
import android.app.slice.Slice;
import android.content.BroadcastReceiver;
@@ -84,6 +88,20 @@ public class SliceBroadcastReceiver extends BroadcastReceiver {
case ACTION_ZEN_MODE_SLICE_CHANGED:
ZenModeSliceBuilder.handleUriChange(context, intent);
break;
+ case ACTION_ENHANCED_4G_LTE_CHANGED:
+ FeatureFactory.getFactory(context)
+ .getSlicesFeatureProvider()
+ .getNewEnhanced4gLteSliceHelper(context)
+ .handleEnhanced4gLteChanged(intent);
+ break;
+ case ACTION_WIFI_CALLING_PREFERENCE_WIFI_ONLY:
+ case ACTION_WIFI_CALLING_PREFERENCE_WIFI_PREFERRED:
+ case ACTION_WIFI_CALLING_PREFERENCE_CELLULAR_PREFERRED:
+ FeatureFactory.getFactory(context)
+ .getSlicesFeatureProvider()
+ .getNewWifiCallingSliceHelper(context)
+ .handleWifiCallingPreferenceChanged(intent);
+ break;
default:
final String uriString = intent.getStringExtra(SliceBroadcastRelay.EXTRA_URI);
if (!TextUtils.isEmpty(uriString)) {
diff --git a/src/com/android/settings/slices/SlicesFeatureProvider.java b/src/com/android/settings/slices/SlicesFeatureProvider.java
index 8dd6547b398..8395a58dc16 100644
--- a/src/com/android/settings/slices/SlicesFeatureProvider.java
+++ b/src/com/android/settings/slices/SlicesFeatureProvider.java
@@ -2,6 +2,7 @@ package com.android.settings.slices;
import android.content.Context;
+import com.android.settings.mobilenetwork.Enhanced4gLteSliceHelper;
import com.android.settings.wifi.calling.WifiCallingSliceHelper;
/**
@@ -31,4 +32,10 @@ public interface SlicesFeatureProvider {
* Gets new WifiCallingSliceHelper object
*/
WifiCallingSliceHelper getNewWifiCallingSliceHelper(Context context);
+
+ /**
+ * Gets new Enhanced4gLteSliceHelper object
+ */
+ Enhanced4gLteSliceHelper getNewEnhanced4gLteSliceHelper(Context context);
}
+
diff --git a/src/com/android/settings/slices/SlicesFeatureProviderImpl.java b/src/com/android/settings/slices/SlicesFeatureProviderImpl.java
index 16684bfb022..988bcfe2273 100644
--- a/src/com/android/settings/slices/SlicesFeatureProviderImpl.java
+++ b/src/com/android/settings/slices/SlicesFeatureProviderImpl.java
@@ -2,6 +2,7 @@ package com.android.settings.slices;
import android.content.Context;
+import com.android.settings.mobilenetwork.Enhanced4gLteSliceHelper;
import com.android.settings.wifi.calling.WifiCallingSliceHelper;
import com.android.settingslib.utils.ThreadUtils;
@@ -45,4 +46,9 @@ public class SlicesFeatureProviderImpl implements SlicesFeatureProvider {
public WifiCallingSliceHelper getNewWifiCallingSliceHelper(Context context) {
return new WifiCallingSliceHelper(context);
}
+
+ @Override
+ public Enhanced4gLteSliceHelper getNewEnhanced4gLteSliceHelper(Context context) {
+ return new Enhanced4gLteSliceHelper(context);
+ }
}
diff --git a/src/com/android/settings/wifi/calling/WifiCallingSliceHelper.java b/src/com/android/settings/wifi/calling/WifiCallingSliceHelper.java
index e8e33ef0531..ab8db2b7728 100644
--- a/src/com/android/settings/wifi/calling/WifiCallingSliceHelper.java
+++ b/src/com/android/settings/wifi/calling/WifiCallingSliceHelper.java
@@ -35,11 +35,14 @@ import android.util.Log;
import androidx.core.graphics.drawable.IconCompat;
import androidx.slice.Slice;
import androidx.slice.builders.ListBuilder;
+import androidx.slice.builders.ListBuilder.RowBuilder;
import androidx.slice.builders.SliceAction;
+import com.android.ims.ImsConfig;
import com.android.ims.ImsManager;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
+import com.android.settings.Utils;
import com.android.settings.slices.SettingsSliceProvider;
import com.android.settings.slices.SliceBroadcastReceiver;
import com.android.settings.slices.SliceBuilderUtils;
@@ -65,12 +68,34 @@ public class WifiCallingSliceHelper {
*/
public static final String PATH_WIFI_CALLING = "wifi_calling";
+ /**
+ * Settings slice path to wifi calling preference setting.
+ */
+ public static final String PATH_WIFI_CALLING_PREFERENCE =
+ "wifi_calling_preference";
+
/**
* Action passed for changes to wifi calling slice (toggle).
*/
public static final String ACTION_WIFI_CALLING_CHANGED =
"com.android.settings.wifi.calling.action.WIFI_CALLING_CHANGED";
+ /**
+ * Action passed when user selects wifi only preference.
+ */
+ public static final String ACTION_WIFI_CALLING_PREFERENCE_WIFI_ONLY =
+ "com.android.settings.slice.action.WIFI_CALLING_PREFERENCE_WIFI_ONLY";
+ /**
+ * Action passed when user selects wifi preferred preference.
+ */
+ public static final String ACTION_WIFI_CALLING_PREFERENCE_WIFI_PREFERRED =
+ "com.android.settings.slice.action.WIFI_CALLING_PREFERENCE_WIFI_PREFERRED";
+ /**
+ * Action passed when user selects cellular preferred preference.
+ */
+ public static final String ACTION_WIFI_CALLING_PREFERENCE_CELLULAR_PREFERRED =
+ "com.android.settings.slice.action.WIFI_CALLING_PREFERENCE_CELLULAR_PREFERRED";
+
/**
* Action for Wifi calling Settings activity which
* allows setting configuration for Wifi calling
@@ -88,12 +113,20 @@ public class WifiCallingSliceHelper {
.appendPath(PATH_WIFI_CALLING)
.build();
+ /**
+ * Full {@link Uri} for the Wifi Calling Preference Slice.
+ */
+ public static final Uri WIFI_CALLING_PREFERENCE_URI = new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+ .appendPath(PATH_WIFI_CALLING_PREFERENCE)
+ .build();
+
/**
* Timeout for querying wifi calling setting from ims manager.
*/
private static final int TIMEOUT_MILLIS = 2000;
- protected SubscriptionManager mSubscriptionManager;
private final Context mContext;
@VisibleForTesting
@@ -115,14 +148,10 @@ public class WifiCallingSliceHelper {
*/
public Slice createWifiCallingSlice(Uri sliceUri) {
final int subId = getDefaultVoiceSubId();
- final String carrierName = getSimCarrierName();
if (subId <= SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
Log.d(TAG, "Invalid subscription Id");
- return getNonActionableWifiCallingSlice(
- mContext.getString(R.string.wifi_calling_settings_title),
- mContext.getString(R.string.wifi_calling_not_supported, carrierName),
- sliceUri, getSettingsIntent(mContext));
+ return null;
}
final ImsManager imsManager = getImsManager(subId);
@@ -130,10 +159,7 @@ public class WifiCallingSliceHelper {
if (!imsManager.isWfcEnabledByPlatform()
|| !imsManager.isWfcProvisionedOnDevice()) {
Log.d(TAG, "Wifi calling is either not provisioned or not enabled by Platform");
- return getNonActionableWifiCallingSlice(
- mContext.getString(R.string.wifi_calling_settings_title),
- mContext.getString(R.string.wifi_calling_not_supported, carrierName),
- sliceUri, getSettingsIntent(mContext));
+ return null;
}
try {
@@ -148,18 +174,15 @@ public class WifiCallingSliceHelper {
// Activation needed for the next action of the user
// Give instructions to go to settings app
return getNonActionableWifiCallingSlice(
- mContext.getString(R.string.wifi_calling_settings_title),
- mContext.getString(
+ mContext.getText(R.string.wifi_calling_settings_title),
+ mContext.getText(
R.string.wifi_calling_settings_activation_instructions),
sliceUri, getActivityIntent(ACTION_WIFI_CALLING_SETTINGS_ACTIVITY));
}
- return getWifiCallingSlice(sliceUri, mContext, isWifiCallingEnabled);
+ return getWifiCallingSlice(sliceUri, isWifiCallingEnabled);
} catch (InterruptedException | TimeoutException | ExecutionException e) {
Log.e(TAG, "Unable to read the current WiFi calling status", e);
- return getNonActionableWifiCallingSlice(
- mContext.getString(R.string.wifi_calling_settings_title),
- mContext.getString(R.string.wifi_calling_turn_on),
- sliceUri, getActivityIntent(ACTION_WIFI_CALLING_SETTINGS_ACTIVITY));
+ return null;
}
}
@@ -174,25 +197,21 @@ public class WifiCallingSliceHelper {
final ExecutorService executor = Executors.newSingleThreadExecutor();
executor.execute(isWifiOnTask);
- Boolean isWifiEnabledByUser = false;
- isWifiEnabledByUser = isWifiOnTask.get(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
-
- return isWifiEnabledByUser && imsManager.isNonTtyOrTtyOnVolteEnabled();
+ return isWifiOnTask.get(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)
+ && imsManager.isNonTtyOrTtyOnVolteEnabled();
}
/**
* Builds a toggle slice where the intent takes you to the wifi calling page and the toggle
* enables/disables wifi calling.
*/
- private Slice getWifiCallingSlice(Uri sliceUri, Context mContext,
- boolean isWifiCallingEnabled) {
-
+ private Slice getWifiCallingSlice(Uri sliceUri, boolean isWifiCallingEnabled) {
final IconCompat icon = IconCompat.createWithResource(mContext, R.drawable.wifi_signal);
- final String title = mContext.getString(R.string.wifi_calling_settings_title);
+
return new ListBuilder(mContext, sliceUri, ListBuilder.INFINITY)
- .setColor(R.color.material_blue_500)
+ .setAccentColor(Utils.getColorAccentDefaultColor(mContext))
.addRow(b -> b
- .setTitle(title)
+ .setTitle(mContext.getText(R.string.wifi_calling_settings_title))
.addEndItem(
new SliceAction(
getBroadcastIntent(ACTION_WIFI_CALLING_CHANGED),
@@ -200,15 +219,160 @@ public class WifiCallingSliceHelper {
.setPrimaryAction(new SliceAction(
getActivityIntent(ACTION_WIFI_CALLING_SETTINGS_ACTIVITY),
icon,
- title)))
+ mContext.getText(R.string.wifi_calling_settings_title))))
.build();
}
+ /**
+ * Returns Slice object for wifi calling preference.
+ *
+ * If wifi calling is not turned on, this method will return a slice to turn on wifi calling.
+ *
+ * If wifi calling preference is not user editable, this method will return a slice to display
+ * appropriate message.
+ *
+ * If wifi calling preference can be changed, this method will return a slice with 3 or 4 rows:
+ * Header Row: current preference settings
+ * Row 1: wifi only option with ACTION_WIFI_CALLING_PREFERENCE_WIFI_ONLY, if wifi only option
+ * is editable
+ * Row 2: wifi preferred option with ACTION_WIFI_CALLING_PREFERENCE_WIFI_PREFERRED
+ * Row 3: cellular preferred option with ACTION_WIFI_CALLING_PREFERENCE_CELLULAR_PREFERRED
+ */
+ public Slice createWifiCallingPreferenceSlice(Uri sliceUri) {
+ final int subId = getDefaultVoiceSubId();
+
+ if (subId <= SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ Log.d(TAG, "Invalid Subscription Id");
+ return null;
+ }
+
+ final boolean isWifiCallingPrefEditable = isCarrierConfigManagerKeyEnabled(
+ CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL, subId,false);
+ final boolean isWifiOnlySupported = isCarrierConfigManagerKeyEnabled(
+ CarrierConfigManager.KEY_CARRIER_WFC_SUPPORTS_WIFI_ONLY_BOOL, subId, true);
+ final ImsManager imsManager = getImsManager(subId);
+
+ if (!imsManager.isWfcEnabledByPlatform()
+ || !imsManager.isWfcProvisionedOnDevice()) {
+ Log.d(TAG, "Wifi calling is either not provisioned or not enabled by platform");
+ return null;
+ }
+
+ if (!isWifiCallingPrefEditable) {
+ Log.d(TAG, "Wifi calling preference is not editable");
+ return null;
+ }
+
+ boolean isWifiCallingEnabled = false;
+ int wfcMode = -1;
+ try {
+ isWifiCallingEnabled = isWifiCallingEnabled(imsManager);
+ wfcMode = getWfcMode(imsManager);
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ Log.e(TAG, "Unable to get wifi calling preferred mode", e);
+ return null;
+ }
+ if (!isWifiCallingEnabled) {
+ // wifi calling is not enabled. Ask user to enable wifi calling
+ return getNonActionableWifiCallingSlice(
+ mContext.getText(R.string.wifi_calling_mode_title),
+ mContext.getText(R.string.wifi_calling_turn_on),
+ sliceUri, getActivityIntent(ACTION_WIFI_CALLING_SETTINGS_ACTIVITY));
+ }
+ // Return the slice to change wifi calling preference
+ return getWifiCallingPreferenceSlice(
+ isWifiOnlySupported, wfcMode, sliceUri);
+ }
+
+ /**
+ * Returns actionable wifi calling preference slice.
+ *
+ * @param isWifiOnlySupported adds row for wifi only if this is true
+ * @param currentWfcPref current Preference {@link ImsConfig}
+ * @param sliceUri sliceUri
+ * @return Slice for actionable wifi calling preference settings
+ */
+ private Slice getWifiCallingPreferenceSlice(boolean isWifiOnlySupported,
+ int currentWfcPref,
+ Uri sliceUri) {
+ final IconCompat icon = IconCompat.createWithResource(mContext, R.drawable.wifi_signal);
+ // Top row shows information on current preference state
+ ListBuilder listBuilder = new ListBuilder(mContext, sliceUri, ListBuilder.INFINITY)
+ .setAccentColor(Utils.getColorAccentDefaultColor(mContext));
+ listBuilder.setHeader(new ListBuilder.HeaderBuilder(listBuilder)
+ .setTitle(mContext.getText(R.string.wifi_calling_mode_title))
+ .setSubtitle(getWifiCallingPreferenceSummary(currentWfcPref))
+ .setPrimaryAction(new SliceAction(
+ getActivityIntent(ACTION_WIFI_CALLING_SETTINGS_ACTIVITY),
+ icon,
+ mContext.getText(R.string.wifi_calling_mode_title))));
+
+ if (isWifiOnlySupported) {
+ listBuilder.addRow(wifiPreferenceRowBuilder(listBuilder,
+ com.android.internal.R.string.wfc_mode_wifi_only_summary,
+ ACTION_WIFI_CALLING_PREFERENCE_WIFI_ONLY,
+ currentWfcPref == ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY));
+ }
+
+ listBuilder.addRow(wifiPreferenceRowBuilder(listBuilder,
+ com.android.internal.R.string.wfc_mode_wifi_preferred_summary,
+ ACTION_WIFI_CALLING_PREFERENCE_WIFI_PREFERRED,
+ currentWfcPref == ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED));
+
+ listBuilder.addRow(wifiPreferenceRowBuilder(listBuilder,
+ com.android.internal.R.string.wfc_mode_cellular_preferred_summary,
+ ACTION_WIFI_CALLING_PREFERENCE_CELLULAR_PREFERRED,
+ currentWfcPref == ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED));
+
+ return listBuilder.build();
+ }
+
+ /**
+ * Returns RowBuilder for a new row containing specific wifi calling preference.
+ *
+ * @param listBuilder ListBuilder that will be the parent for this RowBuilder
+ * @param preferenceTitleResId resource Id for the preference row title
+ * @param action action to be added for the row
+ * @return RowBuilder for the row
+ */
+ private RowBuilder wifiPreferenceRowBuilder(ListBuilder listBuilder,
+ int preferenceTitleResId, String action, boolean checked) {
+ final IconCompat icon =
+ IconCompat.createWithResource(mContext, R.drawable.radio_button_check);
+ return new RowBuilder(listBuilder)
+ .setTitle(mContext.getText(preferenceTitleResId))
+ .setTitleItem(new SliceAction(getBroadcastIntent(action),
+ icon, mContext.getText(preferenceTitleResId), checked));
+ }
+
+
+ /**
+ * Returns the String describing wifi calling preference mentioned in wfcMode
+ *
+ * @param wfcMode ImsConfig constant for the preference {@link ImsConfig}
+ * @return summary/name of the wifi calling preference
+ */
+ private CharSequence getWifiCallingPreferenceSummary(int wfcMode) {
+ switch (wfcMode) {
+ case ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY:
+ return mContext.getText(
+ com.android.internal.R.string.wfc_mode_wifi_only_summary);
+ case ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED:
+ return mContext.getText(
+ com.android.internal.R.string.wfc_mode_wifi_preferred_summary);
+ case ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED:
+ return mContext.getText(
+ com.android.internal.R.string.wfc_mode_cellular_preferred_summary);
+ default:
+ return null;
+ }
+ }
+
protected ImsManager getImsManager(int subId) {
return ImsManager.getInstance(mContext, SubscriptionManager.getPhoneId(subId));
}
- private Integer getWfcMode(ImsManager imsManager)
+ private int getWfcMode(ImsManager imsManager)
throws InterruptedException, ExecutionException, TimeoutException {
FutureTask wfcModeTask = new FutureTask<>(new Callable() {
@Override
@@ -233,7 +397,7 @@ public class WifiCallingSliceHelper {
if (subId > SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
final ImsManager imsManager = getImsManager(subId);
if (imsManager.isWfcEnabledByPlatform()
- || imsManager.isWfcProvisionedOnDevice()) {
+ && imsManager.isWfcProvisionedOnDevice()) {
final boolean currentValue = imsManager.isWfcEnabledByUser()
&& imsManager.isNonTtyOrTtyOnVolteEnabled();
final boolean newValue = intent.getBooleanExtra(EXTRA_TOGGLE_STATE,
@@ -255,6 +419,63 @@ public class WifiCallingSliceHelper {
mContext.getContentResolver().notifyChange(uri, null);
}
+ /**
+ * Handles wifi calling preference Setting change from wifi calling preference Slice and posts
+ * notification for the change. Should be called when intent action is one of the below
+ * ACTION_WIFI_CALLING_PREFERENCE_WIFI_ONLY
+ * ACTION_WIFI_CALLING_PREFERENCE_WIFI_PREFERRED
+ * ACTION_WIFI_CALLING_PREFERENCE_CELLULAR_PREFERRED
+ *
+ * @param intent intent
+ */
+ public void handleWifiCallingPreferenceChanged(Intent intent) {
+ final int subId = getDefaultVoiceSubId();
+ final int errorValue = -1;
+
+ if (subId > SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ final boolean isWifiCallingPrefEditable = isCarrierConfigManagerKeyEnabled(
+ CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL, subId,false);
+ final boolean isWifiOnlySupported = isCarrierConfigManagerKeyEnabled(
+ CarrierConfigManager.KEY_CARRIER_WFC_SUPPORTS_WIFI_ONLY_BOOL, subId, true);
+
+ ImsManager imsManager = getImsManager(subId);
+ if (isWifiCallingPrefEditable
+ && imsManager.isWfcEnabledByPlatform()
+ && imsManager.isWfcProvisionedOnDevice()
+ && imsManager.isWfcEnabledByUser()
+ && imsManager.isNonTtyOrTtyOnVolteEnabled()) {
+ // Change the preference only when wifi calling is enabled
+ // And when wifi calling preference is editable for the current carrier
+ final int currentValue = imsManager.getWfcMode(false);
+ int newValue = errorValue;
+ switch (intent.getAction()) {
+ case ACTION_WIFI_CALLING_PREFERENCE_WIFI_ONLY:
+ if (isWifiOnlySupported) {
+ // change to wifi_only when wifi_only is enabled.
+ newValue = ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY;
+ }
+ break;
+ case ACTION_WIFI_CALLING_PREFERENCE_WIFI_PREFERRED:
+ newValue = ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED;
+ break;
+ case ACTION_WIFI_CALLING_PREFERENCE_CELLULAR_PREFERRED:
+ newValue = ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED;
+ break;
+ }
+ if (newValue != errorValue && newValue != currentValue) {
+ // Update the setting only when there is a valid update
+ imsManager.setWfcMode(newValue, false);
+ }
+ }
+ }
+
+ // notify change in slice in any case to get re-queried. This would result in displaying
+ // appropriate message.
+ final Uri uri = SliceBuilderUtils.getUri(PATH_WIFI_CALLING_PREFERENCE,
+ false /*isPlatformSlice*/);
+ mContext.getContentResolver().notifyChange(uri, null);
+ }
+
/**
* Returns Slice with the title and subtitle provided as arguments with wifi signal Icon.
*
@@ -263,12 +484,11 @@ public class WifiCallingSliceHelper {
* @param sliceUri slice uri
* @return Slice with title and subtitle
*/
- // TODO(b/79548264) asses different scenarios and return null instead of non-actionable slice
- private Slice getNonActionableWifiCallingSlice(String title, String subtitle, Uri sliceUri,
- PendingIntent primaryActionIntent) {
+ private Slice getNonActionableWifiCallingSlice(CharSequence title, CharSequence subtitle,
+ Uri sliceUri, PendingIntent primaryActionIntent) {
final IconCompat icon = IconCompat.createWithResource(mContext, R.drawable.wifi_signal);
return new ListBuilder(mContext, sliceUri, ListBuilder.INFINITY)
- .setColor(R.color.material_blue_500)
+ .setAccentColor(Utils.getColorAccentDefaultColor(mContext))
.addRow(b -> b
.setTitle(title)
.setSubtitle(subtitle)
@@ -281,8 +501,8 @@ public class WifiCallingSliceHelper {
/**
* Returns {@code true} when the key is enabled for the carrier, and {@code false} otherwise.
*/
- private boolean isCarrierConfigManagerKeyEnabled(Context mContext, String key,
- int subId, boolean defaultValue) {
+ protected boolean isCarrierConfigManagerKeyEnabled(String key, int subId,
+ boolean defaultValue) {
final CarrierConfigManager configManager = getCarrierConfigManager(mContext);
boolean ret = false;
if (configManager != null) {
@@ -302,9 +522,6 @@ public class WifiCallingSliceHelper {
* Returns the current default voice subId obtained from SubscriptionManager
*/
protected int getDefaultVoiceSubId() {
- if (mSubscriptionManager == null) {
- mSubscriptionManager = mContext.getSystemService(SubscriptionManager.class);
- }
return SubscriptionManager.getDefaultVoiceSubscriptionId();
}
@@ -350,6 +567,7 @@ public class WifiCallingSliceHelper {
private PendingIntent getBroadcastIntent(String action) {
final Intent intent = new Intent(action);
intent.setClass(mContext, SliceBroadcastReceiver.class);
+ intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
return PendingIntent.getBroadcast(mContext, 0 /* requestCode */, intent,
PendingIntent.FLAG_CANCEL_CURRENT);
}
@@ -362,17 +580,4 @@ public class WifiCallingSliceHelper {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
return PendingIntent.getActivity(mContext, 0 /* requestCode */, intent, 0 /* flags */);
}
-
- /**
- * Returns carrier id name of the current Subscription
- */
- private String getSimCarrierName() {
- final TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
- final CharSequence carrierName = telephonyManager.getSimCarrierIdName();
- if (carrierName == null) {
- return mContext.getString(R.string.carrier);
- }
- return carrierName.toString();
- }
-
}
diff --git a/tests/robotests/src/com/android/settings/mobilenetwork/Enhanced4gLteSliceHelperTest.java b/tests/robotests/src/com/android/settings/mobilenetwork/Enhanced4gLteSliceHelperTest.java
new file mode 100644
index 00000000000..625a68bef85
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/mobilenetwork/Enhanced4gLteSliceHelperTest.java
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.mobilenetwork;
+
+import static android.app.slice.Slice.EXTRA_TOGGLE_STATE;
+import static android.app.slice.Slice.HINT_TITLE;
+import static android.app.slice.SliceItem.FORMAT_TEXT;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.telephony.CarrierConfigManager;
+
+import androidx.slice.Slice;
+import androidx.slice.SliceItem;
+import androidx.slice.SliceMetadata;
+import androidx.slice.SliceProvider;
+import androidx.slice.core.SliceAction;
+import androidx.slice.core.SliceQuery;
+import androidx.slice.widget.SliceLiveData;
+
+import com.android.ims.ImsManager;
+import com.android.settings.R;
+import com.android.settings.slices.SettingsSliceProvider;
+import com.android.settings.slices.SliceBroadcastReceiver;
+import com.android.settings.slices.SlicesFeatureProvider;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+
+import java.util.List;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class Enhanced4gLteSliceHelperTest {
+
+ private Context mContext;
+ @Mock
+ private CarrierConfigManager mMockCarrierConfigManager;
+
+ @Mock
+ private ImsManager mMockImsManager;
+
+ private FakeEnhanced4gLteSliceHelper mEnhanced4gLteSliceHelper;
+ private SettingsSliceProvider mProvider;
+ private SliceBroadcastReceiver mReceiver;
+ private FakeFeatureFactory mFeatureFactory;
+ private SlicesFeatureProvider mSlicesFeatureProvider;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = spy(RuntimeEnvironment.application);
+
+ //setup for SettingsSliceProvider tests
+ mProvider = spy(new SettingsSliceProvider());
+ doReturn(mContext).when(mProvider).getContext();
+
+ //setup for SliceBroadcastReceiver test
+ mReceiver = spy(new SliceBroadcastReceiver());
+
+ mFeatureFactory = FakeFeatureFactory.setupForTest();
+ mSlicesFeatureProvider = mFeatureFactory.getSlicesFeatureProvider();
+
+ // Prevent crash in SliceMetadata.
+ Resources resources = spy(mContext.getResources());
+ doReturn(60).when(resources).getDimensionPixelSize(anyInt());
+ doReturn(resources).when(mContext).getResources();
+
+ mEnhanced4gLteSliceHelper = new FakeEnhanced4gLteSliceHelper(mContext);
+
+ // Set-up specs for SliceMetadata.
+ SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
+ }
+
+ @Test
+ public void test_CreateEnhanced4gLteSlice_invalidSubId() {
+ mEnhanced4gLteSliceHelper.setDefaultVoiceSubId(-1);
+
+ final Slice slice = mEnhanced4gLteSliceHelper.createEnhanced4gLteSlice(
+ Enhanced4gLteSliceHelper.SLICE_URI);
+
+ assertThat(slice).isNull();
+ }
+
+ @Test
+ public void test_CreateEnhanced4gLteSlice_enhanced4gLteNotSupported() {
+ when(mMockImsManager.isVolteEnabledByPlatform()).thenReturn(false);
+
+ final Slice slice = mEnhanced4gLteSliceHelper.createEnhanced4gLteSlice(
+ Enhanced4gLteSliceHelper.SLICE_URI);
+
+ assertThat(mEnhanced4gLteSliceHelper.getDefaultVoiceSubId()).isEqualTo(1);
+ assertThat(slice).isNull();
+ }
+
+ @Test
+ public void test_CreateEnhanced4gLteSlice_success() {
+ when(mMockImsManager.isVolteEnabledByPlatform()).thenReturn(true);
+ when(mMockImsManager.isVolteProvisionedOnDevice()).thenReturn(true);
+ when(mMockImsManager.isEnhanced4gLteModeSettingEnabledByUser()).thenReturn(true);
+ when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(true);
+ when(mMockCarrierConfigManager.getConfigForSubId(1)).thenReturn(null);
+
+ final Slice slice = mEnhanced4gLteSliceHelper.createEnhanced4gLteSlice(
+ Enhanced4gLteSliceHelper.SLICE_URI);
+
+ assertThat(mEnhanced4gLteSliceHelper.getDefaultVoiceSubId()).isEqualTo(1);
+ testEnhanced4gLteSettingsToggleSlice(slice);
+ }
+
+ @Test
+ public void test_SettingSliceProvider_getsRightSliceEnhanced4gLte() {
+ when(mMockImsManager.isVolteEnabledByPlatform()).thenReturn(true);
+ when(mMockImsManager.isVolteProvisionedOnDevice()).thenReturn(true);
+ when(mMockImsManager.isEnhanced4gLteModeSettingEnabledByUser()).thenReturn(true);
+ when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(true);
+ when(mMockCarrierConfigManager.getConfigForSubId(1)).thenReturn(null);
+ when(mSlicesFeatureProvider.getNewEnhanced4gLteSliceHelper(mContext))
+ .thenReturn(mEnhanced4gLteSliceHelper);
+
+ final Slice slice = mProvider.onBindSlice(Enhanced4gLteSliceHelper.SLICE_URI);
+
+ assertThat(mEnhanced4gLteSliceHelper.getDefaultVoiceSubId()).isEqualTo(1);
+ testEnhanced4gLteSettingsToggleSlice(slice);
+ }
+
+ @Test
+ public void test_SliceBroadcastReceiver_toggleOffEnhanced4gLte() {
+ when(mMockImsManager.isVolteEnabledByPlatform()).thenReturn(true);
+ when(mMockImsManager.isVolteProvisionedOnDevice()).thenReturn(true);
+ when(mMockImsManager.isEnhanced4gLteModeSettingEnabledByUser()).thenReturn(false);
+ when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(true);
+ when(mSlicesFeatureProvider.getNewEnhanced4gLteSliceHelper(mContext))
+ .thenReturn(mEnhanced4gLteSliceHelper);
+
+ ArgumentCaptor mEnhanced4gLteSettingCaptor = ArgumentCaptor.forClass(
+ Boolean.class);
+
+ // turn on Enhanced4gLte setting
+ Intent intent = new Intent(Enhanced4gLteSliceHelper.ACTION_ENHANCED_4G_LTE_CHANGED);
+ intent.putExtra(EXTRA_TOGGLE_STATE, true);
+
+ // change the setting
+ mReceiver.onReceive(mContext, intent);
+
+ verify((mMockImsManager)).setEnhanced4gLteModeSetting(
+ mEnhanced4gLteSettingCaptor.capture());
+
+ // assert the change
+ assertThat(mEnhanced4gLteSettingCaptor.getValue()).isTrue();
+ }
+
+ private void testEnhanced4gLteSettingsUnavailableSlice(Slice slice,
+ PendingIntent expectedPrimaryAction) {
+ final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
+
+ //Check there is no toggle action
+ final List toggles = metadata.getToggles();
+ assertThat(toggles).isEmpty();
+
+ // Check whether the primary action is to open Enhanced4gLte settings activity
+ final PendingIntent primaryPendingIntent =
+ metadata.getPrimaryAction().getAction();
+ assertThat(primaryPendingIntent).isEqualTo(expectedPrimaryAction);
+
+ // Check the title
+ final List sliceItems = slice.getItems();
+ assertTitle(sliceItems, mContext.getString(R.string.enhanced_4g_lte_mode_title));
+ }
+
+ private void testEnhanced4gLteSettingsToggleSlice(Slice slice) {
+ final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
+
+ final List toggles = metadata.getToggles();
+ assertThat(toggles).hasSize(1);
+
+ final SliceAction mainToggleAction = toggles.get(0);
+
+ // Check intent in Toggle Action
+ final PendingIntent togglePendingIntent = mainToggleAction.getAction();
+ final PendingIntent expectedToggleIntent = getBroadcastIntent(
+ Enhanced4gLteSliceHelper.ACTION_ENHANCED_4G_LTE_CHANGED);
+ assertThat(togglePendingIntent).isEqualTo(expectedToggleIntent);
+
+ // Check primary intent
+ final PendingIntent primaryPendingIntent = metadata.getPrimaryAction().getAction();
+ final PendingIntent expectedPendingIntent =
+ getActivityIntent(Enhanced4gLteSliceHelper.ACTION_MOBILE_NETWORK_SETTINGS_ACTIVITY);
+ assertThat(primaryPendingIntent).isEqualTo(expectedPendingIntent);
+
+ // Check the title
+ final List sliceItems = slice.getItems();
+ assertTitle(sliceItems, mContext.getString(R.string.enhanced_4g_lte_mode_title));
+ }
+
+ private PendingIntent getBroadcastIntent(String action) {
+ final Intent intent = new Intent(action);
+ intent.setClass(mContext, SliceBroadcastReceiver.class);
+ return PendingIntent.getBroadcast(mContext, 0 /* requestCode */, intent,
+ PendingIntent.FLAG_CANCEL_CURRENT);
+ }
+
+ private PendingIntent getActivityIntent(String action) {
+ final Intent intent = new Intent(action);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ return PendingIntent.getActivity(mContext, 0 /* requestCode */, intent, 0 /* flags */);
+ }
+
+ private void assertTitle(List sliceItems, String title) {
+ boolean hasTitle = false;
+ for (SliceItem item : sliceItems) {
+ List titleItems = SliceQuery.findAll(item, FORMAT_TEXT, HINT_TITLE,
+ null /* non-hints */);
+ if (titleItems == null) {
+ continue;
+ }
+
+ hasTitle = true;
+ for (SliceItem subTitleItem : titleItems) {
+ assertThat(subTitleItem.getText()).isEqualTo(title);
+ }
+ }
+ assertThat(hasTitle).isTrue();
+ }
+
+ private class FakeEnhanced4gLteSliceHelper extends Enhanced4gLteSliceHelper {
+ int mSubId = 1;
+
+ FakeEnhanced4gLteSliceHelper(Context context) {
+ super(context);
+ }
+
+ @Override
+ protected CarrierConfigManager getCarrierConfigManager() {
+ return mMockCarrierConfigManager;
+ }
+
+ @Override
+ protected ImsManager getImsManager(int subId) {
+ return mMockImsManager;
+ }
+
+ protected int getDefaultVoiceSubId() {
+ return mSubId;
+ }
+
+ protected void setDefaultVoiceSubId(int id) {
+ mSubId = id;
+ }
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/nfc/PaymentSettingsTest.java b/tests/robotests/src/com/android/settings/nfc/PaymentSettingsTest.java
index 02687115493..b85bddad55e 100644
--- a/tests/robotests/src/com/android/settings/nfc/PaymentSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/nfc/PaymentSettingsTest.java
@@ -18,11 +18,16 @@
package com.android.settings.nfc;
import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
+import android.os.UserHandle;
+import android.os.UserManager;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
@@ -45,22 +50,31 @@ public class PaymentSettingsTest {
static final String PAYMENT_KEY = "nfc_payment";
static final String FOREGROUND_KEY = "nfc_foreground";
+ static final String PAYMENT_SCREEN_KEY = "nfc_payment_settings_screen";
private Context mContext;
@Mock
- private PackageManager mManager;
+ private PackageManager mPackageManager;
+
+ @Mock
+ private UserManager mUserManager;
+
+ @Mock
+ private UserInfo mUserInfo;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
- when(mContext.getPackageManager()).thenReturn(mManager);
+ when(mContext.getPackageManager()).thenReturn(mPackageManager);
+ doReturn(mUserManager).when(mContext).getSystemService(UserManager.class);
+ when(mUserManager.getUserInfo(UserHandle.myUserId())).thenReturn(mUserInfo);
}
@Test
- public void getNonIndexableKey_NoNFC_AllKeysAdded() {
- when(mManager.hasSystemFeature(PackageManager.FEATURE_NFC)).thenReturn(false);
+ public void getNonIndexableKey_noNFC_allKeysAdded() {
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_NFC)).thenReturn(false);
final List niks =
PaymentSettings.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext);
@@ -70,8 +84,8 @@ public class PaymentSettingsTest {
}
@Test
- public void getNonIndexableKey_NFC_ForegroundKeyAdded() {
- when(mManager.hasSystemFeature(PackageManager.FEATURE_NFC)).thenReturn(true);
+ public void getNonIndexableKey_NFC_foregroundKeyAdded() {
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_NFC)).thenReturn(true);
final List niks =
PaymentSettings.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext);
@@ -79,6 +93,27 @@ public class PaymentSettingsTest {
assertThat(niks).contains(FOREGROUND_KEY);
}
+ @Test
+ public void getNonIndexableKey_primaryUser_returnsTrue() {
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_NFC)).thenReturn(true);
+
+ final List niks =
+ PaymentSettings.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext);
+
+ assertThat(niks).containsExactly(FOREGROUND_KEY);
+ }
+
+ @Test
+ public void getNonIndexabkeKey_guestUser_returnsFalse() {
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_NFC)).thenReturn(true);
+ when(mUserInfo.isGuest()).thenReturn(true);
+
+ final List niks =
+ PaymentSettings.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext);
+
+ assertThat(niks).containsAllOf(FOREGROUND_KEY, PAYMENT_KEY, PAYMENT_SCREEN_KEY);
+ }
+
@Implements(PaymentBackend.class)
public static class ShadowPaymentBackend {
private ArrayList mAppInfos;
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeStarredContactsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeStarredContactsPreferenceControllerTest.java
index 9a2bccd6b15..064c0911319 100644
--- a/tests/robotests/src/com/android/settings/notification/ZenModeStarredContactsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeStarredContactsPreferenceControllerTest.java
@@ -23,12 +23,25 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.doAnswer;
+import org.mockito.stubbing.Answer;
+import org.mockito.invocation.InvocationOnMock;
import android.app.NotificationManager;
import android.content.ComponentName;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
+import android.database.CharArrayBuffer;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.database.DataSetObserver;
+import android.net.Uri;
+import android.os.Bundle;
+
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
@@ -42,6 +55,8 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.util.ReflectionHelpers;
+import java.util.ArrayList;
+import java.util.List;
@RunWith(SettingsRobolectricTestRunner.class)
public class ZenModeStarredContactsPreferenceControllerTest {
@@ -148,4 +163,31 @@ public class ZenModeStarredContactsPreferenceControllerTest {
assertThat(mMessagesController.isAvailable()).isTrue();
}
+
+ @Test
+ public void updateSummary_nullCursorValues() {
+ Cursor testCursorWithNullValues = mock(Cursor.class);
+ when(testCursorWithNullValues.moveToFirst()).thenReturn(true);
+
+ doAnswer(new Answer() {
+ int count = 0;
+ @Override
+ public Boolean answer(InvocationOnMock invocation) throws Throwable {
+ if (count < 3) {
+ count++;
+ return true;
+ }
+ return false;
+ }
+
+ }).when(testCursorWithNullValues).moveToNext();
+
+ when(testCursorWithNullValues.getString(0)).thenReturn(null);
+
+ // expected - no null values
+ List contacts = mMessagesController.getStarredContacts(testCursorWithNullValues);
+ for (int i = 0 ; i < contacts.size(); i++) {
+ assertThat(contacts.get(i)).isNotNull();
+ }
+ }
}
diff --git a/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSliceHelperTest.java b/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSliceHelperTest.java
index 21f6daa3428..6388297eaeb 100644
--- a/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSliceHelperTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSliceHelperTest.java
@@ -20,9 +20,12 @@ import static android.app.slice.Slice.EXTRA_TOGGLE_STATE;
import static android.app.slice.Slice.HINT_TITLE;
import static android.app.slice.SliceItem.FORMAT_TEXT;
+import static com.android.settings.slices.SettingsSliceProvider.EXTRA_SLICE_PLATFORM_DEFINED;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
@@ -41,8 +44,11 @@ import androidx.slice.SliceMetadata;
import androidx.slice.SliceProvider;
import androidx.slice.core.SliceAction;
import androidx.slice.core.SliceQuery;
+import androidx.slice.widget.ListContent;
+import androidx.slice.widget.RowContent;
import androidx.slice.widget.SliceLiveData;
+import com.android.ims.ImsConfig;
import com.android.ims.ImsManager;
import com.android.settings.R;
import com.android.settings.slices.SettingsSliceProvider;
@@ -61,6 +67,8 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
+import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
@RunWith(SettingsRobolectricTestRunner.class)
@@ -73,8 +81,6 @@ public class WifiCallingSliceHelperTest {
@Mock
private ImsManager mMockImsManager;
- private final Uri mWfcURI = Uri.parse("content://com.android.settings.slices/wifi_calling");
-
private FakeWifiCallingSliceHelper mWfcSliceHelper;
private SettingsSliceProvider mProvider;
private SliceBroadcastReceiver mReceiver;
@@ -111,21 +117,21 @@ public class WifiCallingSliceHelperTest {
public void test_CreateWifiCallingSlice_invalidSubId() {
mWfcSliceHelper.setDefaultVoiceSubId(-1);
- final Slice slice = mWfcSliceHelper.createWifiCallingSlice(mWfcURI);
+ final Slice slice = mWfcSliceHelper.createWifiCallingSlice(
+ WifiCallingSliceHelper.WIFI_CALLING_URI);
- testWifiCallingSettingsUnavailableSlice(slice, null,
- WifiCallingSliceHelper.getSettingsIntent(mContext));
+ assertThat(slice).isNull();
}
@Test
public void test_CreateWifiCallingSlice_wfcNotSupported() {
- doReturn(false).when(mMockImsManager).isWfcEnabledByPlatform();
+ when(mMockImsManager.isWfcEnabledByPlatform()).thenReturn(false);
- final Slice slice = mWfcSliceHelper.createWifiCallingSlice(mWfcURI);
+ final Slice slice = mWfcSliceHelper.createWifiCallingSlice(
+ WifiCallingSliceHelper.WIFI_CALLING_URI);
assertThat(mWfcSliceHelper.getDefaultVoiceSubId()).isEqualTo(1);
- testWifiCallingSettingsUnavailableSlice(slice, null,
- WifiCallingSliceHelper.getSettingsIntent(mContext));
+ assertThat(slice).isNull();
}
@Test
@@ -135,29 +141,32 @@ public class WifiCallingSliceHelperTest {
turned off) we need to guide the user to wifi calling settings
activity so the user can perform the activation there.(PrimaryAction)
*/
- doReturn(true).when(mMockImsManager).isWfcEnabledByPlatform();
- doReturn(true).when(mMockImsManager).isWfcProvisionedOnDevice();
- doReturn(false).when(mMockImsManager).isWfcEnabledByUser();
- doReturn(false).when(mMockImsManager).isNonTtyOrTtyOnVolteEnabled();
- doReturn(null).when(mMockCarrierConfigManager).getConfigForSubId(1);
+ when(mMockImsManager.isWfcEnabledByPlatform()).thenReturn(true);
+ when(mMockImsManager.isWfcProvisionedOnDevice()).thenReturn(true);
+ when(mMockImsManager.isWfcEnabledByUser()).thenReturn(false);
+ when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(false);
+ when(mMockCarrierConfigManager.getConfigForSubId(1)).thenReturn(null);
mWfcSliceHelper.setActivationAppIntent(new Intent()); // dummy Intent
- final Slice slice = mWfcSliceHelper.createWifiCallingSlice(mWfcURI);
+ final Slice slice = mWfcSliceHelper.createWifiCallingSlice(
+ WifiCallingSliceHelper.WIFI_CALLING_URI);
assertThat(mWfcSliceHelper.getDefaultVoiceSubId()).isEqualTo(1);
testWifiCallingSettingsUnavailableSlice(slice, null,
- getActivityIntent(WifiCallingSliceHelper.ACTION_WIFI_CALLING_SETTINGS_ACTIVITY));
+ getActivityIntent(WifiCallingSliceHelper.ACTION_WIFI_CALLING_SETTINGS_ACTIVITY),
+ mContext.getString(R.string.wifi_calling_settings_title));
}
@Test
public void test_CreateWifiCallingSlice_success() {
- doReturn(true).when(mMockImsManager).isWfcEnabledByPlatform();
- doReturn(true).when(mMockImsManager).isWfcProvisionedOnDevice();
- doReturn(true).when(mMockImsManager).isWfcEnabledByUser();
- doReturn(true).when(mMockImsManager).isNonTtyOrTtyOnVolteEnabled();
- doReturn(null).when(mMockCarrierConfigManager).getConfigForSubId(1);
+ when(mMockImsManager.isWfcEnabledByPlatform()).thenReturn(true);
+ when(mMockImsManager.isWfcProvisionedOnDevice()).thenReturn(true);
+ when(mMockImsManager.isWfcEnabledByUser()).thenReturn(true);
+ when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(true);
+ when(mMockCarrierConfigManager.getConfigForSubId(1)).thenReturn(null);
- final Slice slice = mWfcSliceHelper.createWifiCallingSlice(mWfcURI);
+ final Slice slice = mWfcSliceHelper.createWifiCallingSlice(
+ WifiCallingSliceHelper.WIFI_CALLING_URI);
assertThat(mWfcSliceHelper.getDefaultVoiceSubId()).isEqualTo(1);
testWifiCallingSettingsToggleSlice(slice, null);
@@ -165,28 +174,28 @@ public class WifiCallingSliceHelperTest {
@Test
public void test_SettingSliceProvider_getsRightSliceWifiCalling() {
- doReturn(true).when(mMockImsManager).isWfcEnabledByPlatform();
- doReturn(true).when(mMockImsManager).isWfcProvisionedOnDevice();
- doReturn(true).when(mMockImsManager).isWfcEnabledByUser();
- doReturn(true).when(mMockImsManager).isNonTtyOrTtyOnVolteEnabled();
- doReturn(null).when(mMockCarrierConfigManager).getConfigForSubId(1);
- doReturn(mWfcSliceHelper).when(mSlicesFeatureProvider)
- .getNewWifiCallingSliceHelper(mContext);
+ when(mMockImsManager.isWfcEnabledByPlatform()).thenReturn(true);
+ when(mMockImsManager.isWfcProvisionedOnDevice()).thenReturn(true);
+ when(mMockImsManager.isWfcEnabledByUser()).thenReturn(true);
+ when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(true);
+ when(mMockCarrierConfigManager.getConfigForSubId(1)).thenReturn(null);
+ when(mSlicesFeatureProvider.getNewWifiCallingSliceHelper(mContext))
+ .thenReturn(mWfcSliceHelper);
- final Slice slice = mProvider.onBindSlice(mWfcURI);
+ final Slice slice = mProvider.onBindSlice(WifiCallingSliceHelper.WIFI_CALLING_URI);
assertThat(mWfcSliceHelper.getDefaultVoiceSubId()).isEqualTo(1);
testWifiCallingSettingsToggleSlice(slice, null);
}
@Test
- public void test_SliceBroadcastReceiver_toggleOffWifiCalling() {
- doReturn(true).when(mMockImsManager).isWfcEnabledByPlatform();
- doReturn(true).when(mMockImsManager).isWfcProvisionedOnDevice();
- doReturn(false).when(mMockImsManager).isWfcEnabledByUser();
- doReturn(true).when(mMockImsManager).isNonTtyOrTtyOnVolteEnabled();
- doReturn(mWfcSliceHelper).when(mSlicesFeatureProvider)
- .getNewWifiCallingSliceHelper(mContext);
+ public void test_SliceBroadcastReceiver_toggleOnWifiCalling() {
+ when(mMockImsManager.isWfcEnabledByPlatform()).thenReturn(true);
+ when(mMockImsManager.isWfcProvisionedOnDevice()).thenReturn(true);
+ when(mMockImsManager.isWfcEnabledByUser()).thenReturn(false);
+ when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(true);
+ when(mSlicesFeatureProvider.getNewWifiCallingSliceHelper(mContext))
+ .thenReturn(mWfcSliceHelper);
mWfcSliceHelper.setActivationAppIntent(null);
ArgumentCaptor mWfcSettingCaptor = ArgumentCaptor.forClass(Boolean.class);
@@ -204,8 +213,104 @@ public class WifiCallingSliceHelperTest {
assertThat(mWfcSettingCaptor.getValue()).isTrue();
}
+ @Test
+ public void test_CreateWifiCallingPreferenceSlice_prefNotEditable() {
+ when(mMockImsManager.isWfcEnabledByPlatform()).thenReturn(true);
+ when(mMockImsManager.isWfcProvisionedOnDevice()).thenReturn(true);
+ when(mMockImsManager.isWfcEnabledByUser()).thenReturn(true);
+ when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(true);
+ mWfcSliceHelper.setIsWifiCallingPrefEditable(false);
+
+ final Slice slice = mWfcSliceHelper.createWifiCallingPreferenceSlice(
+ WifiCallingSliceHelper.WIFI_CALLING_PREFERENCE_URI);
+
+ assertThat(mWfcSliceHelper.getDefaultVoiceSubId()).isEqualTo(1);
+ assertThat(slice).isNull();
+ }
+
+ @Test
+ public void test_CreateWifiCallingPreferenceSlice_wfcOff() {
+ when(mMockImsManager.isWfcEnabledByPlatform()).thenReturn(true);
+ when(mMockImsManager.isWfcProvisionedOnDevice()).thenReturn(true);
+ when(mMockImsManager.isWfcEnabledByUser()).thenReturn(false);
+ when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(true);
+ mWfcSliceHelper.setIsWifiCallingPrefEditable(true);
+
+ final Slice slice = mWfcSliceHelper.createWifiCallingPreferenceSlice(
+ WifiCallingSliceHelper.WIFI_CALLING_PREFERENCE_URI);
+
+ assertThat(mWfcSliceHelper.getDefaultVoiceSubId()).isEqualTo(1);
+ testWifiCallingSettingsUnavailableSlice(slice, null,
+ getActivityIntent(WifiCallingSliceHelper.ACTION_WIFI_CALLING_SETTINGS_ACTIVITY),
+ mContext.getString(R.string.wifi_calling_mode_title));
+ }
+
+ @Test
+ public void test_CreateWifiCallingPreferenceSlice_success() {
+ when(mMockImsManager.isWfcEnabledByPlatform()).thenReturn(true);
+ when(mMockImsManager.isWfcProvisionedOnDevice()).thenReturn(true);
+ when(mMockImsManager.isWfcEnabledByUser()).thenReturn(true);
+ when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(true);
+ when(mMockImsManager.getWfcMode(false)).thenReturn(
+ ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED);
+ mWfcSliceHelper.setIsWifiCallingPrefEditable(true);
+
+ final Slice slice = mWfcSliceHelper.createWifiCallingPreferenceSlice(
+ WifiCallingSliceHelper.WIFI_CALLING_PREFERENCE_URI);
+
+ assertThat(mWfcSliceHelper.getDefaultVoiceSubId()).isEqualTo(1);
+ testWifiCallingPreferenceSlice(slice, null,
+ getActivityIntent(WifiCallingSliceHelper.ACTION_WIFI_CALLING_SETTINGS_ACTIVITY));
+ }
+
+ @Test
+ public void test_SettingsSliceProvider_getWfcPreferenceSlice() {
+ when(mMockImsManager.isWfcEnabledByPlatform()).thenReturn(true);
+ when(mMockImsManager.isWfcProvisionedOnDevice()).thenReturn(true);
+ when(mMockImsManager.isWfcEnabledByUser()).thenReturn(true);
+ when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(true);
+ when(mMockImsManager.getWfcMode(false)).thenReturn(
+ ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED);
+ when(mSlicesFeatureProvider.getNewWifiCallingSliceHelper(mContext))
+ .thenReturn(mWfcSliceHelper);
+ mWfcSliceHelper.setIsWifiCallingPrefEditable(true);
+
+ final Slice slice = mProvider.onBindSlice(
+ WifiCallingSliceHelper.WIFI_CALLING_PREFERENCE_URI);
+
+ assertThat(mWfcSliceHelper.getDefaultVoiceSubId()).isEqualTo(1);
+ testWifiCallingPreferenceSlice(slice, null,
+ getActivityIntent(WifiCallingSliceHelper.ACTION_WIFI_CALLING_SETTINGS_ACTIVITY));
+ }
+ @Test
+ public void test_SliceBroadcastReceiver_setWfcPrefCellularPref() {
+ when(mMockImsManager.isWfcEnabledByPlatform()).thenReturn(true);
+ when(mMockImsManager.isWfcProvisionedOnDevice()).thenReturn(true);
+ when(mMockImsManager.isWfcEnabledByUser()).thenReturn(true);
+ when(mMockImsManager.isNonTtyOrTtyOnVolteEnabled()).thenReturn(true);
+ when(mMockImsManager.getWfcMode(false)).thenReturn(
+ ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED);
+ when(mSlicesFeatureProvider.getNewWifiCallingSliceHelper(mContext))
+ .thenReturn(mWfcSliceHelper);
+ mWfcSliceHelper.setIsWifiCallingPrefEditable(true);
+
+ ArgumentCaptor mWfcPreferenceCaptor = ArgumentCaptor.forClass(Integer.class);
+
+ // Change preference to Cellular pref
+ Intent intent = new Intent(
+ WifiCallingSliceHelper.ACTION_WIFI_CALLING_PREFERENCE_CELLULAR_PREFERRED);
+
+ mReceiver.onReceive(mContext, intent);
+
+ verify((mMockImsManager)).setWfcMode(mWfcPreferenceCaptor.capture(), eq(false));
+
+ // assert the change
+ assertThat(mWfcPreferenceCaptor.getValue()).isEqualTo(
+ ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED);
+ }
+
private void testWifiCallingSettingsUnavailableSlice(Slice slice,
- SliceData sliceData, PendingIntent expectedPrimaryAction) {
+ SliceData sliceData, PendingIntent expectedPrimaryAction, String title) {
final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
//Check there is no toggle action
@@ -219,7 +324,7 @@ public class WifiCallingSliceHelperTest {
// Check the title
final List sliceItems = slice.getItems();
- assertTitle(sliceItems, mContext.getString(R.string.wifi_calling_settings_title));
+ assertTitle(sliceItems, title);
}
private void testWifiCallingSettingsToggleSlice(Slice slice,
@@ -248,6 +353,51 @@ public class WifiCallingSliceHelperTest {
assertTitle(sliceItems, mContext.getString(R.string.wifi_calling_settings_title));
}
+ private void testWifiCallingPreferenceSlice(Slice slice, SliceData sliceData,
+ PendingIntent expectedPrimaryAction) {
+ final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
+
+ //Check there is no toggle action
+ final List toggles = metadata.getToggles();
+ assertThat(toggles).isEmpty();
+
+ // Check whether the primary action is to open wifi calling settings activity
+ final PendingIntent primaryPendingIntent =
+ metadata.getPrimaryAction().getAction();
+ assertThat(primaryPendingIntent).isEqualTo(expectedPrimaryAction);
+
+ // Get all the rows
+ final ListContent listContent = new ListContent(mContext, slice);
+ final ArrayList rowItems = listContent.getRowItems();
+
+ assertThat(rowItems.size()).isEqualTo(4 /* 4 items including header */);
+
+ // First row is HEADER
+ SliceItem rowSliceItem = rowItems.get(0);
+ RowContent rowContent = new RowContent(mContext, rowSliceItem, true);
+ assertThat(rowContent.getTitleItem().getText()).isEqualTo(mContext.getText(
+ R.string.wifi_calling_mode_title));
+
+ // next is WIFI_ONLY
+ rowSliceItem = rowItems.get(1);
+ rowContent = new RowContent(mContext, rowSliceItem, false);
+ assertThat(rowContent.getTitleItem().getText()).isEqualTo(mContext.getText(
+ com.android.internal.R.string.wfc_mode_wifi_only_summary));
+
+ // next is WIFI_PREFERRED
+ rowSliceItem = rowItems.get(2);
+ rowContent = new RowContent(mContext, rowSliceItem, false);
+ assertThat(rowContent.getTitleItem().getText()).isEqualTo(mContext.getText(
+ com.android.internal.R.string.wfc_mode_wifi_preferred_summary));
+
+ // next is CELLULAR_PREFERRED
+ rowSliceItem = rowItems.get(3);
+ rowContent = new RowContent(mContext, rowSliceItem, false);
+ assertThat(rowContent.getTitleItem().getText()).isEqualTo(mContext.getText(
+ com.android.internal.R.string.wfc_mode_cellular_preferred_summary));
+
+ }
+
private PendingIntent getBroadcastIntent(String action) {
final Intent intent = new Intent(action);
intent.setClass(mContext, SliceBroadcastReceiver.class);
@@ -279,6 +429,8 @@ public class WifiCallingSliceHelperTest {
}
private class FakeWifiCallingSliceHelper extends WifiCallingSliceHelper {
int mSubId = 1;
+ boolean isWifiCallingPrefEditable = true;
+ boolean isWifiOnlySupported = true;
private Intent mActivationAppIntent;
FakeWifiCallingSliceHelper(Context context) {
@@ -308,9 +460,23 @@ public class WifiCallingSliceHelperTest {
protected Intent getWifiCallingCarrierActivityIntent(int subId) {
return mActivationAppIntent;
}
+ @Override
+ protected boolean isCarrierConfigManagerKeyEnabled(String key, int subId,
+ boolean defaultValue) {
+ if(key.equals(CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL)) {
+ return isWifiCallingPrefEditable;
+ } else if(key.equals(CarrierConfigManager.KEY_CARRIER_WFC_SUPPORTS_WIFI_ONLY_BOOL)) {
+ return isWifiOnlySupported;
+ }
+ return defaultValue;
+ }
public void setActivationAppIntent(Intent intent) {
mActivationAppIntent = intent;
}
+
+ public void setIsWifiCallingPrefEditable(boolean isWifiCallingPrefEditable) {
+ this.isWifiCallingPrefEditable = isWifiCallingPrefEditable;
+ }
}
}