Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fab72cdd authored by Jeff Davidson's avatar Jeff Davidson
Browse files

Clear carrier privilege rules on SIM reset.

Synchronization blocks have been added for any reads of mCatService
and mCarrierPrivilegeRules since these are being nullified. There are
other thread-safety issues in this class which can be addressed in a
follow-up.

Includes other safe cleanup.

Bug: 33057511
Test: Switched carriers and verified rules were temporarily dropped
Change-Id: Id0fe6c9f5df025aa03b120968cd486e741c34ee9
parent 9f1c5080
Loading
Loading
Loading
Loading
+70 −56
Original line number Diff line number Diff line
@@ -98,23 +98,15 @@ public class UiccCard {

    private static final LocalLog mLocalLog = new LocalLog(100);

    private int mPhoneId;

    public UiccCard(Context c, CommandsInterface ci, IccCardStatus ics) {
        if (DBG) log("Creating");
        mCardState = ics.mCardState;
        update(c, ci, ics);
    }
    private final int mPhoneId;

    public UiccCard(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId) {
        if (DBG) log("Creating");
        mCardState = ics.mCardState;
        mPhoneId = phoneId;
        update(c, ci, ics);
    }

    protected UiccCard() {
    }

    public void dispose() {
        synchronized (mLock) {
            if (DBG) log("Disposing card");
@@ -160,18 +152,19 @@ public class UiccCard {
                }
            }

            createAndUpdateCatService();
            createAndUpdateCatServiceLocked();

            // Reload the carrier privilege rules if necessary.
            log("Before privilege rules: " + mCarrierPrivilegeRules + " : " + mCardState);
            if (mCarrierPrivilegeRules == null && mCardState == CardState.CARDSTATE_PRESENT) {
                mCarrierPrivilegeRules = new UiccCarrierPrivilegeRules(this,
                        mHandler.obtainMessage(EVENT_CARRIER_PRIVILIGES_LOADED));
            } else if (mCarrierPrivilegeRules != null && mCardState != CardState.CARDSTATE_PRESENT) {
            } else if (mCarrierPrivilegeRules != null
                    && mCardState != CardState.CARDSTATE_PRESENT) {
                mCarrierPrivilegeRules = null;
            }

            sanitizeApplicationIndexes();
            sanitizeApplicationIndexesLocked();

            RadioState radioState = mCi.getRadioState();
            if (DBG) log("update: radioState=" + radioState + " mLastRadioState="
@@ -193,13 +186,13 @@ public class UiccCard {
        }
    }

    protected void createAndUpdateCatService() {
    private void createAndUpdateCatServiceLocked() {
        if (mUiccApplications.length > 0 && mUiccApplications[0] != null) {
            // Initialize or Reinitialize CatService
            if (mCatService == null) {
                mCatService = CatService.getInstance(mCi, mContext, this, mPhoneId);
            } else {
                ((CatService)mCatService).update(mCi, mContext, this);
                mCatService.update(mCi, mContext, this);
            }
        } else {
            if (mCatService != null) {
@@ -209,10 +202,6 @@ public class UiccCard {
        }
    }

    public CatService getCatService() {
        return mCatService;
    }

    @Override
    protected void finalize() {
        if (DBG) log("UiccCard finalized");
@@ -223,16 +212,18 @@ public class UiccCard {
     * and resets invalid indexes. (This should never happen, but in case
     * RIL misbehaves we need to manage situation gracefully)
     */
    private void sanitizeApplicationIndexes() {
    private void sanitizeApplicationIndexesLocked() {
        mGsmUmtsSubscriptionAppIndex =
                checkIndex(mGsmUmtsSubscriptionAppIndex, AppType.APPTYPE_SIM, AppType.APPTYPE_USIM);
                checkIndexLocked(
                        mGsmUmtsSubscriptionAppIndex, AppType.APPTYPE_SIM, AppType.APPTYPE_USIM);
        mCdmaSubscriptionAppIndex =
                checkIndex(mCdmaSubscriptionAppIndex, AppType.APPTYPE_RUIM, AppType.APPTYPE_CSIM);
                checkIndexLocked(
                        mCdmaSubscriptionAppIndex, AppType.APPTYPE_RUIM, AppType.APPTYPE_CSIM);
        mImsSubscriptionAppIndex =
                checkIndex(mImsSubscriptionAppIndex, AppType.APPTYPE_ISIM, null);
                checkIndexLocked(mImsSubscriptionAppIndex, AppType.APPTYPE_ISIM, null);
    }

    private int checkIndex(int index, AppType expectedAppType, AppType altExpectedAppType) {
    private int checkIndexLocked(int index, AppType expectedAppType, AppType altExpectedAppType) {
        if (mUiccApplications == null || index >= mUiccApplications.length) {
            loge("App index " + index + " is invalid since there are no applications");
            return -1;
@@ -568,14 +559,23 @@ public class UiccCard {
                    changed = true;
                }
            }
            if (TextUtils.isEmpty(aid)) {
                if (mCarrierPrivilegeRules != null) {
                    mCarrierPrivilegeRules = null;
                    changed = true;
                }
                if (mCatService != null) {
                    mCatService.dispose();
                    mCatService = null;
                    changed = true;
                }
            }
            return changed;
        }
        // TODO: For a card level notification, we should delete the CarrierPrivilegeRules and the
        // CAT service.
    }

    /**
     * Exposes {@link CommandsInterface.iccOpenLogicalChannel}
     * Exposes {@link CommandsInterface#iccOpenLogicalChannel}
     */
    public void iccOpenLogicalChannel(String AID, int p2, Message response) {
        loglocal("Open Logical Channel: " + AID + " , " + p2 + " by pid:" + Binder.getCallingPid()
@@ -585,7 +585,7 @@ public class UiccCard {
    }

    /**
     * Exposes {@link CommandsInterface.iccCloseLogicalChannel}
     * Exposes {@link CommandsInterface#iccCloseLogicalChannel}
     */
    public void iccCloseLogicalChannel(int channel, Message response) {
        loglocal("Close Logical Channel: " + channel);
@@ -594,7 +594,7 @@ public class UiccCard {
    }

    /**
     * Exposes {@link CommandsInterface.iccTransmitApduLogicalChannel}
     * Exposes {@link CommandsInterface#iccTransmitApduLogicalChannel}
     */
    public void iccTransmitApduLogicalChannel(int channel, int cla, int command,
            int p1, int p2, int p3, String data, Message response) {
@@ -603,7 +603,7 @@ public class UiccCard {
    }

    /**
     * Exposes {@link CommandsInterface.iccTransmitApduBasicChannel}
     * Exposes {@link CommandsInterface#iccTransmitApduBasicChannel}
     */
    public void iccTransmitApduBasicChannel(int cla, int command,
            int p1, int p2, int p3, String data, Message response) {
@@ -612,7 +612,7 @@ public class UiccCard {
    }

    /**
     * Exposes {@link CommandsInterface.iccIO}
     * Exposes {@link CommandsInterface#iccIO}
     */
    public void iccExchangeSimIO(int fileID, int command, int p1, int p2, int p3,
            String pathID, Message response) {
@@ -621,7 +621,7 @@ public class UiccCard {
    }

    /**
     * Exposes {@link CommandsInterface.sendEnvelopeWithStatus}
     * Exposes {@link CommandsInterface#sendEnvelopeWithStatus}
     */
    public void sendEnvelopeWithStatus(String contents, Message response) {
        mCi.sendEnvelopeWithStatus(contents, response);
@@ -646,64 +646,78 @@ public class UiccCard {
     * Returns true iff carrier privileges rules are null (dont need to be loaded) or loaded.
     */
    public boolean areCarrierPriviligeRulesLoaded() {
        return mCarrierPrivilegeRules == null
            || mCarrierPrivilegeRules.areCarrierPriviligeRulesLoaded();
        UiccCarrierPrivilegeRules carrierPrivilegeRules = getCarrierPrivilegeRules();
        return carrierPrivilegeRules == null
                || carrierPrivilegeRules.areCarrierPriviligeRulesLoaded();
    }

    /**
     * Returns true if there are some carrier privilege rules loaded and specified.
     */
    public boolean hasCarrierPrivilegeRules() {
        return mCarrierPrivilegeRules != null
                && mCarrierPrivilegeRules.hasCarrierPrivilegeRules();
        UiccCarrierPrivilegeRules carrierPrivilegeRules = getCarrierPrivilegeRules();
        return carrierPrivilegeRules != null && carrierPrivilegeRules.hasCarrierPrivilegeRules();
    }

    /**
     * Exposes {@link UiccCarrierPrivilegeRules.getCarrierPrivilegeStatus}.
     * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPrivilegeStatus}.
     */
    public int getCarrierPrivilegeStatus(Signature signature, String packageName) {
        return mCarrierPrivilegeRules == null ?
            TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED :
            mCarrierPrivilegeRules.getCarrierPrivilegeStatus(signature, packageName);
        UiccCarrierPrivilegeRules carrierPrivilegeRules = getCarrierPrivilegeRules();
        return carrierPrivilegeRules == null
                ? TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED :
                carrierPrivilegeRules.getCarrierPrivilegeStatus(signature, packageName);
    }

    /**
     * Exposes {@link UiccCarrierPrivilegeRules.getCarrierPrivilegeStatus}.
     * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPrivilegeStatus}.
     */
    public int getCarrierPrivilegeStatus(PackageManager packageManager, String packageName) {
        return mCarrierPrivilegeRules == null ?
            TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED :
            mCarrierPrivilegeRules.getCarrierPrivilegeStatus(packageManager, packageName);
        UiccCarrierPrivilegeRules carrierPrivilegeRules = getCarrierPrivilegeRules();
        return carrierPrivilegeRules == null
                ? TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED :
                carrierPrivilegeRules.getCarrierPrivilegeStatus(packageManager, packageName);
    }

    /**
     * Exposes {@link UiccCarrierPrivilegeRules.getCarrierPrivilegeStatus}.
     * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPrivilegeStatus}.
     */
    public int getCarrierPrivilegeStatus(PackageInfo packageInfo) {
        return mCarrierPrivilegeRules == null ?
            TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED :
            mCarrierPrivilegeRules.getCarrierPrivilegeStatus(packageInfo);
        UiccCarrierPrivilegeRules carrierPrivilegeRules = getCarrierPrivilegeRules();
        return carrierPrivilegeRules == null
                ? TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED :
                carrierPrivilegeRules.getCarrierPrivilegeStatus(packageInfo);
    }

    /**
     * Exposes {@link UiccCarrierPrivilegeRules.getCarrierPrivilegeStatusForCurrentTransaction}.
     * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPrivilegeStatusForCurrentTransaction}.
     */
    public int getCarrierPrivilegeStatusForCurrentTransaction(PackageManager packageManager) {
        return mCarrierPrivilegeRules == null ?
            TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED :
            mCarrierPrivilegeRules.getCarrierPrivilegeStatusForCurrentTransaction(packageManager);
        UiccCarrierPrivilegeRules carrierPrivilegeRules = getCarrierPrivilegeRules();
        return carrierPrivilegeRules == null
                ? TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED :
                carrierPrivilegeRules.getCarrierPrivilegeStatusForCurrentTransaction(
                        packageManager);
    }

    /**
     * Exposes {@link UiccCarrierPrivilegeRules.getCarrierPackageNamesForIntent}.
     * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPackageNamesForIntent}.
     */
    public List<String> getCarrierPackageNamesForIntent(
            PackageManager packageManager, Intent intent) {
        return mCarrierPrivilegeRules == null ? null :
            mCarrierPrivilegeRules.getCarrierPackageNamesForIntent(
        UiccCarrierPrivilegeRules carrierPrivilegeRules = getCarrierPrivilegeRules();
        return carrierPrivilegeRules == null ? null :
                carrierPrivilegeRules.getCarrierPackageNamesForIntent(
                        packageManager, intent);
    }

    /** Returns a reference to the current {@link UiccCarrierPrivilegeRules}. */
    private UiccCarrierPrivilegeRules getCarrierPrivilegeRules() {
        synchronized (mLock) {
            return mCarrierPrivilegeRules;
        }
    }

    public boolean setOperatorBrandOverride(String brand) {
        log("setOperatorBrandOverride: " + brand);
        log("current iccId: " + getIccId());
+18 −11
Original line number Diff line number Diff line
@@ -15,26 +15,33 @@
 */
package com.android.internal.telephony.uicc;

import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.isA;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.test.suitebuilder.annotation.SmallTest;

import com.android.internal.telephony.TelephonyTest;
import com.android.internal.telephony.cat.CatService;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.android.internal.telephony.TelephonyTest;
import com.android.internal.telephony.cat.CatService;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import static org.mockito.Mockito.*;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;

public class UiccCardTest extends TelephonyTest {
    private UiccCard mUicccard;
@@ -69,7 +76,7 @@ public class UiccCardTest extends TelephonyTest {
        @Override
        public void onLooperPrepared() {
            mUicccard = new UiccCard(mContextFixture.getTestDouble(),
                                     mSimulatedCommands, mIccCardStatus);
                                     mSimulatedCommands, mIccCardStatus, 0 /* phoneId */);
            /* create a custom handler for the Handler Thread */
            mHandler = new Handler(mTestHandlerThread.getLooper()) {
                @Override
+11 −10
Original line number Diff line number Diff line
@@ -16,6 +16,16 @@

package com.android.internal.telephony.uicc;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyObject;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
@@ -35,15 +45,6 @@ import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyObject;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

public class UiccStateChangedLauncherTest extends TelephonyTest {
    private static final String TAG = UiccStateChangedLauncherTest.class.getName();
@@ -101,7 +102,7 @@ public class UiccStateChangedLauncherTest extends TelephonyTest {
        // The first broadcast should be sent after initialization.
        UiccCard[] cards = new UiccCard[CARD_COUNT];
        cards[0] = new UiccCard(mContext, mSimulatedCommands,
                makeCardStatus(CardState.CARDSTATE_PRESENT));
                makeCardStatus(CardState.CARDSTATE_PRESENT), 0 /* phoneId */);
        when(UiccController.getInstance().getUiccCards()).thenReturn(cards);
        uiccLauncher.handleMessage(msg);