Merge "Migrate to new ImsRegistrationCallback" into main
This commit is contained in:
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2024 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.deviceinfo.simstatus
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.telephony.SubscriptionManager
|
||||||
|
import androidx.lifecycle.Lifecycle
|
||||||
|
import androidx.lifecycle.LifecycleOwner
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
|
import com.android.settings.network.telephony.SimSlotRepository
|
||||||
|
import com.android.settings.network.telephony.ims.ImsMmTelRepository
|
||||||
|
import com.android.settings.network.telephony.ims.ImsMmTelRepositoryImpl
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.conflate
|
||||||
|
import kotlinx.coroutines.flow.flatMapLatest
|
||||||
|
import kotlinx.coroutines.flow.flowOf
|
||||||
|
import kotlinx.coroutines.flow.flowOn
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
|
class ImsRegistrationStateController @JvmOverloads constructor(
|
||||||
|
private val context: Context,
|
||||||
|
private val simSlotRepository: SimSlotRepository = SimSlotRepository(context),
|
||||||
|
private val imsMmTelRepositoryFactory: (subId: Int) -> ImsMmTelRepository = { subId ->
|
||||||
|
ImsMmTelRepositoryImpl(context, subId)
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
fun collectImsRegistered(
|
||||||
|
lifecycleOwner: LifecycleOwner,
|
||||||
|
simSlotIndex: Int,
|
||||||
|
action: (imsRegistered: Boolean) -> Unit,
|
||||||
|
) {
|
||||||
|
lifecycleOwner.lifecycleScope.launch {
|
||||||
|
lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||||
|
imsRegisteredFlow(simSlotIndex).collect(action)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun imsRegisteredFlow(simSlotIndex: Int): Flow<Boolean> =
|
||||||
|
simSlotRepository.subIdInSimSlotFlow(simSlotIndex)
|
||||||
|
.flatMapLatest { subId ->
|
||||||
|
if (SubscriptionManager.isValidSubscriptionId(subId)) {
|
||||||
|
imsMmTelRepositoryFactory(subId).imsRegisteredFlow()
|
||||||
|
} else {
|
||||||
|
flowOf(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.conflate()
|
||||||
|
.flowOn(Dispatchers.Default)
|
||||||
|
}
|
@@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
package com.android.settings.deviceinfo.simstatus;
|
package com.android.settings.deviceinfo.simstatus;
|
||||||
|
|
||||||
import static androidx.lifecycle.Lifecycle.Event;
|
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -30,7 +28,6 @@ import android.content.res.Resources;
|
|||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.PersistableBundle;
|
import android.os.PersistableBundle;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.telephony.AccessNetworkConstants;
|
|
||||||
import android.telephony.Annotation;
|
import android.telephony.Annotation;
|
||||||
import android.telephony.CarrierConfigManager;
|
import android.telephony.CarrierConfigManager;
|
||||||
import android.telephony.CellBroadcastIntents;
|
import android.telephony.CellBroadcastIntents;
|
||||||
@@ -46,29 +43,28 @@ import android.telephony.TelephonyCallback;
|
|||||||
import android.telephony.TelephonyDisplayInfo;
|
import android.telephony.TelephonyDisplayInfo;
|
||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
import android.telephony.euicc.EuiccManager;
|
import android.telephony.euicc.EuiccManager;
|
||||||
import android.telephony.ims.ImsException;
|
|
||||||
import android.telephony.ims.ImsMmTelManager;
|
|
||||||
import android.telephony.ims.ImsReasonInfo;
|
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
import androidx.lifecycle.LifecycleObserver;
|
import androidx.lifecycle.DefaultLifecycleObserver;
|
||||||
import androidx.lifecycle.OnLifecycleEvent;
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.network.SubscriptionUtil;
|
import com.android.settings.network.SubscriptionUtil;
|
||||||
import com.android.settingslib.Utils;
|
import com.android.settingslib.Utils;
|
||||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||||
|
|
||||||
|
import kotlin.Unit;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controller for Sim Status information within the About Phone Settings page.
|
* Controller for Sim Status information within the About Phone Settings page.
|
||||||
*/
|
*/
|
||||||
public class SimStatusDialogController implements LifecycleObserver {
|
public class SimStatusDialogController implements DefaultLifecycleObserver {
|
||||||
|
|
||||||
private final static String TAG = "SimStatusDialogCtrl";
|
private final static String TAG = "SimStatusDialogCtrl";
|
||||||
|
|
||||||
@@ -110,26 +106,7 @@ public class SimStatusDialogController implements LifecycleObserver {
|
|||||||
new OnSubscriptionsChangedListener() {
|
new OnSubscriptionsChangedListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onSubscriptionsChanged() {
|
public void onSubscriptionsChanged() {
|
||||||
final int prevSubId = (mSubscriptionInfo != null)
|
|
||||||
? mSubscriptionInfo.getSubscriptionId()
|
|
||||||
: SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
|
||||||
|
|
||||||
mSubscriptionInfo = getPhoneSubscriptionInfo(mSlotIndex);
|
mSubscriptionInfo = getPhoneSubscriptionInfo(mSlotIndex);
|
||||||
|
|
||||||
final int nextSubId = (mSubscriptionInfo != null)
|
|
||||||
? mSubscriptionInfo.getSubscriptionId()
|
|
||||||
: SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
|
||||||
|
|
||||||
if (prevSubId != nextSubId) {
|
|
||||||
if (SubscriptionManager.isValidSubscriptionId(prevSubId)) {
|
|
||||||
unregisterImsRegistrationCallback(prevSubId);
|
|
||||||
}
|
|
||||||
if (SubscriptionManager.isValidSubscriptionId(nextSubId)) {
|
|
||||||
mTelephonyManager =
|
|
||||||
getTelephonyManager().createForSubscriptionId(nextSubId);
|
|
||||||
registerImsRegistrationCallback(nextSubId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
updateSubscriptionStatus();
|
updateSubscriptionStatus();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -269,8 +246,8 @@ public class SimStatusDialogController implements LifecycleObserver {
|
|||||||
/**
|
/**
|
||||||
* OnResume lifecycle event, resume listening for phone state or subscription changes.
|
* OnResume lifecycle event, resume listening for phone state or subscription changes.
|
||||||
*/
|
*/
|
||||||
@OnLifecycleEvent(Event.ON_RESUME)
|
@Override
|
||||||
public void onResume() {
|
public void onResume(@NonNull LifecycleOwner owner) {
|
||||||
if (mSubscriptionInfo == null) {
|
if (mSubscriptionInfo == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -280,7 +257,7 @@ public class SimStatusDialogController implements LifecycleObserver {
|
|||||||
.registerTelephonyCallback(mContext.getMainExecutor(), mTelephonyCallback);
|
.registerTelephonyCallback(mContext.getMainExecutor(), mTelephonyCallback);
|
||||||
mSubscriptionManager.addOnSubscriptionsChangedListener(
|
mSubscriptionManager.addOnSubscriptionsChangedListener(
|
||||||
mContext.getMainExecutor(), mOnSubscriptionsChangedListener);
|
mContext.getMainExecutor(), mOnSubscriptionsChangedListener);
|
||||||
registerImsRegistrationCallback(mSubscriptionInfo.getSubscriptionId());
|
collectImsRegistered(owner);
|
||||||
|
|
||||||
if (mShowLatestAreaInfo) {
|
if (mShowLatestAreaInfo) {
|
||||||
updateAreaInfoText();
|
updateAreaInfoText();
|
||||||
@@ -295,8 +272,8 @@ public class SimStatusDialogController implements LifecycleObserver {
|
|||||||
/**
|
/**
|
||||||
* onPause lifecycle event, no longer listen for phone state or subscription changes.
|
* onPause lifecycle event, no longer listen for phone state or subscription changes.
|
||||||
*/
|
*/
|
||||||
@OnLifecycleEvent(Event.ON_PAUSE)
|
@Override
|
||||||
public void onPause() {
|
public void onPause(@NonNull LifecycleOwner owner) {
|
||||||
if (mSubscriptionInfo == null) {
|
if (mSubscriptionInfo == null) {
|
||||||
if (mIsRegisteredListener) {
|
if (mIsRegisteredListener) {
|
||||||
mSubscriptionManager.removeOnSubscriptionsChangedListener(
|
mSubscriptionManager.removeOnSubscriptionsChangedListener(
|
||||||
@@ -310,7 +287,6 @@ public class SimStatusDialogController implements LifecycleObserver {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
unregisterImsRegistrationCallback(mSubscriptionInfo.getSubscriptionId());
|
|
||||||
mSubscriptionManager.removeOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
|
mSubscriptionManager.removeOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
|
||||||
getTelephonyManager().unregisterTelephonyCallback(mTelephonyCallback);
|
getTelephonyManager().unregisterTelephonyCallback(mTelephonyCallback);
|
||||||
|
|
||||||
@@ -625,51 +601,22 @@ public class SimStatusDialogController implements LifecycleObserver {
|
|||||||
mDialog.removeSettingFromScreen(IMS_REGISTRATION_STATE_VALUE_ID);
|
mDialog.removeSettingFromScreen(IMS_REGISTRATION_STATE_VALUE_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ImsMmTelManager.RegistrationCallback mImsRegStateCallback =
|
private void collectImsRegistered(@NonNull LifecycleOwner owner) {
|
||||||
new ImsMmTelManager.RegistrationCallback() {
|
|
||||||
@Override
|
|
||||||
public void onRegistered(@AccessNetworkConstants.TransportType int imsTransportType) {
|
|
||||||
mDialog.setText(IMS_REGISTRATION_STATE_VALUE_ID, mRes.getString(
|
|
||||||
com.android.settingslib.R.string.ims_reg_status_registered));
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void onRegistering(@AccessNetworkConstants.TransportType int imsTransportType) {
|
|
||||||
mDialog.setText(IMS_REGISTRATION_STATE_VALUE_ID, mRes.getString(
|
|
||||||
com.android.settingslib.R.string.ims_reg_status_not_registered));
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void onUnregistered(@Nullable ImsReasonInfo info) {
|
|
||||||
mDialog.setText(IMS_REGISTRATION_STATE_VALUE_ID, mRes.getString(
|
|
||||||
com.android.settingslib.R.string.ims_reg_status_not_registered));
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void onTechnologyChangeFailed(
|
|
||||||
@AccessNetworkConstants.TransportType int imsTransportType,
|
|
||||||
@Nullable ImsReasonInfo info) {
|
|
||||||
mDialog.setText(IMS_REGISTRATION_STATE_VALUE_ID, mRes.getString(
|
|
||||||
com.android.settingslib.R.string.ims_reg_status_not_registered));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private void registerImsRegistrationCallback(int subId) {
|
|
||||||
if (!isImsRegistrationStateShowUp()) {
|
if (!isImsRegistrationStateShowUp()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
new ImsRegistrationStateController(mContext).collectImsRegistered(
|
||||||
final ImsMmTelManager imsMmTelMgr = ImsMmTelManager.createForSubscriptionId(subId);
|
owner, mSlotIndex, (Boolean imsRegistered) -> {
|
||||||
imsMmTelMgr.registerImsRegistrationCallback(mDialog.getContext().getMainExecutor(),
|
if (imsRegistered) {
|
||||||
mImsRegStateCallback);
|
mDialog.setText(IMS_REGISTRATION_STATE_VALUE_ID, mRes.getString(
|
||||||
} catch (ImsException exception) {
|
com.android.settingslib.R.string.ims_reg_status_registered));
|
||||||
Log.w(TAG, "fail to register IMS status for subId=" + subId, exception);
|
} else {
|
||||||
}
|
mDialog.setText(IMS_REGISTRATION_STATE_VALUE_ID, mRes.getString(
|
||||||
}
|
com.android.settingslib.R.string.ims_reg_status_not_registered));
|
||||||
|
}
|
||||||
private void unregisterImsRegistrationCallback(int subId) {
|
return Unit.INSTANCE;
|
||||||
if (!isImsRegistrationStateShowUp()) {
|
}
|
||||||
return;
|
);
|
||||||
}
|
|
||||||
final ImsMmTelManager imsMmTelMgr = ImsMmTelManager.createForSubscriptionId(subId);
|
|
||||||
imsMmTelMgr.unregisterImsRegistrationCallback(mImsRegStateCallback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private SubscriptionInfo getPhoneSubscriptionInfo(int slotId) {
|
private SubscriptionInfo getPhoneSubscriptionInfo(int slotId) {
|
||||||
|
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2024 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.network.telephony
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.telephony.SubscriptionManager
|
||||||
|
import android.util.Log
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.conflate
|
||||||
|
import kotlinx.coroutines.flow.flowOn
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
import kotlinx.coroutines.flow.onEach
|
||||||
|
|
||||||
|
class SimSlotRepository(private val context: Context) {
|
||||||
|
private val subscriptionManager = context.requireSubscriptionManager()
|
||||||
|
|
||||||
|
fun subIdInSimSlotFlow(simSlotIndex: Int) =
|
||||||
|
context.subscriptionsChangedFlow()
|
||||||
|
.map {
|
||||||
|
subscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(simSlotIndex)
|
||||||
|
?.subscriptionId
|
||||||
|
?: SubscriptionManager.INVALID_SUBSCRIPTION_ID
|
||||||
|
}
|
||||||
|
.conflate()
|
||||||
|
.onEach { Log.d(TAG, "sub id in sim slot $simSlotIndex: $it") }
|
||||||
|
.flowOn(Dispatchers.Default)
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
private const val TAG = "SimSlotRepository"
|
||||||
|
}
|
||||||
|
}
|
@@ -21,7 +21,10 @@ import android.telephony.AccessNetworkConstants
|
|||||||
import android.telephony.ims.ImsManager
|
import android.telephony.ims.ImsManager
|
||||||
import android.telephony.ims.ImsMmTelManager
|
import android.telephony.ims.ImsMmTelManager
|
||||||
import android.telephony.ims.ImsMmTelManager.WiFiCallingMode
|
import android.telephony.ims.ImsMmTelManager.WiFiCallingMode
|
||||||
|
import android.telephony.ims.ImsReasonInfo
|
||||||
|
import android.telephony.ims.ImsRegistrationAttributes
|
||||||
import android.telephony.ims.ImsStateCallback
|
import android.telephony.ims.ImsStateCallback
|
||||||
|
import android.telephony.ims.RegistrationManager
|
||||||
import android.telephony.ims.feature.MmTelFeature
|
import android.telephony.ims.feature.MmTelFeature
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import kotlin.coroutines.resume
|
import kotlin.coroutines.resume
|
||||||
@@ -39,7 +42,11 @@ import kotlinx.coroutines.withContext
|
|||||||
interface ImsMmTelRepository {
|
interface ImsMmTelRepository {
|
||||||
@WiFiCallingMode
|
@WiFiCallingMode
|
||||||
fun getWiFiCallingMode(useRoamingMode: Boolean): Int
|
fun getWiFiCallingMode(useRoamingMode: Boolean): Int
|
||||||
|
|
||||||
|
fun imsRegisteredFlow(): Flow<Boolean>
|
||||||
|
|
||||||
fun imsReadyFlow(): Flow<Boolean>
|
fun imsReadyFlow(): Flow<Boolean>
|
||||||
|
|
||||||
suspend fun isSupported(
|
suspend fun isSupported(
|
||||||
@MmTelFeature.MmTelCapabilities.MmTelCapability capability: Int,
|
@MmTelFeature.MmTelCapabilities.MmTelCapability capability: Int,
|
||||||
@AccessNetworkConstants.TransportType transportType: Int,
|
@AccessNetworkConstants.TransportType transportType: Int,
|
||||||
@@ -64,6 +71,36 @@ class ImsMmTelRepositoryImpl(
|
|||||||
ImsMmTelManager.WIFI_MODE_UNKNOWN
|
ImsMmTelManager.WIFI_MODE_UNKNOWN
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun imsRegisteredFlow(): Flow<Boolean> = callbackFlow {
|
||||||
|
val callback = object : RegistrationManager.RegistrationCallback() {
|
||||||
|
override fun onRegistered(attributes: ImsRegistrationAttributes) {
|
||||||
|
Log.d(TAG, "[$subId] IMS onRegistered")
|
||||||
|
trySend(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onRegistering(imsTransportType: Int) {
|
||||||
|
Log.d(TAG, "[$subId] IMS onRegistering")
|
||||||
|
trySend(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTechnologyChangeFailed(imsTransportType: Int, info: ImsReasonInfo) {
|
||||||
|
Log.d(TAG, "[$subId] IMS onTechnologyChangeFailed")
|
||||||
|
trySend(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onUnregistered(info: ImsReasonInfo) {
|
||||||
|
Log.d(TAG, "[$subId] IMS onUnregistered")
|
||||||
|
trySend(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
imsMmTelManager.registerImsRegistrationCallback(Dispatchers.Default.asExecutor(), callback)
|
||||||
|
|
||||||
|
awaitClose { imsMmTelManager.unregisterImsRegistrationCallback(callback) }
|
||||||
|
}.catch { e ->
|
||||||
|
Log.w(TAG, "[$subId] error while imsRegisteredFlow", e)
|
||||||
|
}.conflate().flowOn(Dispatchers.Default)
|
||||||
|
|
||||||
override fun imsReadyFlow(): Flow<Boolean> = callbackFlow {
|
override fun imsReadyFlow(): Flow<Boolean> = callbackFlow {
|
||||||
val callback = object : ImsStateCallback() {
|
val callback = object : ImsStateCallback() {
|
||||||
override fun onAvailable() {
|
override fun onAvailable() {
|
||||||
|
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2024 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.deviceinfo.simstatus
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.lifecycle.testing.TestLifecycleOwner
|
||||||
|
import androidx.test.core.app.ApplicationProvider
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.android.settings.network.telephony.SimSlotRepository
|
||||||
|
import com.android.settings.network.telephony.ims.ImsMmTelRepository
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.flow.flowOf
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
import org.mockito.kotlin.doReturn
|
||||||
|
import org.mockito.kotlin.mock
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class ImsRegistrationStateControllerTest {
|
||||||
|
|
||||||
|
private val context: Context = ApplicationProvider.getApplicationContext()
|
||||||
|
|
||||||
|
private val mockSimSlotRepository = mock<SimSlotRepository> {
|
||||||
|
on { subIdInSimSlotFlow(SIM_SLOT_INDEX) } doReturn flowOf(SUB_ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val mockImsMmTelRepository = mock<ImsMmTelRepository> {
|
||||||
|
on { imsRegisteredFlow() } doReturn flowOf(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val controller = ImsRegistrationStateController(
|
||||||
|
context = context,
|
||||||
|
simSlotRepository = mockSimSlotRepository,
|
||||||
|
imsMmTelRepositoryFactory = { subId ->
|
||||||
|
assertThat(subId).isEqualTo(SUB_ID)
|
||||||
|
mockImsMmTelRepository
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun collectImsRegistered() = runBlocking {
|
||||||
|
var imsRegistered = false
|
||||||
|
|
||||||
|
controller.collectImsRegistered(TestLifecycleOwner(), SIM_SLOT_INDEX) {
|
||||||
|
imsRegistered = it
|
||||||
|
}
|
||||||
|
delay(100)
|
||||||
|
|
||||||
|
assertThat(imsRegistered).isTrue()
|
||||||
|
}
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
const val SIM_SLOT_INDEX = 0
|
||||||
|
const val SUB_ID = 1
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2024 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.network.telephony
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.telephony.SubscriptionInfo
|
||||||
|
import android.telephony.SubscriptionManager
|
||||||
|
import androidx.test.core.app.ApplicationProvider
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.android.settingslib.spa.testutils.firstWithTimeoutOrNull
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
import org.mockito.kotlin.any
|
||||||
|
import org.mockito.kotlin.doAnswer
|
||||||
|
import org.mockito.kotlin.doReturn
|
||||||
|
import org.mockito.kotlin.mock
|
||||||
|
import org.mockito.kotlin.spy
|
||||||
|
import org.mockito.kotlin.stub
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class SimSlotRepositoryTest {
|
||||||
|
|
||||||
|
private val mockSubscriptionManager = mock<SubscriptionManager> {
|
||||||
|
on { addOnSubscriptionsChangedListener(any(), any()) } doAnswer {
|
||||||
|
val listener = it.arguments[1] as SubscriptionManager.OnSubscriptionsChangedListener
|
||||||
|
listener.onSubscriptionsChanged()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val context: Context = spy(ApplicationProvider.getApplicationContext()) {
|
||||||
|
on { getSystemService(SubscriptionManager::class.java) } doReturn mockSubscriptionManager
|
||||||
|
}
|
||||||
|
|
||||||
|
private val repository = SimSlotRepository(context)
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun subIdInSimSlotFlow_valid() = runBlocking {
|
||||||
|
mockSubscriptionManager.stub {
|
||||||
|
on { getActiveSubscriptionInfoForSimSlotIndex(SIM_SLOT_INDEX) } doReturn
|
||||||
|
SubscriptionInfo.Builder().setId(SUB_ID).build()
|
||||||
|
}
|
||||||
|
|
||||||
|
val subId = repository.subIdInSimSlotFlow(SIM_SLOT_INDEX).firstWithTimeoutOrNull()
|
||||||
|
|
||||||
|
assertThat(subId).isEqualTo(SUB_ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun subIdInSimSlotFlow_invalid() = runBlocking {
|
||||||
|
mockSubscriptionManager.stub {
|
||||||
|
on { getActiveSubscriptionInfoForSimSlotIndex(SIM_SLOT_INDEX) } doReturn null
|
||||||
|
}
|
||||||
|
|
||||||
|
val subId = repository.subIdInSimSlotFlow(SIM_SLOT_INDEX).firstWithTimeoutOrNull()
|
||||||
|
|
||||||
|
assertThat(subId).isEqualTo(SubscriptionManager.INVALID_SIM_SLOT_INDEX)
|
||||||
|
}
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
const val SIM_SLOT_INDEX = 0
|
||||||
|
const val SUB_ID = 1
|
||||||
|
}
|
||||||
|
}
|
@@ -19,10 +19,14 @@ package com.android.settings.network.telephony.ims
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.telephony.AccessNetworkConstants
|
import android.telephony.AccessNetworkConstants
|
||||||
import android.telephony.ims.ImsMmTelManager
|
import android.telephony.ims.ImsMmTelManager
|
||||||
|
import android.telephony.ims.ImsReasonInfo
|
||||||
|
import android.telephony.ims.ImsRegistrationAttributes
|
||||||
import android.telephony.ims.ImsStateCallback
|
import android.telephony.ims.ImsStateCallback
|
||||||
|
import android.telephony.ims.RegistrationManager.RegistrationCallback
|
||||||
import android.telephony.ims.feature.MmTelFeature
|
import android.telephony.ims.feature.MmTelFeature
|
||||||
import androidx.test.core.app.ApplicationProvider
|
import androidx.test.core.app.ApplicationProvider
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.android.settingslib.spa.testutils.firstWithTimeoutOrNull
|
||||||
import com.android.settingslib.spa.testutils.toListWithTimeout
|
import com.android.settingslib.spa.testutils.toListWithTimeout
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import java.util.function.Consumer
|
import java.util.function.Consumer
|
||||||
@@ -44,12 +48,17 @@ import org.mockito.kotlin.stub
|
|||||||
class ImsMmTelRepositoryTest {
|
class ImsMmTelRepositoryTest {
|
||||||
private val context: Context = ApplicationProvider.getApplicationContext()
|
private val context: Context = ApplicationProvider.getApplicationContext()
|
||||||
|
|
||||||
|
private var registrationCallback: RegistrationCallback? = null
|
||||||
private var stateCallback: ImsStateCallback? = null
|
private var stateCallback: ImsStateCallback? = null
|
||||||
|
|
||||||
private val mockImsMmTelManager = mock<ImsMmTelManager> {
|
private val mockImsMmTelManager = mock<ImsMmTelManager> {
|
||||||
on { isVoWiFiSettingEnabled } doReturn true
|
on { isVoWiFiSettingEnabled } doReturn true
|
||||||
on { getVoWiFiRoamingModeSetting() } doReturn ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED
|
on { getVoWiFiRoamingModeSetting() } doReturn ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED
|
||||||
on { getVoWiFiModeSetting() } doReturn ImsMmTelManager.WIFI_MODE_CELLULAR_PREFERRED
|
on { getVoWiFiModeSetting() } doReturn ImsMmTelManager.WIFI_MODE_CELLULAR_PREFERRED
|
||||||
|
on { registerImsRegistrationCallback(any(), any<RegistrationCallback>()) } doAnswer {
|
||||||
|
registrationCallback = it.arguments[1] as RegistrationCallback
|
||||||
|
registrationCallback?.onRegistered(mock<ImsRegistrationAttributes>())
|
||||||
|
}
|
||||||
on { registerImsStateCallback(any(), any()) } doAnswer {
|
on { registerImsStateCallback(any(), any()) } doAnswer {
|
||||||
stateCallback = it.arguments[1] as ImsStateCallback
|
stateCallback = it.arguments[1] as ImsStateCallback
|
||||||
stateCallback?.onAvailable()
|
stateCallback?.onAvailable()
|
||||||
@@ -99,6 +108,25 @@ class ImsMmTelRepositoryTest {
|
|||||||
assertThat(wiFiCallingMode).isEqualTo(ImsMmTelManager.WIFI_MODE_UNKNOWN)
|
assertThat(wiFiCallingMode).isEqualTo(ImsMmTelManager.WIFI_MODE_UNKNOWN)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun imsRegisteredFlow_sendInitialValue() = runBlocking {
|
||||||
|
val imsRegistered = repository.imsRegisteredFlow().firstWithTimeoutOrNull()
|
||||||
|
|
||||||
|
assertThat(imsRegistered).isTrue()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun imsRegisteredFlow_changed(): Unit = runBlocking {
|
||||||
|
val listDeferred = async {
|
||||||
|
repository.imsRegisteredFlow().toListWithTimeout()
|
||||||
|
}
|
||||||
|
delay(100)
|
||||||
|
|
||||||
|
registrationCallback?.onUnregistered(ImsReasonInfo())
|
||||||
|
|
||||||
|
assertThat(listDeferred.await().last()).isFalse()
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun imsReadyFlow_sendInitialValue() = runBlocking {
|
fun imsReadyFlow_sendInitialValue() = runBlocking {
|
||||||
val flow = repository.imsReadyFlow()
|
val flow = repository.imsReadyFlow()
|
||||||
|
@@ -418,7 +418,6 @@ public class SimStatusDialogControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
|
||||||
public void initialize_showImsRegistration_shouldNotRemoveImsRegistrationStateSetting() {
|
public void initialize_showImsRegistration_shouldNotRemoveImsRegistrationStateSetting() {
|
||||||
mPersistableBundle.putBoolean(
|
mPersistableBundle.putBoolean(
|
||||||
CarrierConfigManager.KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL, true);
|
CarrierConfigManager.KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL, true);
|
||||||
@@ -429,7 +428,6 @@ public class SimStatusDialogControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
|
||||||
public void initialize_doNotShowImsRegistration_shouldRemoveImsRegistrationStateSetting() {
|
public void initialize_doNotShowImsRegistration_shouldRemoveImsRegistrationStateSetting() {
|
||||||
mPersistableBundle.putBoolean(
|
mPersistableBundle.putBoolean(
|
||||||
CarrierConfigManager.KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL, false);
|
CarrierConfigManager.KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL, false);
|
||||||
|
Reference in New Issue
Block a user