/* * 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.telephony; import android.Manifest; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.os.SystemClock; import android.telephony.euicc.EuiccManager; import android.util.Log; import com.android.settings.SidecarFragment; import java.util.concurrent.atomic.AtomicInteger; /** * The sidecar base class that an Euicc sidecar can extend from. The extended class should implement * getReceiverAction() to return the action string for the broadcast receiver. The extended class * should implement its own get() function to return an instance of that class, and implement the * functional class like run() to actually trigger the function in EuiccManager. */ public abstract class EuiccOperationSidecar extends SidecarFragment { private static final String TAG = "EuiccOperationSidecar"; private static final int REQUEST_CODE = 0; private static final String EXTRA_OP_ID = "op_id"; private static AtomicInteger sCurrentOpId = new AtomicInteger((int) SystemClock.elapsedRealtime()); protected EuiccManager mEuiccManager; private int mResultCode; private int mDetailedCode; private Intent mResultIntent; private int mOpId; protected final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (getReceiverAction().equals(intent.getAction()) && mOpId == intent.getIntExtra(EXTRA_OP_ID, -1)) { mResultCode = getResultCode(); /* TODO: This relies on our LUI and LPA to coexist, should think about how to generalize this further. */ mDetailedCode = intent.getIntExtra( EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, 0 /* defaultValue*/); mResultIntent = intent; Log.i( TAG, String.format( "Result code : %d; detailed code : %d", mResultCode, mDetailedCode)); onActionReceived(); } } }; /** * This is called when the broadcast action is received. The subclass may override this to * perform different logic. The broadcast result code may be obtained with {@link * #getResultCode()} and the Intent may be obtained with {@link #getResultIntent()}. */ protected void onActionReceived() { if (mResultCode == EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK) { setState(State.SUCCESS, Substate.UNUSED); } else { setState(State.ERROR, mResultCode); } } /** * The extended class should implement it to return a string for the broadcast action. The class * should be unique across all the child classes. */ protected abstract String getReceiverAction(); protected PendingIntent createCallbackIntent() { mOpId = sCurrentOpId.incrementAndGet(); Intent intent = new Intent(getReceiverAction()); intent.putExtra(EXTRA_OP_ID, mOpId); return PendingIntent.getBroadcast( getContext(), REQUEST_CODE, intent, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mEuiccManager = getContext().getSystemService(EuiccManager.class); getContext() .getApplicationContext() .registerReceiver( mReceiver, new IntentFilter(getReceiverAction()), Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS, null); } @Override public void onDestroy() { getContext().getApplicationContext().unregisterReceiver(mReceiver); super.onDestroy(); } public int getResultCode() { return mResultCode; } public int getDetailedCode() { return mDetailedCode; } public Intent getResultIntent() { return mResultIntent; } }