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