MmsRequest.java revision b2823fa889f5c1bde4047af36b3b07672942f700
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 com.android.mms.service.exception.ApnException; 20c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wenimport com.android.mms.service.exception.MmsHttpException; 21c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wenimport com.android.mms.service.exception.MmsNetworkException; 22c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen 23c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wenimport android.app.Activity; 24c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wenimport android.app.PendingIntent; 25b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wenimport android.content.BroadcastReceiver; 26c984707ecf54d545a4a5809c6ce1d18bf7cee61eYe Wenimport android.content.ContentValues; 27c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wenimport android.content.Context; 28c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wenimport android.content.Intent; 29b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wenimport android.net.ConnectivityManager; 30b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wenimport android.net.LinkProperties; 31b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wenimport android.net.Network; 323a14e46a22e95062102a19c955a819bf239dbc52Ye Wenimport android.net.Uri; 33b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wenimport android.os.Bundle; 34b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wenimport android.provider.Telephony; 354fd5a8951574cb8a74126c41ec890374eb09e8b9Ye Wenimport android.telephony.SmsManager; 36c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wenimport android.util.Log; 37c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen 38b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wenimport java.net.Inet4Address; 39b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wenimport java.net.Inet6Address; 40b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wenimport java.net.InetAddress; 41b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wenimport java.net.UnknownHostException; 42b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wenimport java.util.ArrayList; 43b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wenimport java.util.List; 44b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen 45c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen/** 46c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen * Base class for MMS requests. This has the common logic of sending/downloading MMS. 47c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen */ 48c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wenpublic abstract class MmsRequest { 49c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen private static final int RETRY_TIMES = 3; 50c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen 51b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen protected static final String EXTRA_MESSAGE_REF = "messageref"; 52b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen 53b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen /** 54b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * Interface for certain functionalities from MmsService 55b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen */ 56b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen public static interface RequestManager { 57b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen /** 58b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * Add a request to pending queue when it is executed by carrier app 59b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * 60b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * @param key The message ref key from carrier app 61b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * @param request The request in pending 62b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen */ 63b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen public void addPending(int key, MmsRequest request); 64b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen 65b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen /** 66b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * Enqueue an MMS request for running 67b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * 68b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * @param request the request to enqueue 69b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen */ 70b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen public void addRunning(MmsRequest request); 716f31811156a8aeef55011749c25d7c98d7a7a7ddShishir Agrawal 728c027a60c84d23672647a3775190ee3fa7655b34Ye Wen /* 738c027a60c84d23672647a3775190ee3fa7655b34Ye Wen * @return Whether to auto persist received MMS 748c027a60c84d23672647a3775190ee3fa7655b34Ye Wen */ 758c027a60c84d23672647a3775190ee3fa7655b34Ye Wen public boolean getAutoPersistingPref(); 76b83f2faa04dc275b6779644308384459ffcff63fJulian Odell 77b83f2faa04dc275b6779644308384459ffcff63fJulian Odell /** 78b83f2faa04dc275b6779644308384459ffcff63fJulian Odell * Read pdu (up to maxSize bytes) from supplied content uri 79b83f2faa04dc275b6779644308384459ffcff63fJulian Odell * @param contentUri content uri from which to read 80b83f2faa04dc275b6779644308384459ffcff63fJulian Odell * @param maxSize maximum number of bytes to read 81b83f2faa04dc275b6779644308384459ffcff63fJulian Odell * @return read pdu (else null in case of error or too big) 82b83f2faa04dc275b6779644308384459ffcff63fJulian Odell */ 83b83f2faa04dc275b6779644308384459ffcff63fJulian Odell public byte[] readPduFromContentUri(final Uri contentUri, final int maxSize); 84b83f2faa04dc275b6779644308384459ffcff63fJulian Odell 85b83f2faa04dc275b6779644308384459ffcff63fJulian Odell /** 86b83f2faa04dc275b6779644308384459ffcff63fJulian Odell * Write pdu to supplied content uri 87b83f2faa04dc275b6779644308384459ffcff63fJulian Odell * @param contentUri content uri to which bytes should be written 88b83f2faa04dc275b6779644308384459ffcff63fJulian Odell * @param pdu pdu bytes to write 89b83f2faa04dc275b6779644308384459ffcff63fJulian Odell * @return true in case of success (else false) 90b83f2faa04dc275b6779644308384459ffcff63fJulian Odell */ 91b83f2faa04dc275b6779644308384459ffcff63fJulian Odell public boolean writePduToContentUri(final Uri contentUri, final byte[] pdu); 92b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen } 93b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen 943a14e46a22e95062102a19c955a819bf239dbc52Ye Wen // The URI of persisted message 953a14e46a22e95062102a19c955a819bf239dbc52Ye Wen protected Uri mMessageUri; 96b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen // The reference to the pending requests manager (i.e. the MmsService) 97b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen protected RequestManager mRequestManager; 9818aabe2742cbaffc3c8293cfb3ce2841fe82326dYe Wen // The SIM id 9918aabe2742cbaffc3c8293cfb3ce2841fe82326dYe Wen protected long mSubId; 10018aabe2742cbaffc3c8293cfb3ce2841fe82326dYe Wen // The creator app 10118aabe2742cbaffc3c8293cfb3ce2841fe82326dYe Wen protected String mCreator; 102c984707ecf54d545a4a5809c6ce1d18bf7cee61eYe Wen // MMS config 103c984707ecf54d545a4a5809c6ce1d18bf7cee61eYe Wen protected MmsConfig.Overridden mMmsConfig; 104b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen 105b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen // Intent result receiver for carrier app 106b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen protected final BroadcastReceiver mCarrierAppResultReceiver = new BroadcastReceiver() { 107b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen @Override 108b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen public void onReceive(Context context, Intent intent) { 109b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen final String action = intent.getAction(); 110b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen if (action.equals(Telephony.Mms.Intents.MMS_SEND_ACTION) || 111b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen action.equals(Telephony.Mms.Intents.MMS_DOWNLOAD_ACTION)) { 112b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen Log.d(MmsService.TAG, "Carrier app result for " + action); 113b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen final int rc = getResultCode(); 114b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen if (rc == Activity.RESULT_OK) { 115b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen // Handled by carrier app, waiting for result 116b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen Log.d(MmsService.TAG, "Sending/downloading MMS by IP pending."); 117b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen final Bundle resultExtras = getResultExtras(false); 118b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen if (resultExtras != null && resultExtras.containsKey(EXTRA_MESSAGE_REF)) { 119b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen final int ref = resultExtras.getInt(EXTRA_MESSAGE_REF); 120b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen Log.d(MmsService.TAG, "messageref = " + ref); 121b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen mRequestManager.addPending(ref, MmsRequest.this); 122b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen } else { 123b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen // Bad, no message ref provided 124b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen Log.e(MmsService.TAG, "Can't find messageref in result extras."); 125b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen } 126b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen } else { 127b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen // No carrier app present, sending normally 128b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen Log.d(MmsService.TAG, "Sending/downloading MMS by IP failed."); 129b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen mRequestManager.addRunning(MmsRequest.this); 130b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen } 131b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen } else { 132b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen Log.e(MmsService.TAG, "unexpected BroadcastReceiver action: " + action); 133b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen } 134b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen 135b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen } 136b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen }; 137b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen 138b83f2faa04dc275b6779644308384459ffcff63fJulian Odell public MmsRequest(RequestManager requestManager, Uri messageUri, long subId, 1393e40f4c4a8c82e795a5cea235d52eacd177c0a69Ye Wen String creator, Bundle configOverrides) { 140b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen mRequestManager = requestManager; 14118aabe2742cbaffc3c8293cfb3ce2841fe82326dYe Wen mMessageUri = messageUri; 14218aabe2742cbaffc3c8293cfb3ce2841fe82326dYe Wen mSubId = subId; 14318aabe2742cbaffc3c8293cfb3ce2841fe82326dYe Wen mCreator = creator; 14476b0e8693a8004001663044f5188d5b9fe4203e8Tom Taylor mMmsConfig = new MmsConfig.Overridden( 14576b0e8693a8004001663044f5188d5b9fe4203e8Tom Taylor MmsConfigManager.getInstance().getMmsConfigBySubId(subId), 14676b0e8693a8004001663044f5188d5b9fe4203e8Tom Taylor configOverrides); 147b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen } 1483a14e46a22e95062102a19c955a819bf239dbc52Ye Wen 149b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen /** 150b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * Execute the request 151b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * 152b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * @param context The context 153b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * @param networkManager The network manager to use 154b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen */ 155c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen public void execute(Context context, MmsNetworkManager networkManager) { 156b83f2faa04dc275b6779644308384459ffcff63fJulian Odell int result = SmsManager.MMS_ERROR_IO_ERROR; 157c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen byte[] response = null; 158b83f2faa04dc275b6779644308384459ffcff63fJulian Odell 159b83f2faa04dc275b6779644308384459ffcff63fJulian Odell if (prepareForHttpRequest()) { 160b83f2faa04dc275b6779644308384459ffcff63fJulian Odell long retryDelay = 2; 161b83f2faa04dc275b6779644308384459ffcff63fJulian Odell // Try multiple times of MMS HTTP request 162b83f2faa04dc275b6779644308384459ffcff63fJulian Odell for (int i = 0; i < RETRY_TIMES; i++) { 163c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen try { 164b83f2faa04dc275b6779644308384459ffcff63fJulian Odell networkManager.acquireNetwork(); 165b83f2faa04dc275b6779644308384459ffcff63fJulian Odell try { 166b83f2faa04dc275b6779644308384459ffcff63fJulian Odell final ApnSettings apn = ApnSettings.load(context, null/*apnName*/, mSubId); 167b83f2faa04dc275b6779644308384459ffcff63fJulian Odell response = doHttp(context, networkManager, apn); 168b83f2faa04dc275b6779644308384459ffcff63fJulian Odell result = Activity.RESULT_OK; 169b83f2faa04dc275b6779644308384459ffcff63fJulian Odell // Success 170b83f2faa04dc275b6779644308384459ffcff63fJulian Odell break; 171b83f2faa04dc275b6779644308384459ffcff63fJulian Odell } finally { 172b83f2faa04dc275b6779644308384459ffcff63fJulian Odell networkManager.releaseNetwork(); 173b83f2faa04dc275b6779644308384459ffcff63fJulian Odell } 174b83f2faa04dc275b6779644308384459ffcff63fJulian Odell } catch (ApnException e) { 175b83f2faa04dc275b6779644308384459ffcff63fJulian Odell Log.e(MmsService.TAG, "MmsRequest: APN failure", e); 176b83f2faa04dc275b6779644308384459ffcff63fJulian Odell result = SmsManager.MMS_ERROR_INVALID_APN; 177b83f2faa04dc275b6779644308384459ffcff63fJulian Odell break; 178b83f2faa04dc275b6779644308384459ffcff63fJulian Odell } catch (MmsNetworkException e) { 179b83f2faa04dc275b6779644308384459ffcff63fJulian Odell Log.e(MmsService.TAG, "MmsRequest: MMS network acquiring failure", e); 180b83f2faa04dc275b6779644308384459ffcff63fJulian Odell result = SmsManager.MMS_ERROR_UNABLE_CONNECT_MMS; 181b83f2faa04dc275b6779644308384459ffcff63fJulian Odell // Retry 182b83f2faa04dc275b6779644308384459ffcff63fJulian Odell } catch (MmsHttpException e) { 183b83f2faa04dc275b6779644308384459ffcff63fJulian Odell Log.e(MmsService.TAG, "MmsRequest: HTTP or network I/O failure", e); 184b83f2faa04dc275b6779644308384459ffcff63fJulian Odell result = SmsManager.MMS_ERROR_HTTP_FAILURE; 185b83f2faa04dc275b6779644308384459ffcff63fJulian Odell // Retry 186b83f2faa04dc275b6779644308384459ffcff63fJulian Odell } catch (Exception e) { 187b83f2faa04dc275b6779644308384459ffcff63fJulian Odell Log.e(MmsService.TAG, "MmsRequest: unexpected failure", e); 188b83f2faa04dc275b6779644308384459ffcff63fJulian Odell result = SmsManager.MMS_ERROR_UNSPECIFIED; 189c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen break; 190c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } 191b83f2faa04dc275b6779644308384459ffcff63fJulian Odell try { 192b83f2faa04dc275b6779644308384459ffcff63fJulian Odell Thread.sleep(retryDelay * 1000, 0/*nano*/); 193b83f2faa04dc275b6779644308384459ffcff63fJulian Odell } catch (InterruptedException e) {} 194b83f2faa04dc275b6779644308384459ffcff63fJulian Odell retryDelay <<= 1; 195c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } 196c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } 197b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen processResult(context, result, response); 198b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen } 199b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen 200b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen /** 201b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * Try running MMS HTTP request for all the addresses that we can resolve to 202b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * 203b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * @param context The context 204b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * @param netMgr The {@link com.android.mms.service.MmsNetworkManager} 205b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * @param url The HTTP URL 206b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * @param pdu The PDU to send 207b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * @param method The HTTP method to use 208b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * @param apn The APN setting to use 209b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * @return The response data 210b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * @throws MmsHttpException If there is any HTTP/network failure 211b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen */ 212b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen protected byte[] doHttpForResolvedAddresses(Context context, MmsNetworkManager netMgr, 213b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen String url, byte[] pdu, int method, ApnSettings apn) throws MmsHttpException { 214b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen MmsHttpException lastException = null; 215b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen final ConnectivityManager connMgr = 216b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 217b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen // Do HTTP on all the addresses we can resolve to 218b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen for (final InetAddress address : resolveDestination(connMgr, netMgr, url, apn)) { 219b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen try { 220b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen // TODO: we have to use a deprecated API here because with the new 221b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen // ConnectivityManager APIs in LMP, we need to either use a bound process 222b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen // or a bound socket. The former can not be used since we share the 223b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen // phone process with others. The latter is not supported by any HTTP 224b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen // library yet. We have to rely on this API to get things work. Once 225b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen // a multinet aware HTTP lib is ready, we should switch to that and 226b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen // remove all the unnecessary code. 227b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen if (!connMgr.requestRouteToHostAddress( 228b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen ConnectivityManager.TYPE_MOBILE_MMS, address)) { 229b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen throw new MmsHttpException("MmsRequest: can not request a route for host " 230b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen + address); 231b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen } 232b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen return HttpUtils.httpConnection( 233b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen context, 234b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen url, 235b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen pdu, 236b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen method, 237b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen apn.isProxySet(), 238b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen apn.getProxyAddress(), 239b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen apn.getProxyPort(), 240b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen netMgr, 241c984707ecf54d545a4a5809c6ce1d18bf7cee61eYe Wen address instanceof Inet6Address, 242c984707ecf54d545a4a5809c6ce1d18bf7cee61eYe Wen mMmsConfig); 243b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen } catch (MmsHttpException e) { 244b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen lastException = e; 245b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen Log.e(MmsService.TAG, "MmsRequest: failure in trying address " + address, e); 246b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen } 247b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen } 248b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen if (lastException != null) { 249b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen throw lastException; 250b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen } else { 251b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen // Should not reach here 252b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen throw new MmsHttpException("MmsRequest: unknown failure"); 253b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen } 254b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen } 255b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen 256b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen /** 257b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * Resolve the name of the host we are about to connect to, which can be the URL host or 258b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * the proxy host. We only resolve to the supported address types (IPv4 or IPv6 or both) 259b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * based on the MMS network interface's address type, i.e. we only need addresses that 260b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * match the link address type. 261b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * 262b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * @param connMgr The connectivity manager 263b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * @param netMgr The current {@link MmsNetworkManager} 264b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * @param url The HTTP URL 265b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * @param apn The APN setting to use 266b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * @return A list of matching resolved addresses 267b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * @throws MmsHttpException For any network failure 268b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen */ 269b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen private static List<InetAddress> resolveDestination(ConnectivityManager connMgr, 270b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen MmsNetworkManager netMgr, String url, ApnSettings apn) throws MmsHttpException { 271b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen Log.d(MmsService.TAG, "MmsRequest: resolve url " + url); 272b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen // Find the real host to connect to 273b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen String host = null; 274b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen if (apn.isProxySet()) { 275b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen host = apn.getProxyAddress(); 276b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen } else { 277b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen final Uri uri = Uri.parse(url); 278b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen host = uri.getHost(); 279b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen } 280b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen // Find out the link address types: ipv4 or ipv6 or both 281b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen final int addressTypes = getMmsLinkAddressTypes(connMgr, netMgr.getNetwork()); 282b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen Log.d(MmsService.TAG, "MmsRequest: addressTypes=" + addressTypes); 283b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen // Resolve the host to a list of addresses based on supported address types 284b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen return resolveHostName(netMgr, host, addressTypes); 285b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen } 286b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen 287b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen // Address type masks 288b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen private static final int ADDRESS_TYPE_IPV4 = 1; 289b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen private static final int ADDRESS_TYPE_IPV6 = 1 << 1; 290b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen 291b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen /** 292b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * Try to find out if we should use IPv6 or IPv4 for MMS. Basically we check if the MMS 293b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * network interface has IPv6 address or not. If so, we will use IPv6. Otherwise, use 294b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * IPv4. 295b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * 296b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * @param connMgr The connectivity manager 297b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * @return A bit mask indicating what address types we have 298b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen */ 299b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen private static int getMmsLinkAddressTypes(ConnectivityManager connMgr, Network network) { 300b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen int result = 0; 301b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen // Return none if network is not available 302b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen if (network == null) { 303b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen return result; 304b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen } 305b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen final LinkProperties linkProperties = connMgr.getLinkProperties(network); 306b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen if (linkProperties != null) { 307b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen for (InetAddress addr : linkProperties.getAddresses()) { 308b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen if (addr instanceof Inet4Address) { 309b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen result |= ADDRESS_TYPE_IPV4; 310b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen } else if (addr instanceof Inet6Address) { 311b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen result |= ADDRESS_TYPE_IPV6; 312b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen } 313b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen } 314b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen } 315b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen return result; 316b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen } 317b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen 318b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen /** 319b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * Resolve host name to address by specified address types. 320b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * 321b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * @param netMgr The current {@link MmsNetworkManager} 322b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * @param host The host name 323b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * @param addressTypes The required address type in a bit mask 324b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * (0x01: IPv4, 0x10: IPv6, 0x11: both) 325b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * @return 326b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * @throws MmsHttpException 327b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen */ 328b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen private static List<InetAddress> resolveHostName(MmsNetworkManager netMgr, String host, 329b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen int addressTypes) throws MmsHttpException { 330b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen final List<InetAddress> resolved = new ArrayList<InetAddress>(); 331b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen try { 332b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen if (addressTypes != 0) { 333b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen for (final InetAddress addr : netMgr.getAllByName(host)) { 334b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen if ((addressTypes & ADDRESS_TYPE_IPV6) != 0 335b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen && addr instanceof Inet6Address) { 336b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen // Should use IPv6 and this is IPv6 address, add it 337b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen resolved.add(addr); 338b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen } else if ((addressTypes & ADDRESS_TYPE_IPV4) != 0 339b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen && addr instanceof Inet4Address) { 340b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen // Should use IPv4 and this is IPv4 address, add it 341b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen resolved.add(addr); 342b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen } 343b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen } 344b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen } 345b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen if (resolved.size() < 1) { 346b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen throw new MmsHttpException("Failed to resolve " + host 347b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen + " for allowed address types: " + addressTypes); 348b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen } 349b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen return resolved; 350b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen } catch (final UnknownHostException e) { 351b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen throw new MmsHttpException("Failed to resolve " + host, e); 352b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen } 353b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen } 354b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen 355b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen /** 356b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * Process the result of the completed request, including updating the message status 357b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * in database and sending back the result via pending intents. 358b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * 359b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * @param context The context 360b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * @param result The result code of execution 361b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * @param response The response body 362b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen */ 363b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen public void processResult(Context context, int result, byte[] response) { 364b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen updateStatus(context, result, response); 3653a14e46a22e95062102a19c955a819bf239dbc52Ye Wen 366c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen // Return MMS HTTP request result via PendingIntent 367c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen final PendingIntent pendingIntent = getPendingIntent(); 368c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen if (pendingIntent != null) { 369b83f2faa04dc275b6779644308384459ffcff63fJulian Odell boolean succeeded = true; 3703a14e46a22e95062102a19c955a819bf239dbc52Ye Wen // Extra information to send back with the pending intent 3713a14e46a22e95062102a19c955a819bf239dbc52Ye Wen Intent fillIn = new Intent(); 372c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen if (response != null) { 373b83f2faa04dc275b6779644308384459ffcff63fJulian Odell succeeded = transferResponse(fillIn, response); 3743a14e46a22e95062102a19c955a819bf239dbc52Ye Wen } 3753a14e46a22e95062102a19c955a819bf239dbc52Ye Wen if (mMessageUri != null) { 3763a14e46a22e95062102a19c955a819bf239dbc52Ye Wen fillIn.putExtra("uri", mMessageUri.toString()); 377c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } 378c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen try { 379b83f2faa04dc275b6779644308384459ffcff63fJulian Odell if (!succeeded) { 380b83f2faa04dc275b6779644308384459ffcff63fJulian Odell result = SmsManager.MMS_ERROR_IO_ERROR; 381b83f2faa04dc275b6779644308384459ffcff63fJulian Odell } 3823a14e46a22e95062102a19c955a819bf239dbc52Ye Wen pendingIntent.send(context, result, fillIn); 383c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } catch (PendingIntent.CanceledException e) { 384c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen Log.e(MmsService.TAG, "MmsRequest: sending pending intent canceled", e); 385c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } 386c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } 387b2823fa889f5c1bde4047af36b3b07672942f700Julian Odell 388b2823fa889f5c1bde4047af36b3b07672942f700Julian Odell revokeUriPermission(context); 389c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } 390c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen 3913a14e46a22e95062102a19c955a819bf239dbc52Ye Wen /** 3923a14e46a22e95062102a19c955a819bf239dbc52Ye Wen * Making the HTTP request to MMSC 3933a14e46a22e95062102a19c955a819bf239dbc52Ye Wen * 3943a14e46a22e95062102a19c955a819bf239dbc52Ye Wen * @param context The context 395b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen * @param netMgr The current {@link MmsNetworkManager} 3963a14e46a22e95062102a19c955a819bf239dbc52Ye Wen * @param apn The APN setting 3973a14e46a22e95062102a19c955a819bf239dbc52Ye Wen * @return The HTTP response data 3983a14e46a22e95062102a19c955a819bf239dbc52Ye Wen * @throws MmsHttpException If any network error happens 3993a14e46a22e95062102a19c955a819bf239dbc52Ye Wen */ 400b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen protected abstract byte[] doHttp(Context context, MmsNetworkManager netMgr, ApnSettings apn) 401b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen throws MmsHttpException; 402c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen 4033a14e46a22e95062102a19c955a819bf239dbc52Ye Wen /** 4043a14e46a22e95062102a19c955a819bf239dbc52Ye Wen * @return The PendingIntent associate with the MMS sending invocation 4053a14e46a22e95062102a19c955a819bf239dbc52Ye Wen */ 406c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen protected abstract PendingIntent getPendingIntent(); 4073a14e46a22e95062102a19c955a819bf239dbc52Ye Wen 4083a14e46a22e95062102a19c955a819bf239dbc52Ye Wen /** 409b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * @return The running queue should be used by this request 4103a14e46a22e95062102a19c955a819bf239dbc52Ye Wen */ 411b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen protected abstract int getRunningQueue(); 4123a14e46a22e95062102a19c955a819bf239dbc52Ye Wen 4133a14e46a22e95062102a19c955a819bf239dbc52Ye Wen /** 414b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * Update database status of the message represented by this request 4153a14e46a22e95062102a19c955a819bf239dbc52Ye Wen * 4163a14e46a22e95062102a19c955a819bf239dbc52Ye Wen * @param context The context 4173a14e46a22e95062102a19c955a819bf239dbc52Ye Wen * @param result The result code of execution 418b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * @param response The response body 4193a14e46a22e95062102a19c955a819bf239dbc52Ye Wen */ 420b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen protected abstract void updateStatus(Context context, int result, byte[] response); 421b83f2faa04dc275b6779644308384459ffcff63fJulian Odell 422b83f2faa04dc275b6779644308384459ffcff63fJulian Odell /** 423b83f2faa04dc275b6779644308384459ffcff63fJulian Odell * Prepare to make the HTTP request - will download message for sending 424b83f2faa04dc275b6779644308384459ffcff63fJulian Odell * @return true if preparation succeeds (and request can proceed) else false 425b83f2faa04dc275b6779644308384459ffcff63fJulian Odell */ 426b83f2faa04dc275b6779644308384459ffcff63fJulian Odell protected abstract boolean prepareForHttpRequest(); 427b83f2faa04dc275b6779644308384459ffcff63fJulian Odell 428b83f2faa04dc275b6779644308384459ffcff63fJulian Odell /** 429b83f2faa04dc275b6779644308384459ffcff63fJulian Odell * Transfer the received response to the caller 430b83f2faa04dc275b6779644308384459ffcff63fJulian Odell * 431b83f2faa04dc275b6779644308384459ffcff63fJulian Odell * @param fillIn the intent that will be returned to the caller 432b83f2faa04dc275b6779644308384459ffcff63fJulian Odell * @param response the pdu to transfer 433b83f2faa04dc275b6779644308384459ffcff63fJulian Odell * @return true if response transfer succeeds else false 434b83f2faa04dc275b6779644308384459ffcff63fJulian Odell */ 435b83f2faa04dc275b6779644308384459ffcff63fJulian Odell protected abstract boolean transferResponse(Intent fillIn, byte[] response); 436f6d88a72cd01ecaf9f0319249e239afc008f1ac8Cheuksan Wang 437f6d88a72cd01ecaf9f0319249e239afc008f1ac8Cheuksan Wang /** 438f6d88a72cd01ecaf9f0319249e239afc008f1ac8Cheuksan Wang * Revoke the content URI permission granted by the MMS app to the phone package. 439f6d88a72cd01ecaf9f0319249e239afc008f1ac8Cheuksan Wang * 440f6d88a72cd01ecaf9f0319249e239afc008f1ac8Cheuksan Wang * @param context The context 441f6d88a72cd01ecaf9f0319249e239afc008f1ac8Cheuksan Wang */ 442f6d88a72cd01ecaf9f0319249e239afc008f1ac8Cheuksan Wang protected abstract void revokeUriPermission(Context context); 443c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen} 444