Add Wifi calling Preference slice and other cleanup

WifiCallingPreference Slice Provider:
  1. If Wifi calling is not enabled - display message to user
     to enable Wifi calling
  2. Else if Wifi preference is not editable - return a null
     Slice
  3. Else provide a slice with rows - first row giving current pref
     information, followed by preference items (in each row).
     wifi_only is displayed only when it is allowed to display it.
     Each row with preference item has specific intent action.
WifiCallingPreference Slice BroadcastReceiver:
   1. If only Wifi calling is enabled & Wifi preference is editable &
      there is a change in current value modify wifi pref setting
   2. And Ask to re-query the slice in one second to display
      updated settings if 1 is valid or display appropriate message.
Clean-up:
   1. Return null instead of non-actionable slices.
   2. Use getText to get string resources.
   3. Remove unnecessary extra variables.

Bug: 79548264
Test: Use support-slices-demos-debug.apk to test on device
Change-Id: I186f19be2007c2331eaf6195e70b4a9c635adf9e
This commit is contained in:
Naina Nalluri
2018-05-21 11:53:24 -07:00
parent 606222da7f
commit 6b1869351a
7 changed files with 552 additions and 91 deletions

View File

@@ -0,0 +1,24 @@
<!--
~ 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>

View File

@@ -0,0 +1,24 @@
<!--
~ 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>

View File

@@ -0,0 +1,26 @@
<?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>

View File

@@ -211,6 +211,11 @@ public class SettingsSliceProvider extends SliceProvider {
.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);

View File

@@ -25,6 +25,9 @@ import static com.android.settings.slices.SettingsSliceProvider.EXTRA_SLICE_PLAT
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;
@@ -91,6 +94,14 @@ public class SliceBroadcastReceiver extends 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)) {

View File

@@ -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<Integer> wfcModeTask = new FutureTask<>(new Callable<Integer>() {
@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();
}
}

View File

@@ -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<Boolean> 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<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
@@ -219,7 +324,7 @@ public class WifiCallingSliceHelperTest {
// 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,
@@ -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<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);
@@ -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;
}
}
}