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

Commit fccef9a1 authored by Polina Bondarenko's avatar Polina Bondarenko Committed by android-build-merger
Browse files

Merge "Telephony: notify deviceProvisioningPackage" am: d13c5261 am: 8e626ffd

am: c328eea4

Change-Id: Id7ce89deedd4c0886119b1d230ec92d176aec673
parents 6f972a2a c328eea4
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -101,6 +101,8 @@ public class UiccController extends Handler {


    protected RegistrantList mIccChangedRegistrants = new RegistrantList();
    protected RegistrantList mIccChangedRegistrants = new RegistrantList();


    private UiccStateChangedLauncher mLauncher;

    // Logging for dumpsys. Useful in cases when the cards run into errors.
    // Logging for dumpsys. Useful in cases when the cards run into errors.
    private static final int MAX_PROACTIVE_COMMANDS_TO_LOG = 20;
    private static final int MAX_PROACTIVE_COMMANDS_TO_LOG = 20;
    private LinkedList<String> mCardLogs = new LinkedList<String>();
    private LinkedList<String> mCardLogs = new LinkedList<String>();
@@ -136,6 +138,8 @@ public class UiccController extends Handler {
            mCis[i].registerForNotAvailable(this, EVENT_RADIO_UNAVAILABLE, index);
            mCis[i].registerForNotAvailable(this, EVENT_RADIO_UNAVAILABLE, index);
            mCis[i].registerForIccRefresh(this, EVENT_SIM_REFRESH, index);
            mCis[i].registerForIccRefresh(this, EVENT_SIM_REFRESH, index);
        }
        }

        mLauncher = new UiccStateChangedLauncher(c, this);
    }
    }


    public static UiccController getInstance() {
    public static UiccController getInstance() {
+99 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2016 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.internal.telephony.uicc;

import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.telephony.TelephonyManager;
import android.util.Log;

import com.android.internal.R;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.uicc.IccCardStatus.CardState;

/**
 * This class launches its logic on Uicc cards state changes to / from a
 * {@link #CARDSTATE_RESTRICTED} to notify a device provisioning package {@link
 * com.android.internal.R.string.config_deviceProvisioningPackage}, which manages user notifications
 * that inserted SIM is not supported on the device.
 *
 * @see #CARDSTATE_RESTRICTED
 *
 * {@hide}
 */
public class UiccStateChangedLauncher extends Handler {
    private static final String TAG = UiccStateChangedLauncher.class.getName();
    private static final int EVENT_ICC_CHANGED = 1;

    private static String sDeviceProvisioningPackage = null;
    private Context mContext;
    private UiccController mUiccController;
    private boolean[] mIsRestricted = null;

    public UiccStateChangedLauncher(Context context, UiccController controller) {
        sDeviceProvisioningPackage = context.getResources().getString(
                R.string.config_deviceProvisioningPackage);
        if (sDeviceProvisioningPackage != null && !sDeviceProvisioningPackage.isEmpty()) {
            mContext = context;
            mUiccController = controller;
            mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
        }
    }

    @Override
    public void handleMessage(Message msg) {
        switch(msg.what) {
            case (EVENT_ICC_CHANGED):
                boolean shouldNotify = false;
                if (mIsRestricted == null) {
                    mIsRestricted = new boolean[TelephonyManager.getDefault().getPhoneCount()];
                    shouldNotify = true;
                }
                UiccCard[] cards = mUiccController.getUiccCards();
                for (int i = 0; cards != null && i < cards.length; ++i) {
                    // Update only if restricted state changes.
                    if ((cards[i] == null
                            || cards[i].getCardState() != CardState.CARDSTATE_RESTRICTED)
                            != mIsRestricted[i]) {
                        mIsRestricted[i] = !mIsRestricted[i];
                        shouldNotify = true;
                    }
                }
                if (shouldNotify) {
                    notifyStateChanged();
                }
                break;
            default:
                throw new RuntimeException("unexpected event not handled");
        }
    }

    /**
     * Send an explicit intent to device provisioning package.
     */
    private void notifyStateChanged() {
        Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
        intent.setPackage(sDeviceProvisioningPackage);
        try {
            mContext.sendBroadcast(intent);
        } catch (Exception e) {
            Log.e(TAG, e.toString());
        }
    }
}
+161 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2016 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.internal.telephony.uicc;

import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Looper;
import android.os.Message;
import android.telephony.TelephonyManager;
import android.test.suitebuilder.annotation.SmallTest;

import com.android.internal.R;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.TelephonyTest;
import com.android.internal.telephony.uicc.IccCardStatus.CardState;

import org.junit.After;
import org.junit.Before;
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();
    private static final int CARD_COUNT = 1;
    private static final String PROVISIONING_PACKAGE_NAME = "test.provisioning.package";

    @Mock
    private Context mContext;
    @Mock
    private Resources mResources;

    private IccCardStatus makeCardStatus(CardState state) {
        IccCardStatus status = new IccCardStatus();
        status.setCardState(state.ordinal());
        status.mApplications = new IccCardApplicationStatus[0];
        status.mCdmaSubscriptionAppIndex = -1;
        status.mGsmUmtsSubscriptionAppIndex = -1;
        status.mImsSubscriptionAppIndex = -1;
        return status;
    }

    @Before
    public void setUp() throws Exception {
        super.setUp(TAG);

        MockitoAnnotations.initMocks(this);
        when(mContext.getResources()).thenReturn(mResources);
        when(TelephonyManager.getDefault().getPhoneCount()).thenReturn(CARD_COUNT);
    }

    @After
    public void tearDown() throws Exception {
        super.tearDown();
    }

    @Test @SmallTest
    public void testProvisioningPackageSet() {
        // deviceProvisioningPackage is set.
        when(mResources.getString(eq(R.string.config_deviceProvisioningPackage)))
                .thenReturn(PROVISIONING_PACKAGE_NAME);

        if (Looper.myLooper() == null) {
            Looper.prepare();
        }

        UiccStateChangedLauncher uiccLauncher =
                new UiccStateChangedLauncher(mContext, UiccController.getInstance());
        ArgumentCaptor<Integer> integerArgumentCaptor = ArgumentCaptor.forClass(Integer.class);
        verify(UiccController.getInstance(), times(1)).registerForIccChanged(eq(uiccLauncher),
                integerArgumentCaptor.capture(),
                anyObject());
        Message msg = Message.obtain();
        msg.what = integerArgumentCaptor.getValue();

        // The first broadcast should be sent after initialization.
        UiccCard[] cards = new UiccCard[CARD_COUNT];
        cards[0] = new UiccCard(mContext, mSimulatedCommands,
                makeCardStatus(CardState.CARDSTATE_PRESENT));
        when(UiccController.getInstance().getUiccCards()).thenReturn(cards);
        uiccLauncher.handleMessage(msg);

        ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);

        // Amount of sent broadcasts to the device provisioning package.
        int broadcast_count = 1;
        verify(mContext, times(broadcast_count)).sendBroadcast(intentArgumentCaptor.capture());
        assertEquals(PROVISIONING_PACKAGE_NAME, intentArgumentCaptor.getValue().getPackage());
        assertEquals(TelephonyIntents.ACTION_SIM_STATE_CHANGED,
                intentArgumentCaptor.getValue().getAction());

        // Card state's changed to restricted. Broadcast should be sent.
        cards[0].update(mContext, mSimulatedCommands,
                makeCardStatus(CardState.CARDSTATE_RESTRICTED));
        when(UiccController.getInstance().getUiccCards()).thenReturn(cards);
        uiccLauncher.handleMessage(msg);

        broadcast_count++;
        verify(mContext, times(broadcast_count)).sendBroadcast(intentArgumentCaptor.capture());
        assertEquals(PROVISIONING_PACKAGE_NAME, intentArgumentCaptor.getValue().getPackage());
        assertEquals(TelephonyIntents.ACTION_SIM_STATE_CHANGED,
                intentArgumentCaptor.getValue().getAction());

        // Nothing's changed. Broadcast should not be sent.
        uiccLauncher.handleMessage(msg);
        verify(mContext, times(broadcast_count)).sendBroadcast(any(Intent.class));

        // Card state's changed from restricted. Broadcast should be sent.
        cards[0].update(mContext, mSimulatedCommands,
                makeCardStatus(CardState.CARDSTATE_PRESENT));
        when(UiccController.getInstance().getUiccCards()).thenReturn(cards);
        uiccLauncher.handleMessage(msg);

        broadcast_count++;
        verify(mContext, times(broadcast_count)).sendBroadcast(intentArgumentCaptor.capture());
        assertEquals(PROVISIONING_PACKAGE_NAME, intentArgumentCaptor.getValue().getPackage());
        assertEquals(TelephonyIntents.ACTION_SIM_STATE_CHANGED,
                intentArgumentCaptor.getValue().getAction());
    }

    @Test @SmallTest
    public void testProvisioningPackageUnset() {
        // deviceProvisionigPackage is not set.
        when(mResources.getString(eq(R.string.config_deviceProvisioningPackage)))
                .thenReturn(null);

        if (Looper.myLooper() == null) {
            Looper.prepare();
        }

        UiccStateChangedLauncher uiccLauncher =
                new UiccStateChangedLauncher(mContext, UiccController.getInstance());
        verify(UiccController.getInstance(), never()).registerForIccChanged(eq(uiccLauncher),
                anyInt(), anyObject());
    }
}