1c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen/* 2c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen * Copyright (C) 2014 The Android Open Source Project 3c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen * 4c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen * Licensed under the Apache License, Version 2.0 (the "License"); 5c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen * you may not use this file except in compliance with the License. 6c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen * You may obtain a copy of the License at 7c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen * 8c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen * http://www.apache.org/licenses/LICENSE-2.0 9c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen * 10c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen * Unless required by applicable law or agreed to in writing, software 11c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen * distributed under the License is distributed on an "AS IS" BASIS, 12c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen * See the License for the specific language governing permissions and 14c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen * limitations under the License. 15c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen */ 16c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen 17c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wenpackage com.android.mms.service; 18c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen 19c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wenimport android.app.Activity; 20c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wenimport android.app.PendingIntent; 21c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wenimport android.content.Context; 22c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wenimport android.content.Intent; 233a14e46a22e95062102a19c955a819bf239dbc52Ye Wenimport android.net.Uri; 24b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wenimport android.os.Bundle; 251b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastryimport android.service.carrier.CarrierMessagingService; 261b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastryimport android.service.carrier.ICarrierMessagingCallback; 274fd5a8951574cb8a74126c41ec890374eb09e8b9Ye Wenimport android.telephony.SmsManager; 284467007f09a9f2319ba25aa18e04f54693e6bfa1Jonathan Basseriimport android.telephony.TelephonyManager; 294467007f09a9f2319ba25aa18e04f54693e6bfa1Jonathan Basseriimport android.text.TextUtils; 30c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen 31bdb6fe1cfbc8ecb7ed56798f49de7ba62019fd72Ye Wenimport com.android.mms.service.exception.ApnException; 32bdb6fe1cfbc8ecb7ed56798f49de7ba62019fd72Ye Wenimport com.android.mms.service.exception.MmsHttpException; 33bdb6fe1cfbc8ecb7ed56798f49de7ba62019fd72Ye Wenimport com.android.mms.service.exception.MmsNetworkException; 34b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen 35c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen/** 36c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen * Base class for MMS requests. This has the common logic of sending/downloading MMS. 37c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen */ 38c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wenpublic abstract class MmsRequest { 39c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen private static final int RETRY_TIMES = 3; 40c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen 41b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen /** 42b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * Interface for certain functionalities from MmsService 43b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen */ 44b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen public static interface RequestManager { 45b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen /** 463cf9a9481b8e95d0fb654d083b06ee9a23a8e4e8Ye Wen * Enqueue an MMS request 47b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * 48b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * @param request the request to enqueue 49b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen */ 503cf9a9481b8e95d0fb654d083b06ee9a23a8e4e8Ye Wen public void addSimRequest(MmsRequest request); 516f31811156a8aeef55011749c25d7c98d7a7a7ddShishir Agrawal 528c027a60c84d23672647a3775190ee3fa7655b34Ye Wen /* 538c027a60c84d23672647a3775190ee3fa7655b34Ye Wen * @return Whether to auto persist received MMS 548c027a60c84d23672647a3775190ee3fa7655b34Ye Wen */ 558c027a60c84d23672647a3775190ee3fa7655b34Ye Wen public boolean getAutoPersistingPref(); 56b83f2faa04dc275b6779644308384459ffcff63fJulian Odell 57b83f2faa04dc275b6779644308384459ffcff63fJulian Odell /** 58b83f2faa04dc275b6779644308384459ffcff63fJulian Odell * Read pdu (up to maxSize bytes) from supplied content uri 59b83f2faa04dc275b6779644308384459ffcff63fJulian Odell * @param contentUri content uri from which to read 60b83f2faa04dc275b6779644308384459ffcff63fJulian Odell * @param maxSize maximum number of bytes to read 61b83f2faa04dc275b6779644308384459ffcff63fJulian Odell * @return read pdu (else null in case of error or too big) 62b83f2faa04dc275b6779644308384459ffcff63fJulian Odell */ 63b83f2faa04dc275b6779644308384459ffcff63fJulian Odell public byte[] readPduFromContentUri(final Uri contentUri, final int maxSize); 64b83f2faa04dc275b6779644308384459ffcff63fJulian Odell 65b83f2faa04dc275b6779644308384459ffcff63fJulian Odell /** 66b83f2faa04dc275b6779644308384459ffcff63fJulian Odell * Write pdu to supplied content uri 67b83f2faa04dc275b6779644308384459ffcff63fJulian Odell * @param contentUri content uri to which bytes should be written 68b83f2faa04dc275b6779644308384459ffcff63fJulian Odell * @param pdu pdu bytes to write 69b83f2faa04dc275b6779644308384459ffcff63fJulian Odell * @return true in case of success (else false) 70b83f2faa04dc275b6779644308384459ffcff63fJulian Odell */ 71b83f2faa04dc275b6779644308384459ffcff63fJulian Odell public boolean writePduToContentUri(final Uri contentUri, final byte[] pdu); 72b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen } 73b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen 74b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen // The reference to the pending requests manager (i.e. the MmsService) 75b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen protected RequestManager mRequestManager; 7618aabe2742cbaffc3c8293cfb3ce2841fe82326dYe Wen // The SIM id 77a6b72c46163e5fabe74415d2bfbf877a3941150cWink Saville protected int mSubId; 7818aabe2742cbaffc3c8293cfb3ce2841fe82326dYe Wen // The creator app 7918aabe2742cbaffc3c8293cfb3ce2841fe82326dYe Wen protected String mCreator; 80c984707ecf54d545a4a5809c6ce1d18bf7cee61eYe Wen // MMS config 814467007f09a9f2319ba25aa18e04f54693e6bfa1Jonathan Basseri protected Bundle mMmsConfig; 824467007f09a9f2319ba25aa18e04f54693e6bfa1Jonathan Basseri // MMS config overrides that will be applied to mMmsConfig when we eventually load it. 834ed37352fed9c277f602b82998cba619c5b29363Ye Wen protected Bundle mMmsConfigOverrides; 844467007f09a9f2319ba25aa18e04f54693e6bfa1Jonathan Basseri // Context used to get TelephonyManager. 854467007f09a9f2319ba25aa18e04f54693e6bfa1Jonathan Basseri protected Context mContext; 86b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen 8722519cf9f57f3cc359ccb84bcd508ae0f9750821Ye Wen public MmsRequest(RequestManager requestManager, int subId, String creator, 884467007f09a9f2319ba25aa18e04f54693e6bfa1Jonathan Basseri Bundle configOverrides, Context context) { 89b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen mRequestManager = requestManager; 9018aabe2742cbaffc3c8293cfb3ce2841fe82326dYe Wen mSubId = subId; 9118aabe2742cbaffc3c8293cfb3ce2841fe82326dYe Wen mCreator = creator; 924ed37352fed9c277f602b82998cba619c5b29363Ye Wen mMmsConfigOverrides = configOverrides; 934ed37352fed9c277f602b82998cba619c5b29363Ye Wen mMmsConfig = null; 944467007f09a9f2319ba25aa18e04f54693e6bfa1Jonathan Basseri mContext = context; 954ed37352fed9c277f602b82998cba619c5b29363Ye Wen } 964ed37352fed9c277f602b82998cba619c5b29363Ye Wen 973cf9a9481b8e95d0fb654d083b06ee9a23a8e4e8Ye Wen public int getSubId() { 983cf9a9481b8e95d0fb654d083b06ee9a23a8e4e8Ye Wen return mSubId; 993cf9a9481b8e95d0fb654d083b06ee9a23a8e4e8Ye Wen } 1003cf9a9481b8e95d0fb654d083b06ee9a23a8e4e8Ye Wen 1014ed37352fed9c277f602b82998cba619c5b29363Ye Wen private boolean ensureMmsConfigLoaded() { 1024ed37352fed9c277f602b82998cba619c5b29363Ye Wen if (mMmsConfig == null) { 1034ed37352fed9c277f602b82998cba619c5b29363Ye Wen // Not yet retrieved from mms config manager. Try getting it. 1044467007f09a9f2319ba25aa18e04f54693e6bfa1Jonathan Basseri final Bundle config = MmsConfigManager.getInstance().getMmsConfigBySubId(mSubId); 1054ed37352fed9c277f602b82998cba619c5b29363Ye Wen if (config != null) { 1064467007f09a9f2319ba25aa18e04f54693e6bfa1Jonathan Basseri mMmsConfig = config; 1074467007f09a9f2319ba25aa18e04f54693e6bfa1Jonathan Basseri // TODO: Make MmsConfigManager authoritative for user agent and don't consult 1084467007f09a9f2319ba25aa18e04f54693e6bfa1Jonathan Basseri // TelephonyManager. 1098153aed48a84305533f26c06a07a51bd358cee41Ye Wen final TelephonyManager telephonyManager = 1104467007f09a9f2319ba25aa18e04f54693e6bfa1Jonathan Basseri (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); 1118153aed48a84305533f26c06a07a51bd358cee41Ye Wen final String userAgent = telephonyManager.getMmsUserAgent(); 1124467007f09a9f2319ba25aa18e04f54693e6bfa1Jonathan Basseri if (!TextUtils.isEmpty(userAgent)) { 1134467007f09a9f2319ba25aa18e04f54693e6bfa1Jonathan Basseri config.putString(SmsManager.MMS_CONFIG_USER_AGENT, userAgent); 1144467007f09a9f2319ba25aa18e04f54693e6bfa1Jonathan Basseri } 1158153aed48a84305533f26c06a07a51bd358cee41Ye Wen final String userAgentProfileUrl = telephonyManager.getMmsUAProfUrl(); 1164467007f09a9f2319ba25aa18e04f54693e6bfa1Jonathan Basseri if (!TextUtils.isEmpty(userAgentProfileUrl)) { 1174467007f09a9f2319ba25aa18e04f54693e6bfa1Jonathan Basseri config.putString(SmsManager.MMS_CONFIG_UA_PROF_URL, userAgentProfileUrl); 1184467007f09a9f2319ba25aa18e04f54693e6bfa1Jonathan Basseri } 1194467007f09a9f2319ba25aa18e04f54693e6bfa1Jonathan Basseri // Apply overrides 1204467007f09a9f2319ba25aa18e04f54693e6bfa1Jonathan Basseri if (mMmsConfigOverrides != null) { 1214467007f09a9f2319ba25aa18e04f54693e6bfa1Jonathan Basseri mMmsConfig.putAll(mMmsConfigOverrides); 1224467007f09a9f2319ba25aa18e04f54693e6bfa1Jonathan Basseri } 1234ed37352fed9c277f602b82998cba619c5b29363Ye Wen } 1244ed37352fed9c277f602b82998cba619c5b29363Ye Wen } 1254ed37352fed9c277f602b82998cba619c5b29363Ye Wen return mMmsConfig != null; 126b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen } 1273a14e46a22e95062102a19c955a819bf239dbc52Ye Wen 128b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen /** 129b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * Execute the request 130b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * 131b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * @param context The context 132b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * @param networkManager The network manager to use 133b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen */ 134c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen public void execute(Context context, MmsNetworkManager networkManager) { 1358153aed48a84305533f26c06a07a51bd358cee41Ye Wen final String requestId = this.toString(); 1368153aed48a84305533f26c06a07a51bd358cee41Ye Wen LogUtil.i(requestId, "Executing..."); 1374ed37352fed9c277f602b82998cba619c5b29363Ye Wen int result = SmsManager.MMS_ERROR_UNSPECIFIED; 138848307f23f9b744ad538c23ef2e3b1a98e3bc635Ye Wen int httpStatusCode = 0; 139c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen byte[] response = null; 140e03feaba8ca6d25163ff19e433a3a3c460e834e8Ye Wen // TODO: add mms data channel check back to fast fail if no way to send mms, 141e03feaba8ca6d25163ff19e433a3a3c460e834e8Ye Wen // when telephony provides such API. 1424ed37352fed9c277f602b82998cba619c5b29363Ye Wen if (!ensureMmsConfigLoaded()) { // Check mms config 1438153aed48a84305533f26c06a07a51bd358cee41Ye Wen LogUtil.e(requestId, "mms config is not loaded yet"); 1444ed37352fed9c277f602b82998cba619c5b29363Ye Wen result = SmsManager.MMS_ERROR_CONFIGURATION_ERROR; 1454ed37352fed9c277f602b82998cba619c5b29363Ye Wen } else if (!prepareForHttpRequest()) { // Prepare request, like reading pdu data from user 1468153aed48a84305533f26c06a07a51bd358cee41Ye Wen LogUtil.e(requestId, "Failed to prepare for request"); 1474ed37352fed9c277f602b82998cba619c5b29363Ye Wen result = SmsManager.MMS_ERROR_IO_ERROR; 1484ed37352fed9c277f602b82998cba619c5b29363Ye Wen } else { // Execute 1494ed37352fed9c277f602b82998cba619c5b29363Ye Wen long retryDelaySecs = 2; 150d0c5b20403b3924cee67e0e72d745b10b0691eacAndre Furtado // Try multiple times of MMS HTTP request, depending on the error. 151b83f2faa04dc275b6779644308384459ffcff63fJulian Odell for (int i = 0; i < RETRY_TIMES; i++) { 152c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen try { 1538153aed48a84305533f26c06a07a51bd358cee41Ye Wen networkManager.acquireNetwork(requestId); 154068f2012ef6f6e58f06bfbe7c88604a176d69657Tony Hill final String apnName = networkManager.getApnName(); 1558153aed48a84305533f26c06a07a51bd358cee41Ye Wen LogUtil.d(requestId, "APN name is " + apnName); 156b83f2faa04dc275b6779644308384459ffcff63fJulian Odell try { 157068f2012ef6f6e58f06bfbe7c88604a176d69657Tony Hill ApnSettings apn = null; 158068f2012ef6f6e58f06bfbe7c88604a176d69657Tony Hill try { 1598153aed48a84305533f26c06a07a51bd358cee41Ye Wen apn = ApnSettings.load(context, apnName, mSubId, requestId); 160068f2012ef6f6e58f06bfbe7c88604a176d69657Tony Hill } catch (ApnException e) { 161068f2012ef6f6e58f06bfbe7c88604a176d69657Tony Hill // If no APN could be found, fall back to trying without the APN name 162068f2012ef6f6e58f06bfbe7c88604a176d69657Tony Hill if (apnName == null) { 1639094b943daea4dcaf25eb3009158eeae55cfe799Ye Wen // If the APN name was already null then don't need to retry 1649094b943daea4dcaf25eb3009158eeae55cfe799Ye Wen throw (e); 165068f2012ef6f6e58f06bfbe7c88604a176d69657Tony Hill } 1668153aed48a84305533f26c06a07a51bd358cee41Ye Wen LogUtil.i(requestId, "No match with APN name: " 1679094b943daea4dcaf25eb3009158eeae55cfe799Ye Wen + apnName + ", try with no name"); 1688153aed48a84305533f26c06a07a51bd358cee41Ye Wen apn = ApnSettings.load(context, null, mSubId, requestId); 169068f2012ef6f6e58f06bfbe7c88604a176d69657Tony Hill } 1708153aed48a84305533f26c06a07a51bd358cee41Ye Wen LogUtil.i(requestId, "Using " + apn.toString()); 171b83f2faa04dc275b6779644308384459ffcff63fJulian Odell response = doHttp(context, networkManager, apn); 172b83f2faa04dc275b6779644308384459ffcff63fJulian Odell result = Activity.RESULT_OK; 173b83f2faa04dc275b6779644308384459ffcff63fJulian Odell // Success 174b83f2faa04dc275b6779644308384459ffcff63fJulian Odell break; 175b83f2faa04dc275b6779644308384459ffcff63fJulian Odell } finally { 1768153aed48a84305533f26c06a07a51bd358cee41Ye Wen networkManager.releaseNetwork(requestId); 177b83f2faa04dc275b6779644308384459ffcff63fJulian Odell } 178b83f2faa04dc275b6779644308384459ffcff63fJulian Odell } catch (ApnException e) { 1798153aed48a84305533f26c06a07a51bd358cee41Ye Wen LogUtil.e(requestId, "APN failure", e); 180b83f2faa04dc275b6779644308384459ffcff63fJulian Odell result = SmsManager.MMS_ERROR_INVALID_APN; 181b83f2faa04dc275b6779644308384459ffcff63fJulian Odell break; 182b83f2faa04dc275b6779644308384459ffcff63fJulian Odell } catch (MmsNetworkException e) { 1838153aed48a84305533f26c06a07a51bd358cee41Ye Wen LogUtil.e(requestId, "MMS network acquiring failure", e); 184b83f2faa04dc275b6779644308384459ffcff63fJulian Odell result = SmsManager.MMS_ERROR_UNABLE_CONNECT_MMS; 185d0c5b20403b3924cee67e0e72d745b10b0691eacAndre Furtado break; 186b83f2faa04dc275b6779644308384459ffcff63fJulian Odell } catch (MmsHttpException e) { 1878153aed48a84305533f26c06a07a51bd358cee41Ye Wen LogUtil.e(requestId, "HTTP or network I/O failure", e); 188b83f2faa04dc275b6779644308384459ffcff63fJulian Odell result = SmsManager.MMS_ERROR_HTTP_FAILURE; 189848307f23f9b744ad538c23ef2e3b1a98e3bc635Ye Wen httpStatusCode = e.getStatusCode(); 190b83f2faa04dc275b6779644308384459ffcff63fJulian Odell // Retry 191b83f2faa04dc275b6779644308384459ffcff63fJulian Odell } catch (Exception e) { 1928153aed48a84305533f26c06a07a51bd358cee41Ye Wen LogUtil.e(requestId, "Unexpected failure", e); 193b83f2faa04dc275b6779644308384459ffcff63fJulian Odell result = SmsManager.MMS_ERROR_UNSPECIFIED; 194c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen break; 195c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } 196b83f2faa04dc275b6779644308384459ffcff63fJulian Odell try { 1974ed37352fed9c277f602b82998cba619c5b29363Ye Wen Thread.sleep(retryDelaySecs * 1000, 0/*nano*/); 198b83f2faa04dc275b6779644308384459ffcff63fJulian Odell } catch (InterruptedException e) {} 1994ed37352fed9c277f602b82998cba619c5b29363Ye Wen retryDelaySecs <<= 1; 200c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } 201c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } 202848307f23f9b744ad538c23ef2e3b1a98e3bc635Ye Wen processResult(context, result, response, httpStatusCode); 203b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen } 204b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen 205b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen /** 206b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * Process the result of the completed request, including updating the message status 207b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * in database and sending back the result via pending intents. 208848307f23f9b744ad538c23ef2e3b1a98e3bc635Ye Wen * @param context The context 209b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * @param result The result code of execution 210b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * @param response The response body 211848307f23f9b744ad538c23ef2e3b1a98e3bc635Ye Wen * @param httpStatusCode The optional http status code in case of http failure 212b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen */ 213848307f23f9b744ad538c23ef2e3b1a98e3bc635Ye Wen public void processResult(Context context, int result, byte[] response, int httpStatusCode) { 21422519cf9f57f3cc359ccb84bcd508ae0f9750821Ye Wen final Uri messageUri = persistIfRequired(context, result, response); 2153a14e46a22e95062102a19c955a819bf239dbc52Ye Wen 216c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen // Return MMS HTTP request result via PendingIntent 217c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen final PendingIntent pendingIntent = getPendingIntent(); 218c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen if (pendingIntent != null) { 219b83f2faa04dc275b6779644308384459ffcff63fJulian Odell boolean succeeded = true; 2203a14e46a22e95062102a19c955a819bf239dbc52Ye Wen // Extra information to send back with the pending intent 2213a14e46a22e95062102a19c955a819bf239dbc52Ye Wen Intent fillIn = new Intent(); 222c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen if (response != null) { 223b83f2faa04dc275b6779644308384459ffcff63fJulian Odell succeeded = transferResponse(fillIn, response); 2243a14e46a22e95062102a19c955a819bf239dbc52Ye Wen } 22522519cf9f57f3cc359ccb84bcd508ae0f9750821Ye Wen if (messageUri != null) { 22622519cf9f57f3cc359ccb84bcd508ae0f9750821Ye Wen fillIn.putExtra("uri", messageUri.toString()); 227c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } 228848307f23f9b744ad538c23ef2e3b1a98e3bc635Ye Wen if (result == SmsManager.MMS_ERROR_HTTP_FAILURE && httpStatusCode != 0) { 229848307f23f9b744ad538c23ef2e3b1a98e3bc635Ye Wen fillIn.putExtra(SmsManager.EXTRA_MMS_HTTP_STATUS, httpStatusCode); 230848307f23f9b744ad538c23ef2e3b1a98e3bc635Ye Wen } 231c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen try { 232b83f2faa04dc275b6779644308384459ffcff63fJulian Odell if (!succeeded) { 233b83f2faa04dc275b6779644308384459ffcff63fJulian Odell result = SmsManager.MMS_ERROR_IO_ERROR; 234b83f2faa04dc275b6779644308384459ffcff63fJulian Odell } 2353a14e46a22e95062102a19c955a819bf239dbc52Ye Wen pendingIntent.send(context, result, fillIn); 236c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } catch (PendingIntent.CanceledException e) { 2378153aed48a84305533f26c06a07a51bd358cee41Ye Wen LogUtil.e(this.toString(), "Sending pending intent canceled", e); 238c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } 239c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } 240b2823fa889f5c1bde4047af36b3b07672942f700Julian Odell 241b2823fa889f5c1bde4047af36b3b07672942f700Julian Odell revokeUriPermission(context); 242c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } 243c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen 2443a14e46a22e95062102a19c955a819bf239dbc52Ye Wen /** 2451b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry * Returns true if sending / downloading using the carrier app has failed and completes the 2461b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry * action using platform API's, otherwise false. 2471b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry */ 2481b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry protected boolean maybeFallbackToRegularDelivery(int carrierMessagingAppResult) { 2491b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry if (carrierMessagingAppResult 2501b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry == CarrierMessagingService.SEND_STATUS_RETRY_ON_CARRIER_NETWORK 2511b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry || carrierMessagingAppResult 2521b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry == CarrierMessagingService.DOWNLOAD_STATUS_RETRY_ON_CARRIER_NETWORK) { 2538153aed48a84305533f26c06a07a51bd358cee41Ye Wen LogUtil.d(this.toString(), "Sending/downloading MMS by IP failed."); 2541b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry mRequestManager.addSimRequest(MmsRequest.this); 2551b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry return true; 2561b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry } else { 2571b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry return false; 2581b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry } 2591b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry } 2601b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry 2611b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry /** 2621b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry * Converts from {@code carrierMessagingAppResult} to a platform result code. 2631b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry */ 2641b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry protected static int toSmsManagerResult(int carrierMessagingAppResult) { 2651b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry switch (carrierMessagingAppResult) { 2661b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry case CarrierMessagingService.SEND_STATUS_OK: 2671b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry return Activity.RESULT_OK; 2681b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry case CarrierMessagingService.SEND_STATUS_RETRY_ON_CARRIER_NETWORK: 2691b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry return SmsManager.MMS_ERROR_RETRY; 2701b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry default: 2711b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry return SmsManager.MMS_ERROR_UNSPECIFIED; 2721b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry } 2731b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry } 2741b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry 2758153aed48a84305533f26c06a07a51bd358cee41Ye Wen @Override 2768153aed48a84305533f26c06a07a51bd358cee41Ye Wen public String toString() { 2778153aed48a84305533f26c06a07a51bd358cee41Ye Wen return getClass().getSimpleName() + '@' + Integer.toHexString(hashCode()); 2788153aed48a84305533f26c06a07a51bd358cee41Ye Wen } 2798153aed48a84305533f26c06a07a51bd358cee41Ye Wen 280ab1cadebc3136446b44b4dbdcd9df51a960f289fXia Ying 281ab1cadebc3136446b44b4dbdcd9df51a960f289fXia Ying protected String getRequestId() { 282ab1cadebc3136446b44b4dbdcd9df51a960f289fXia Ying return this.toString(); 283ab1cadebc3136446b44b4dbdcd9df51a960f289fXia Ying } 284ab1cadebc3136446b44b4dbdcd9df51a960f289fXia Ying 2851b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry /** 2863a14e46a22e95062102a19c955a819bf239dbc52Ye Wen * Making the HTTP request to MMSC 2873a14e46a22e95062102a19c955a819bf239dbc52Ye Wen * 2883a14e46a22e95062102a19c955a819bf239dbc52Ye Wen * @param context The context 289b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * @param netMgr The current {@link MmsNetworkManager} 2903a14e46a22e95062102a19c955a819bf239dbc52Ye Wen * @param apn The APN setting 2913a14e46a22e95062102a19c955a819bf239dbc52Ye Wen * @return The HTTP response data 2923a14e46a22e95062102a19c955a819bf239dbc52Ye Wen * @throws MmsHttpException If any network error happens 2933a14e46a22e95062102a19c955a819bf239dbc52Ye Wen */ 294b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen protected abstract byte[] doHttp(Context context, MmsNetworkManager netMgr, ApnSettings apn) 295b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen throws MmsHttpException; 296c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen 2973a14e46a22e95062102a19c955a819bf239dbc52Ye Wen /** 2983a14e46a22e95062102a19c955a819bf239dbc52Ye Wen * @return The PendingIntent associate with the MMS sending invocation 2993a14e46a22e95062102a19c955a819bf239dbc52Ye Wen */ 300c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen protected abstract PendingIntent getPendingIntent(); 3013a14e46a22e95062102a19c955a819bf239dbc52Ye Wen 3023a14e46a22e95062102a19c955a819bf239dbc52Ye Wen /** 3033cf9a9481b8e95d0fb654d083b06ee9a23a8e4e8Ye Wen * @return The queue should be used by this request, 0 is sending and 1 is downloading 3043a14e46a22e95062102a19c955a819bf239dbc52Ye Wen */ 3053cf9a9481b8e95d0fb654d083b06ee9a23a8e4e8Ye Wen protected abstract int getQueueType(); 3063a14e46a22e95062102a19c955a819bf239dbc52Ye Wen 3073a14e46a22e95062102a19c955a819bf239dbc52Ye Wen /** 30822519cf9f57f3cc359ccb84bcd508ae0f9750821Ye Wen * Persist message into telephony if required (i.e. when auto-persisting is on or 30922519cf9f57f3cc359ccb84bcd508ae0f9750821Ye Wen * the calling app is non-default sms app for sending) 3103a14e46a22e95062102a19c955a819bf239dbc52Ye Wen * 3113a14e46a22e95062102a19c955a819bf239dbc52Ye Wen * @param context The context 3123a14e46a22e95062102a19c955a819bf239dbc52Ye Wen * @param result The result code of execution 313b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * @param response The response body 31422519cf9f57f3cc359ccb84bcd508ae0f9750821Ye Wen * @return The persisted URI of the message or null if we don't persist or fail 3153a14e46a22e95062102a19c955a819bf239dbc52Ye Wen */ 31622519cf9f57f3cc359ccb84bcd508ae0f9750821Ye Wen protected abstract Uri persistIfRequired(Context context, int result, byte[] response); 317b83f2faa04dc275b6779644308384459ffcff63fJulian Odell 318b83f2faa04dc275b6779644308384459ffcff63fJulian Odell /** 319b83f2faa04dc275b6779644308384459ffcff63fJulian Odell * Prepare to make the HTTP request - will download message for sending 320b83f2faa04dc275b6779644308384459ffcff63fJulian Odell * @return true if preparation succeeds (and request can proceed) else false 321b83f2faa04dc275b6779644308384459ffcff63fJulian Odell */ 322b83f2faa04dc275b6779644308384459ffcff63fJulian Odell protected abstract boolean prepareForHttpRequest(); 323b83f2faa04dc275b6779644308384459ffcff63fJulian Odell 324b83f2faa04dc275b6779644308384459ffcff63fJulian Odell /** 325b83f2faa04dc275b6779644308384459ffcff63fJulian Odell * Transfer the received response to the caller 326b83f2faa04dc275b6779644308384459ffcff63fJulian Odell * 327b83f2faa04dc275b6779644308384459ffcff63fJulian Odell * @param fillIn the intent that will be returned to the caller 328b83f2faa04dc275b6779644308384459ffcff63fJulian Odell * @param response the pdu to transfer 329b83f2faa04dc275b6779644308384459ffcff63fJulian Odell * @return true if response transfer succeeds else false 330b83f2faa04dc275b6779644308384459ffcff63fJulian Odell */ 331b83f2faa04dc275b6779644308384459ffcff63fJulian Odell protected abstract boolean transferResponse(Intent fillIn, byte[] response); 332f6d88a72cd01ecaf9f0319249e239afc008f1ac8Cheuksan Wang 333f6d88a72cd01ecaf9f0319249e239afc008f1ac8Cheuksan Wang /** 334f6d88a72cd01ecaf9f0319249e239afc008f1ac8Cheuksan Wang * Revoke the content URI permission granted by the MMS app to the phone package. 335f6d88a72cd01ecaf9f0319249e239afc008f1ac8Cheuksan Wang * 336f6d88a72cd01ecaf9f0319249e239afc008f1ac8Cheuksan Wang * @param context The context 337f6d88a72cd01ecaf9f0319249e239afc008f1ac8Cheuksan Wang */ 338f6d88a72cd01ecaf9f0319249e239afc008f1ac8Cheuksan Wang protected abstract void revokeUriPermission(Context context); 3391b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry 3401b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry /** 3411b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry * Base class for handling carrier app send / download result. 3421b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry */ 3431b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry protected abstract class CarrierMmsActionCallback extends ICarrierMessagingCallback.Stub { 3441b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry @Override 3451b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry public void onSendSmsComplete(int result, int messageRef) { 3468153aed48a84305533f26c06a07a51bd358cee41Ye Wen LogUtil.e("Unexpected onSendSmsComplete call with result: " + result); 3471b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry } 3481b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry 3491b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry @Override 3501b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry public void onSendMultipartSmsComplete(int result, int[] messageRefs) { 3518153aed48a84305533f26c06a07a51bd358cee41Ye Wen LogUtil.e("Unexpected onSendMultipartSmsComplete call with result: " + result); 3521b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry } 3531b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry 3541b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry @Override 355cd6e4d0abc9b1aba5d8970a0b5408ecb8da5fbb6Ji Yang public void onFilterComplete(int result) { 356cd6e4d0abc9b1aba5d8970a0b5408ecb8da5fbb6Ji Yang LogUtil.e("Unexpected onFilterComplete call with result: " + result); 3571b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry } 3581b2066c9c8f40e2cdabdedfe873a4c960ec7b7d6Abhijith Shastry } 359c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen} 360