blob: 132a2fd2367c0778e9fd8e045ebd24b7b16e1629 [file] [log] [blame]
/*
* Copyright (C) 2020 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;
import android.app.FragmentManager;
import android.os.Bundle;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.util.Log;
import com.android.settings.SidecarFragment;
import com.android.settings.network.telephony.EuiccOperationSidecar;
/**
* This sidecar is responsible for switching to the removable slot. It disables the active eSIM
* profile before switching if there is one.
*/
public class SwitchToRemovableSlotSidecar extends EuiccOperationSidecar
implements SidecarFragment.Listener {
private static final String TAG = "DisableSubscriptionAndSwitchSlotSidecar";
private static final String ACTION_DISABLE_SUBSCRIPTION_AND_SWITCH_SLOT =
"disable_subscription_and_switch_slot_sidecar";
// Stateless members.
private SwitchToEuiccSubscriptionSidecar mSwitchToSubscriptionSidecar;
private SwitchSlotSidecar mSwitchSlotSidecar;
private int mPhysicalSlotId;
/** Returns a SwitchToRemovableSlotSidecar sidecar instance. */
public static SwitchToRemovableSlotSidecar get(FragmentManager fm) {
return SidecarFragment.get(fm, TAG, SwitchToRemovableSlotSidecar.class, null /* args */);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSwitchToSubscriptionSidecar =
SwitchToEuiccSubscriptionSidecar.get(getChildFragmentManager());
mSwitchSlotSidecar = SwitchSlotSidecar.get(getChildFragmentManager());
}
@Override
public void onResume() {
super.onResume();
mSwitchToSubscriptionSidecar.addListener(this);
mSwitchSlotSidecar.addListener(this);
}
@Override
public void onPause() {
mSwitchToSubscriptionSidecar.removeListener(this);
mSwitchSlotSidecar.removeListener(this);
super.onPause();
}
@Override
protected String getReceiverAction() {
return ACTION_DISABLE_SUBSCRIPTION_AND_SWITCH_SLOT;
}
@Override
public void onStateChange(SidecarFragment fragment) {
if (fragment == mSwitchToSubscriptionSidecar) {
onSwitchToSubscriptionSidecarStateChange();
} else if (fragment == mSwitchSlotSidecar) {
onSwitchSlotSidecarStateChange();
} else {
Log.wtf(TAG, "Received state change from a sidecar not expected.");
}
}
/**
* Starts switching to the removable slot. It disables the active eSIM profile before switching
* if there is one.
*
* @param physicalSlotId removable physical SIM slot ID.
*/
public void run(int physicalSlotId) {
mPhysicalSlotId = physicalSlotId;
SubscriptionManager subscriptionManager =
getContext().getSystemService(SubscriptionManager.class);
if (SubscriptionUtil.getActiveSubscriptions(subscriptionManager).stream()
.anyMatch(SubscriptionInfo::isEmbedded)) {
Log.i(TAG, "There is an active eSIM profile. Disable the profile first.");
// Use INVALID_SUBSCRIPTION_ID to disable the only active profile.
mSwitchToSubscriptionSidecar.run(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
} else {
Log.i(TAG, "There is no active eSIM profiles. Start to switch to removable slot.");
mSwitchSlotSidecar.runSwitchToRemovableSlot(mPhysicalSlotId);
}
}
private void onSwitchToSubscriptionSidecarStateChange() {
switch (mSwitchToSubscriptionSidecar.getState()) {
case State.SUCCESS:
mSwitchToSubscriptionSidecar.reset();
Log.i(
TAG,
"Successfully disabled eSIM profile. Start to switch to Removable slot.");
mSwitchSlotSidecar.runSwitchToRemovableSlot(mPhysicalSlotId);
break;
case State.ERROR:
mSwitchToSubscriptionSidecar.reset();
Log.i(TAG, "Failed to disable the active eSIM profile.");
setState(State.ERROR, Substate.UNUSED);
break;
}
}
private void onSwitchSlotSidecarStateChange() {
switch (mSwitchSlotSidecar.getState()) {
case State.SUCCESS:
mSwitchSlotSidecar.reset();
Log.i(TAG, "Successfully switched to removable slot.");
setState(State.SUCCESS, Substate.UNUSED);
break;
case State.ERROR:
mSwitchSlotSidecar.reset();
Log.i(TAG, "Failed to switch to removable slot.");
setState(State.ERROR, Substate.UNUSED);
break;
}
}
}