/*
 * Copyright (C) 2014 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 android.telephony.cts;

import android.content.Context;
import android.telephony.SmsManager;
import android.telephony.TelephonyManager;
import android.test.AndroidTestCase;

public class SimRestrictedApisTest extends AndroidTestCase {
    private static final byte[] TEST_PDU = {
            0, 0 };
    private TelephonyManager mTelephonyManager;

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        mTelephonyManager =
                (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE);
    }

    private boolean isSimCardPresent() {
        return mTelephonyManager.getSimState() != TelephonyManager.SIM_STATE_ABSENT;
    }

    /**
     * Tests the SmsManager.injectSmsPdu() API. This makes a call to injectSmsPdu() API and expects
     * a SecurityException since the test apk is not signed by a certificate on the SIM.
     */
    public void testInjectSmsPdu() {
        try {
            if (isSimCardPresent()) {
                SmsManager.getDefault().injectSmsPdu(TEST_PDU, "3gpp", null);
                fail("Expected SecurityException. App doesn't have carrier privileges.");
            }
        } catch (SecurityException expected) {
        }
    }

    /**
     * Tests the TelephonyManager.setLine1NumberForDisplay() API. This makes a call to
     * setLine1NumberForDisplay() API and expects a SecurityException since the test apk is not
     * signed by a certificate on the SIM.
     */
    public void testSetLine1NumberForDisplay() {
        try {
            if (isSimCardPresent()) {
                TelephonyManager.getDefault().setLine1NumberForDisplay("", "");
                fail("Expected SecurityException. App doesn't have carrier privileges.");
            }
        } catch (SecurityException expected) {
        }
    }

    /**
     * Tests the TelephonyManager.setLine1NumberForDisplay(long, string, string) API. This makes a
     * call to setLine1NumberForDisplay() API and expects a SecurityException since the test apk is
     * not signed by the certificate on the SIM.
     */
    public void testSetLine1NumberForDisplay2() {
        try {
            if (isSimCardPresent()) {
                TelephonyManager.getDefault().setLine1NumberForDisplayForSubscriber(0, "", "");
                fail("Expected SecurityException. App doesn't have carrier privileges.");
            }
        } catch (SecurityException expected) {
        }
    }

    /**
     * Tests the TelephonyManager.iccOpenLogicalChannel() API. This makes a call to
     * iccOpenLogicalChannel() API and expects a SecurityException since the test apk is not signed
     * by certificate on the SIM.
     */
    public void testIccOpenLogicalChannel() {
        try {
            if (isSimCardPresent()) {
                TelephonyManager.getDefault().iccOpenLogicalChannel("");
                fail("Expected SecurityException. App doesn't have carrier privileges.");
            }
        } catch (SecurityException expected) {
        }
    }

    /**
     * Tests the TelephonyManager.iccCloseLogicalChannel() API. This makes a call to
     * iccCloseLogicalChannel() API and expects a SecurityException since the test apk is not signed
     * by certificate on the SIM.
     */
    public void testIccCloseLogicalChannel() {
        try {
            if (isSimCardPresent()) {
                TelephonyManager.getDefault().iccCloseLogicalChannel(0);
                fail("Expected SecurityException. App doesn't have carrier privileges.");
            }
        } catch (SecurityException expected) {
        }
    }

    /**
     * Tests the TelephonyManager.iccTransmitApduLogicalChannel() API. This makes a call to
     * iccTransmitApduLogicalChannel() API and expects a SecurityException since the test apk is not
     * signed by a certificate on the SIM.
     */
    public void testIccTransmitApduLogicalChannel() {
        try {
            if (isSimCardPresent()) {
                TelephonyManager.getDefault().iccTransmitApduLogicalChannel(0, 0, 0, 0, 0, 0, "");
                fail("Expected SecurityException. App doesn't have carrier privileges.");
            }
        } catch (SecurityException expected) {
        }
    }

    /**
     * Tests the TelephonyManager.iccTransmitApduBasicChannel() API. This makes a call to
     * iccTransmitApduBasicChannel() API and expects a SecurityException since the test apk is not
     * signed by a certificate on the SIM.
     */
    public void testIccTransmitApduBasicChannel() {
        try {
            if (isSimCardPresent()) {
                TelephonyManager.getDefault().iccTransmitApduBasicChannel(0, 0, 0, 0, 0, "");
                fail("Expected SecurityException. App doesn't have carrier privileges.");
            }
        } catch (SecurityException expected) {
        }
    }

    /**
     * Tests the TelephonyManager.sendEnvelopeWithStatus() API. This makes a call to
     * sendEnvelopeWithStatus() API and expects a SecurityException since the test apk is not signed
     * by certificate on the SIM.
     */
    public void testSendEnvelopeWithStatus() {
        try {
            if (isSimCardPresent()) {
                TelephonyManager.getDefault().sendEnvelopeWithStatus("");
                fail("Expected SecurityException. App doesn't have carrier privileges.");
            }
        } catch (SecurityException expected) {
        }
    }

    /**
     * Tests the TelephonyManager.nvReadItem() API. This makes a call to nvReadItem() API and
     * expects a SecurityException since the test apk is not signed by a certificate on the SIM.
     */
    public void testNvReadItem() {
        try {
            if (isSimCardPresent()) {
                TelephonyManager.getDefault().nvReadItem(0);
                fail("Expected SecurityException. App doesn't have carrier privileges.");
            }
        } catch (SecurityException expected) {
        }
    }

    /**
     * Tests the TelephonyManager.nvWriteItem() API. This makes a call to nvWriteItem() API and
     * expects a SecurityException since the test apk is not signed by a certificate on the SIM.
     */
    public void testNvWriteItem() {
        try {
            if (isSimCardPresent()) {
                TelephonyManager.getDefault().nvWriteItem(0, "");
                fail("Expected SecurityException. App doesn't have carrier privileges.");
            }
        } catch (SecurityException expected) {
        }
    }

    /**
     * Tests the TelephonyManager.nvWriteCdmaPrl() API. This makes a call to nvWriteCdmaPrl() API
     * and expects a SecurityException since the test apk is not signed by a certificate on the SIM.
     */
    public void testNvWriteCdmaPrl() {
        try {
            if (isSimCardPresent()) {
                TelephonyManager.getDefault().nvWriteCdmaPrl(null);
                fail("Expected SecurityException. App doesn't have carrier privileges.");
            }
        } catch (SecurityException expected) {
        }
    }

    /**
     * Tests the TelephonyManager.nvResetConfig() API. This makes a call to nvResetConfig() API and
     * expects a SecurityException since the test apk is not signed by a certificate on the SIM.
     */
    public void testNvResetConfig() {
        try {
            if (isSimCardPresent()) {
                TelephonyManager.getDefault().nvResetConfig(0);
                fail("Expected SecurityException. App doesn't have carrier privileges.");
            }
        } catch (SecurityException expected) {
        }
    }

    /**
     * Tests the TelephonyManager.getPreferredNetworkType() API. This makes a call to
     * getPreferredNetworkType() API and expects a SecurityException since the test apk is not
     * signed by certificate on the SIM.
     */
    public void testGetPreferredNetworkType() {
        try {
            if (isSimCardPresent()) {
                TelephonyManager.getDefault().getPreferredNetworkType();
                fail("Expected SecurityException. App doesn't have carrier privileges.");
            }
        } catch (SecurityException expected) {
        }
    }

    /**
     * Tests the TelephonyManager.setPreferredNetworkTypeToGlobal() API. This makes a call to
     * setPreferredNetworkTypeToGlobal() API and expects a SecurityException since the test apk is not
     * signed by certificate on the SIM.
     */
    public void testSetPreferredNetworkTypeToGlobal() {
        try {
            if (isSimCardPresent()) {
                TelephonyManager.getDefault().setPreferredNetworkTypeToGlobal();
                fail("Expected SecurityException. App doesn't have carrier privileges.");
            }
        } catch (SecurityException expected) {
        }
    }

    /**
     * Tests that the test apk doesn't have carrier previliges.
     */
    public void testHasCarrierPrivileges() {
        if (TelephonyManager.getDefault().hasCarrierPrivileges()) {
            fail("App unexpectedly has carrier privileges");
        }
    }

    /**
     * Tests the TelephonyManager.setOperatorBrandOverride() API. This makes a call to
     * setOperatorBrandOverride() API and expects a SecurityException since the test apk is not
     * signed by certificate on the SIM.
     */
    public void testSetOperatorBrandOverride() {
        try {
            if (isSimCardPresent()) {
                TelephonyManager.getDefault().setOperatorBrandOverride("");
                fail("Expected SecurityException. App doesn't have carrier privileges.");
            }
        } catch (SecurityException expected) {
        }
    }
}
