Home | History | Annotate | Download | only in gsm
      1 /*
      2 ** Copyright 2007, The Android Open Source Project
      3 **
      4 ** Licensed under the Apache License, Version 2.0 (the "License");
      5 ** you may not use this file except in compliance with the License.
      6 ** You may obtain a copy of the License at
      7 **
      8 **     http://www.apache.org/licenses/LICENSE-2.0
      9 **
     10 ** Unless required by applicable law or agreed to in writing, software
     11 ** distributed under the License is distributed on an "AS IS" BASIS,
     12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 ** See the License for the specific language governing permissions and
     14 ** limitations under the License.
     15 */
     16 
     17 package com.android.internal.telephony.gsm;
     18 
     19 import android.Manifest;
     20 import android.content.Context;
     21 import android.os.Binder;
     22 import android.os.Message;
     23 import android.telephony.Rlog;
     24 
     25 import com.android.internal.telephony.IccSmsInterfaceManager;
     26 import com.android.internal.telephony.IntRangeManager;
     27 import com.android.internal.telephony.SMSDispatcher;
     28 import com.android.internal.telephony.uicc.IccUtils;
     29 
     30 import java.util.ArrayList;
     31 
     32 /**
     33  * SimSmsInterfaceManager to provide an inter-process communication to
     34  * access Sms in Sim.
     35  */
     36 public class SimSmsInterfaceManager extends IccSmsInterfaceManager {
     37     static final String LOG_TAG = "SimSmsIM";
     38     static final boolean DBG = true;
     39 
     40     private CellBroadcastRangeManager mCellBroadcastRangeManager =
     41             new CellBroadcastRangeManager();
     42 
     43     private static final int SMS_CB_CODE_SCHEME_MIN = 0;
     44     private static final int SMS_CB_CODE_SCHEME_MAX = 255;
     45 
     46     public SimSmsInterfaceManager(GSMPhone phone, SMSDispatcher dispatcher) {
     47         super(phone);
     48         mDispatcher = dispatcher;
     49     }
     50 
     51     public void dispose() {
     52     }
     53 
     54     @Override
     55     protected void finalize() {
     56         try {
     57             super.finalize();
     58         } catch (Throwable throwable) {
     59             Rlog.e(LOG_TAG, "Error while finalizing:", throwable);
     60         }
     61         if(DBG) Rlog.d(LOG_TAG, "SimSmsInterfaceManager finalized");
     62     }
     63 
     64     @Override
     65     protected void deleteSms(int index, Message response) {
     66         mPhone.mCi.deleteSmsOnSim(index, response);
     67     }
     68 
     69     @Override
     70     protected void writeSms(int status, byte[] pdu, byte[] smsc, Message response) {
     71         mPhone.mCi.writeSmsToSim(status, IccUtils.bytesToHexString(smsc),
     72                 IccUtils.bytesToHexString(pdu), response);
     73     }
     74 
     75     @Override
     76     public boolean enableCellBroadcast(int messageIdentifier) {
     77         return enableCellBroadcastRange(messageIdentifier, messageIdentifier);
     78     }
     79 
     80     @Override
     81     public boolean disableCellBroadcast(int messageIdentifier) {
     82         return disableCellBroadcastRange(messageIdentifier, messageIdentifier);
     83     }
     84 
     85     @Override
     86     public boolean enableCellBroadcastRange(int startMessageId, int endMessageId) {
     87         if (DBG) log("enableCellBroadcastRange");
     88 
     89         Context context = mPhone.getContext();
     90 
     91         context.enforceCallingPermission(
     92                 Manifest.permission.RECEIVE_SMS,
     93                 "Enabling cell broadcast SMS");
     94 
     95         String client = context.getPackageManager().getNameForUid(
     96                 Binder.getCallingUid());
     97 
     98         if (!mCellBroadcastRangeManager.enableRange(startMessageId, endMessageId, client)) {
     99             log("Failed to add cell broadcast subscription for MID range " + startMessageId
    100                     + " to " + endMessageId + " from client " + client);
    101             return false;
    102         }
    103 
    104         if (DBG)
    105             log("Added cell broadcast subscription for MID range " + startMessageId
    106                     + " to " + endMessageId + " from client " + client);
    107 
    108         setCellBroadcastActivation(!mCellBroadcastRangeManager.isEmpty());
    109 
    110         return true;
    111     }
    112 
    113     @Override
    114     public boolean disableCellBroadcastRange(int startMessageId, int endMessageId) {
    115         if (DBG) log("disableCellBroadcastRange");
    116 
    117         Context context = mPhone.getContext();
    118 
    119         context.enforceCallingPermission(
    120                 Manifest.permission.RECEIVE_SMS,
    121                 "Disabling cell broadcast SMS");
    122 
    123         String client = context.getPackageManager().getNameForUid(
    124                 Binder.getCallingUid());
    125 
    126         if (!mCellBroadcastRangeManager.disableRange(startMessageId, endMessageId, client)) {
    127             log("Failed to remove cell broadcast subscription for MID range " + startMessageId
    128                     + " to " + endMessageId + " from client " + client);
    129             return false;
    130         }
    131 
    132         if (DBG)
    133             log("Removed cell broadcast subscription for MID range " + startMessageId
    134                     + " to " + endMessageId + " from client " + client);
    135 
    136         setCellBroadcastActivation(!mCellBroadcastRangeManager.isEmpty());
    137 
    138         return true;
    139     }
    140 
    141     class CellBroadcastRangeManager extends IntRangeManager {
    142         private ArrayList<SmsBroadcastConfigInfo> mConfigList =
    143                 new ArrayList<SmsBroadcastConfigInfo>();
    144 
    145         /**
    146          * Called when the list of enabled ranges has changed. This will be
    147          * followed by zero or more calls to {@link #addRange} followed by
    148          * a call to {@link #finishUpdate}.
    149          */
    150         @Override
    151         protected void startUpdate() {
    152             mConfigList.clear();
    153         }
    154 
    155         /**
    156          * Called after {@link #startUpdate} to indicate a range of enabled
    157          * values.
    158          * @param startId the first id included in the range
    159          * @param endId the last id included in the range
    160          */
    161         @Override
    162         protected void addRange(int startId, int endId, boolean selected) {
    163             mConfigList.add(new SmsBroadcastConfigInfo(startId, endId,
    164                         SMS_CB_CODE_SCHEME_MIN, SMS_CB_CODE_SCHEME_MAX, selected));
    165         }
    166 
    167         /**
    168          * Called to indicate the end of a range update started by the
    169          * previous call to {@link #startUpdate}.
    170          * @return true if successful, false otherwise
    171          */
    172         @Override
    173         protected boolean finishUpdate() {
    174             if (mConfigList.isEmpty()) {
    175                 return true;
    176             } else {
    177                 SmsBroadcastConfigInfo[] configs =
    178                         mConfigList.toArray(new SmsBroadcastConfigInfo[mConfigList.size()]);
    179                 return setCellBroadcastConfig(configs);
    180             }
    181         }
    182     }
    183 
    184     private boolean setCellBroadcastConfig(SmsBroadcastConfigInfo[] configs) {
    185         if (DBG)
    186             log("Calling setGsmBroadcastConfig with " + configs.length + " configurations");
    187 
    188         synchronized (mLock) {
    189             Message response = mHandler.obtainMessage(EVENT_SET_BROADCAST_CONFIG_DONE);
    190 
    191             mSuccess = false;
    192             mPhone.mCi.setGsmBroadcastConfig(configs, response);
    193 
    194             try {
    195                 mLock.wait();
    196             } catch (InterruptedException e) {
    197                 log("interrupted while trying to set cell broadcast config");
    198             }
    199         }
    200 
    201         return mSuccess;
    202     }
    203 
    204     private boolean setCellBroadcastActivation(boolean activate) {
    205         if (DBG)
    206             log("Calling setCellBroadcastActivation(" + activate + ')');
    207 
    208         synchronized (mLock) {
    209             Message response = mHandler.obtainMessage(EVENT_SET_BROADCAST_ACTIVATION_DONE);
    210 
    211             mSuccess = false;
    212             mPhone.mCi.setGsmBroadcastActivation(activate, response);
    213 
    214             try {
    215                 mLock.wait();
    216             } catch (InterruptedException e) {
    217                 log("interrupted while trying to set cell broadcast activation");
    218             }
    219         }
    220 
    221         return mSuccess;
    222     }
    223 
    224     @Override
    225     protected void log(String msg) {
    226         Rlog.d(LOG_TAG, "[SimSmsInterfaceManager] " + msg);
    227     }
    228 }
    229