--- /dev/null
+<!--
+ ~ Copyright 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.
+ -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M12,7c-2.76,0 -5,2.24 -5,5s2.24,5 5,5 5,-2.24 5,-5 -2.24,-5 -5,-5zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z"/>
+</vector>
--- /dev/null
+<!--
+ ~ Copyright 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.
+ -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z"/>
+</vector>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright 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.
+ -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:id="@+id/on"
+ android:state_checked="true"
+ android:drawable="@drawable/ic_radio_button_checked_black_24dp" />
+ <item
+ android:id="@+id/off"
+ android:state_checked="false"
+ android:drawable="@drawable/ic_radio_button_unchecked_black_24dp" />
+</selector>
\ No newline at end of file
.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);
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;
.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)) {
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;
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
* related settings
.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
*/
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);
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 {
// 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;
}
}
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),
.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<Integer> wfcModeTask = new FutureTask<>(new Callable<Integer>() {
@Override
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,
}
/**
+ * 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.
*
* @param title Title of the slice
* @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)
/**
* 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) {
* Returns the current default voice subId obtained from SubscriptionManager
*/
protected int getDefaultVoiceSubId() {
- if (mSubscriptionManager == null) {
- mSubscriptionManager = mContext.getSystemService(SubscriptionManager.class);
- }
return SubscriptionManager.getDefaultVoiceSubscriptionId();
}
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);
}
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();
- }
-
}
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;
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;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
+import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
@RunWith(SettingsRobolectricTestRunner.class)
@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;
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
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);
@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<Boolean> mWfcSettingCaptor = ArgumentCaptor.forClass(Boolean.class);
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<Integer> 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
// Check the title
final List<SliceItem> sliceItems = slice.getItems();
- assertTitle(sliceItems, mContext.getString(R.string.wifi_calling_settings_title));
+ assertTitle(sliceItems, title);
}
private void testWifiCallingSettingsToggleSlice(Slice slice,
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<SliceAction> 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<SliceItem> 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);
}
private class FakeWifiCallingSliceHelper extends WifiCallingSliceHelper {
int mSubId = 1;
+ boolean isWifiCallingPrefEditable = true;
+ boolean isWifiOnlySupported = true;
private Intent mActivationAppIntent;
FakeWifiCallingSliceHelper(Context context) {
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;
+ }
}
}