MmsRequest.java revision 18aabe2742cbaffc3c8293cfb3ce2841fe82326d
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; 26c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wenimport android.content.Context; 27c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wenimport android.content.Intent; 283a14e46a22e95062102a19c955a819bf239dbc52Ye Wenimport android.net.Uri; 29b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wenimport android.os.Bundle; 30b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wenimport android.provider.Telephony; 314fd5a8951574cb8a74126c41ec890374eb09e8b9Ye Wenimport android.telephony.SmsManager; 32c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wenimport android.util.Log; 33c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen 34c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen/** 35c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen * Base class for MMS requests. This has the common logic of sending/downloading MMS. 36c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen */ 37c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wenpublic abstract class MmsRequest { 38c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen private static final int RETRY_TIMES = 3; 39c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen 40b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen protected static final String EXTRA_MESSAGE_REF = "messageref"; 41b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen 42b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen /** 43b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * Interface for certain functionalities from MmsService 44b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen */ 45b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen public static interface RequestManager { 46b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen /** 47b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * Add a request to pending queue when it is executed by carrier app 48b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * 49b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * @param key The message ref key from carrier app 50b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * @param request The request in pending 51b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen */ 52b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen public void addPending(int key, MmsRequest request); 53b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen 54b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen /** 55b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * Enqueue an MMS request for running 56b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * 57b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * @param request the request to enqueue 58b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen */ 59b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen public void addRunning(MmsRequest request); 60b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen } 61b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen 623a14e46a22e95062102a19c955a819bf239dbc52Ye Wen // The URI of persisted message 633a14e46a22e95062102a19c955a819bf239dbc52Ye Wen protected Uri mMessageUri; 64b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen // The reference to the pending requests manager (i.e. the MmsService) 65b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen protected RequestManager mRequestManager; 6618aabe2742cbaffc3c8293cfb3ce2841fe82326dYe Wen // The SIM id 6718aabe2742cbaffc3c8293cfb3ce2841fe82326dYe Wen protected long mSubId; 6818aabe2742cbaffc3c8293cfb3ce2841fe82326dYe Wen // The creator app 6918aabe2742cbaffc3c8293cfb3ce2841fe82326dYe Wen protected String mCreator; 70b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen 71b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen // Intent result receiver for carrier app 72b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen protected final BroadcastReceiver mCarrierAppResultReceiver = new BroadcastReceiver() { 73b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen @Override 74b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen public void onReceive(Context context, Intent intent) { 75b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen final String action = intent.getAction(); 76b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen if (action.equals(Telephony.Mms.Intents.MMS_SEND_ACTION) || 77b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen action.equals(Telephony.Mms.Intents.MMS_DOWNLOAD_ACTION)) { 78b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen Log.d(MmsService.TAG, "Carrier app result for " + action); 79b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen final int rc = getResultCode(); 80b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen if (rc == Activity.RESULT_OK) { 81b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen // Handled by carrier app, waiting for result 82b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen Log.d(MmsService.TAG, "Sending/downloading MMS by IP pending."); 83b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen final Bundle resultExtras = getResultExtras(false); 84b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen if (resultExtras != null && resultExtras.containsKey(EXTRA_MESSAGE_REF)) { 85b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen final int ref = resultExtras.getInt(EXTRA_MESSAGE_REF); 86b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen Log.d(MmsService.TAG, "messageref = " + ref); 87b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen mRequestManager.addPending(ref, MmsRequest.this); 88b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen } else { 89b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen // Bad, no message ref provided 90b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen Log.e(MmsService.TAG, "Can't find messageref in result extras."); 91b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen } 92b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen } else { 93b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen // No carrier app present, sending normally 94b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen Log.d(MmsService.TAG, "Sending/downloading MMS by IP failed."); 95b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen mRequestManager.addRunning(MmsRequest.this); 96b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen } 97b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen } else { 98b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen Log.e(MmsService.TAG, "unexpected BroadcastReceiver action: " + action); 99b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen } 100b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen 101b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen } 102b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen }; 103b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen 10418aabe2742cbaffc3c8293cfb3ce2841fe82326dYe Wen public MmsRequest(RequestManager requestManager, Uri messageUri, long subId, String creator) { 105b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen mRequestManager = requestManager; 10618aabe2742cbaffc3c8293cfb3ce2841fe82326dYe Wen mMessageUri = messageUri; 10718aabe2742cbaffc3c8293cfb3ce2841fe82326dYe Wen mSubId = subId; 10818aabe2742cbaffc3c8293cfb3ce2841fe82326dYe Wen mCreator = creator; 109b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen } 1103a14e46a22e95062102a19c955a819bf239dbc52Ye Wen 111b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen /** 112b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * Execute the request 113b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * 114b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * @param context The context 115b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * @param networkManager The network manager to use 116b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen */ 117c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen public void execute(Context context, MmsNetworkManager networkManager) { 118c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen int result = Activity.RESULT_OK; 119c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen byte[] response = null; 120c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen long retryDelay = 2; 121c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen // Try multiple times of MMS HTTP request 122c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen for (int i = 0; i < RETRY_TIMES; i++) { 123c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen try { 124c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen networkManager.acquireNetwork(); 125c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen try { 12618aabe2742cbaffc3c8293cfb3ce2841fe82326dYe Wen final ApnSettings apn = ApnSettings.load(context, null/*apnName*/, mSubId); 127c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen response = doHttp(context, apn); 12829d99f9775eb58623b2f0e5c132ba06f348136aeYe Wen result = Activity.RESULT_OK; 129c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen // Success 130c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen break; 131c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } finally { 132c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen networkManager.releaseNetwork(); 133c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } 134c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } catch (ApnException e) { 135c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen Log.e(MmsService.TAG, "MmsRequest: APN failure", e); 1364fd5a8951574cb8a74126c41ec890374eb09e8b9Ye Wen result = SmsManager.MMS_ERROR_INVALID_APN; 137c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen break; 138c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } catch (MmsNetworkException e) { 139c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen Log.e(MmsService.TAG, "MmsRequest: MMS network acquiring failure", e); 1404fd5a8951574cb8a74126c41ec890374eb09e8b9Ye Wen result = SmsManager.MMS_ERROR_UNABLE_CONNECT_MMS; 141c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen // Retry 142c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } catch (MmsHttpException e) { 143c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen Log.e(MmsService.TAG, "MmsRequest: HTTP or network I/O failure", e); 1444fd5a8951574cb8a74126c41ec890374eb09e8b9Ye Wen result = SmsManager.MMS_ERROR_HTTP_FAILURE; 145c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen // Retry 146c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } catch (Exception e) { 147c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen Log.e(MmsService.TAG, "MmsRequest: unexpected failure", e); 1484fd5a8951574cb8a74126c41ec890374eb09e8b9Ye Wen result = SmsManager.MMS_ERROR_UNSPECIFIED; 149c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen break; 150c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } 151c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen try { 152c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen Thread.sleep(retryDelay * 1000, 0/*nano*/); 153c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } catch (InterruptedException e) {} 154c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen retryDelay <<= 1; 155c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } 156b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen processResult(context, result, response); 157b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen } 158b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen 159b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen /** 160b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * Process the result of the completed request, including updating the message status 161b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * in database and sending back the result via pending intents. 162b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * 163b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * @param context The context 164b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * @param result The result code of execution 165b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * @param response The response body 166b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen */ 167b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen public void processResult(Context context, int result, byte[] response) { 168b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen updateStatus(context, result, response); 1693a14e46a22e95062102a19c955a819bf239dbc52Ye Wen 170c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen // Return MMS HTTP request result via PendingIntent 171c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen final PendingIntent pendingIntent = getPendingIntent(); 172c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen if (pendingIntent != null) { 1733a14e46a22e95062102a19c955a819bf239dbc52Ye Wen // Extra information to send back with the pending intent 1743a14e46a22e95062102a19c955a819bf239dbc52Ye Wen Intent fillIn = new Intent(); 175c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen if (response != null) { 1763a14e46a22e95062102a19c955a819bf239dbc52Ye Wen fillIn.putExtra(SmsManager.MMS_EXTRA_DATA, response); 1773a14e46a22e95062102a19c955a819bf239dbc52Ye Wen } 1783a14e46a22e95062102a19c955a819bf239dbc52Ye Wen if (mMessageUri != null) { 1793a14e46a22e95062102a19c955a819bf239dbc52Ye Wen fillIn.putExtra("uri", mMessageUri.toString()); 180c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } 181c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen try { 1823a14e46a22e95062102a19c955a819bf239dbc52Ye Wen pendingIntent.send(context, result, fillIn); 183c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } catch (PendingIntent.CanceledException e) { 184c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen Log.e(MmsService.TAG, "MmsRequest: sending pending intent canceled", e); 185c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } 186c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } 187c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } 188c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen 1893a14e46a22e95062102a19c955a819bf239dbc52Ye Wen /** 1903a14e46a22e95062102a19c955a819bf239dbc52Ye Wen * Making the HTTP request to MMSC 1913a14e46a22e95062102a19c955a819bf239dbc52Ye Wen * 1923a14e46a22e95062102a19c955a819bf239dbc52Ye Wen * @param context The context 1933a14e46a22e95062102a19c955a819bf239dbc52Ye Wen * @param apn The APN setting 1943a14e46a22e95062102a19c955a819bf239dbc52Ye Wen * @return The HTTP response data 1953a14e46a22e95062102a19c955a819bf239dbc52Ye Wen * @throws MmsHttpException If any network error happens 1963a14e46a22e95062102a19c955a819bf239dbc52Ye Wen */ 197c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen protected abstract byte[] doHttp(Context context, ApnSettings apn) throws MmsHttpException; 198c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen 1993a14e46a22e95062102a19c955a819bf239dbc52Ye Wen /** 2003a14e46a22e95062102a19c955a819bf239dbc52Ye Wen * @return The PendingIntent associate with the MMS sending invocation 2013a14e46a22e95062102a19c955a819bf239dbc52Ye Wen */ 202c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen protected abstract PendingIntent getPendingIntent(); 2033a14e46a22e95062102a19c955a819bf239dbc52Ye Wen 2043a14e46a22e95062102a19c955a819bf239dbc52Ye Wen /** 205b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * @return The running queue should be used by this request 2063a14e46a22e95062102a19c955a819bf239dbc52Ye Wen */ 207b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen protected abstract int getRunningQueue(); 2083a14e46a22e95062102a19c955a819bf239dbc52Ye Wen 2093a14e46a22e95062102a19c955a819bf239dbc52Ye Wen /** 210b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * Update database status of the message represented by this request 2113a14e46a22e95062102a19c955a819bf239dbc52Ye Wen * 2123a14e46a22e95062102a19c955a819bf239dbc52Ye Wen * @param context The context 2133a14e46a22e95062102a19c955a819bf239dbc52Ye Wen * @param result The result code of execution 214b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen * @param response The response body 2153a14e46a22e95062102a19c955a819bf239dbc52Ye Wen */ 216b786d3ea3daf4a91119ea06c532fe7ef5835944cYe Wen protected abstract void updateStatus(Context context, int result, byte[] response); 217c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen} 218