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.content.Context; 20c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wenimport android.net.ConnectivityManager; 21c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wenimport android.net.Network; 22c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wenimport android.net.NetworkCapabilities; 23068f2012ef6f6e58f06bfbe7c88604a176d69657Tony Hillimport android.net.NetworkInfo; 247a284e5b43a12ba9e4fa7786786f059bf924dd78Ye Wenimport android.net.NetworkRequest; 25f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskanimport android.os.Handler; 26f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskanimport android.os.Looper; 27c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wenimport android.os.SystemClock; 28c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen 29bdb6fe1cfbc8ecb7ed56798f49de7ba62019fd72Ye Wenimport com.android.mms.service.exception.MmsNetworkException; 30b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen 31c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen/** 32c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen * Manages the MMS network connectivity 33c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen */ 347a284e5b43a12ba9e4fa7786786f059bf924dd78Ye Wenpublic class MmsNetworkManager { 35c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen // Timeout used to call ConnectivityManager.requestNetwork 36d0c5b20403b3924cee67e0e72d745b10b0691eacAndre Furtado // Given that the telephony layer will retry on failures, this timeout should be high enough. 37d0c5b20403b3924cee67e0e72d745b10b0691eacAndre Furtado private static final int NETWORK_REQUEST_TIMEOUT_MILLIS = 30 * 60 * 1000; 38c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen // Wait timeout for this class, a little bit longer than the above timeout 39c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen // to make sure we don't bail prematurely 40c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen private static final int NETWORK_ACQUIRE_TIMEOUT_MILLIS = 412eca933b79d40eb677e878eebb3433dcf2f9db72Ye Wen NETWORK_REQUEST_TIMEOUT_MILLIS + (5 * 1000); 42f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan // Waiting time used before releasing a network prematurely. This allows the MMS download 43f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan // acknowledgement messages to be sent using the same network that was used to download the data 44f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan private static final int NETWORK_RELEASE_TIMEOUT_MILLIS = 5 * 1000; 45c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen 463cf9a9481b8e95d0fb654d083b06ee9a23a8e4e8Ye Wen private final Context mContext; 473cf9a9481b8e95d0fb654d083b06ee9a23a8e4e8Ye Wen 48c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen // The requested MMS {@link android.net.Network} we are holding 49c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen // We need this when we unbind from it. This is also used to indicate if the 50c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen // MMS network is available. 51c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen private Network mNetwork; 52c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen // The current count of MMS requests that require the MMS network 53c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen // If mMmsRequestCount is 0, we should release the MMS network. 54c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen private int mMmsRequestCount; 550e6456d1c034d76bafeee5877327d32753eab13fYe Wen // This is really just for using the capability 563cf9a9481b8e95d0fb654d083b06ee9a23a8e4e8Ye Wen private final NetworkRequest mNetworkRequest; 570e6456d1c034d76bafeee5877327d32753eab13fYe Wen // The callback to register when we request MMS network 580e6456d1c034d76bafeee5877327d32753eab13fYe Wen private ConnectivityManager.NetworkCallback mNetworkCallback; 59c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen 60bdb6fe1cfbc8ecb7ed56798f49de7ba62019fd72Ye Wen private volatile ConnectivityManager mConnectivityManager; 61bdb6fe1cfbc8ecb7ed56798f49de7ba62019fd72Ye Wen 62bdb6fe1cfbc8ecb7ed56798f49de7ba62019fd72Ye Wen // The MMS HTTP client for this network 63bdb6fe1cfbc8ecb7ed56798f49de7ba62019fd72Ye Wen private MmsHttpClient mMmsHttpClient; 642eca933b79d40eb677e878eebb3433dcf2f9db72Ye Wen 65f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan // The handler used for delayed release of the network 66f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan private final Handler mReleaseHandler; 67f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan 68f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan // The task that does the delayed releasing of the network. 69f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan private final Runnable mNetworkReleaseTask; 70f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan 713cf9a9481b8e95d0fb654d083b06ee9a23a8e4e8Ye Wen // The SIM ID which we use to connect 723cf9a9481b8e95d0fb654d083b06ee9a23a8e4e8Ye Wen private final int mSubId; 733cf9a9481b8e95d0fb654d083b06ee9a23a8e4e8Ye Wen 74428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen /** 75428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen * Network callback for our network request 76428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen */ 77428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen private class NetworkRequestCallback extends ConnectivityManager.NetworkCallback { 78428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen @Override 79428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen public void onAvailable(Network network) { 80428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen super.onAvailable(network); 818153aed48a84305533f26c06a07a51bd358cee41Ye Wen LogUtil.i("NetworkCallbackListener.onAvailable: network=" + network); 82428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen synchronized (MmsNetworkManager.this) { 83428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen mNetwork = network; 84428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen MmsNetworkManager.this.notifyAll(); 85428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen } 86428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen } 87428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen 88428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen @Override 89428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen public void onLost(Network network) { 90428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen super.onLost(network); 918153aed48a84305533f26c06a07a51bd358cee41Ye Wen LogUtil.w("NetworkCallbackListener.onLost: network=" + network); 92428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen synchronized (MmsNetworkManager.this) { 93428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen releaseRequestLocked(this); 94428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen MmsNetworkManager.this.notifyAll(); 95428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen } 96428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen } 97428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen 98428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen @Override 99428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen public void onUnavailable() { 100428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen super.onUnavailable(); 1018153aed48a84305533f26c06a07a51bd358cee41Ye Wen LogUtil.w("NetworkCallbackListener.onUnavailable"); 102428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen synchronized (MmsNetworkManager.this) { 103428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen releaseRequestLocked(this); 104428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen MmsNetworkManager.this.notifyAll(); 105428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen } 106428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen } 107428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen } 108428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen 1093cf9a9481b8e95d0fb654d083b06ee9a23a8e4e8Ye Wen public MmsNetworkManager(Context context, int subId) { 110c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen mContext = context; 1110e6456d1c034d76bafeee5877327d32753eab13fYe Wen mNetworkCallback = null; 112c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen mNetwork = null; 113c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen mMmsRequestCount = 0; 1142eca933b79d40eb677e878eebb3433dcf2f9db72Ye Wen mConnectivityManager = null; 115bdb6fe1cfbc8ecb7ed56798f49de7ba62019fd72Ye Wen mMmsHttpClient = null; 1163cf9a9481b8e95d0fb654d083b06ee9a23a8e4e8Ye Wen mSubId = subId; 117f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan mReleaseHandler = new Handler(Looper.getMainLooper()); 1183cf9a9481b8e95d0fb654d083b06ee9a23a8e4e8Ye Wen mNetworkRequest = new NetworkRequest.Builder() 1193cf9a9481b8e95d0fb654d083b06ee9a23a8e4e8Ye Wen .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) 1203cf9a9481b8e95d0fb654d083b06ee9a23a8e4e8Ye Wen .addCapability(NetworkCapabilities.NET_CAPABILITY_MMS) 1213cf9a9481b8e95d0fb654d083b06ee9a23a8e4e8Ye Wen .setNetworkSpecifier(Integer.toString(mSubId)) 1223cf9a9481b8e95d0fb654d083b06ee9a23a8e4e8Ye Wen .build(); 123f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan 124f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan mNetworkReleaseTask = new Runnable() { 125f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan @Override 126f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan public void run() { 127f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan synchronized (this) { 128f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan if (mMmsRequestCount < 1) { 129f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan releaseRequestLocked(mNetworkCallback); 130f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan } 131f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan } 132f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan } 133f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan }; 134b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen } 135b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen 136c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen /** 137c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen * Acquire the MMS network 138c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen * 1398153aed48a84305533f26c06a07a51bd358cee41Ye Wen * @param requestId request ID for logging 140c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen * @throws com.android.mms.service.exception.MmsNetworkException if we fail to acquire it 141c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen */ 1428153aed48a84305533f26c06a07a51bd358cee41Ye Wen public void acquireNetwork(final String requestId) throws MmsNetworkException { 143c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen synchronized (this) { 144f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan // Since we are acquiring the network, remove the network release task if exists. 145f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan mReleaseHandler.removeCallbacks(mNetworkReleaseTask); 146c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen mMmsRequestCount += 1; 147c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen if (mNetwork != null) { 148c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen // Already available 1498153aed48a84305533f26c06a07a51bd358cee41Ye Wen LogUtil.d(requestId, "MmsNetworkManager: already available"); 150c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen return; 151c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } 152428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen // Not available, so start a new request if not done yet 153428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen if (mNetworkCallback == null) { 1548153aed48a84305533f26c06a07a51bd358cee41Ye Wen LogUtil.d(requestId, "MmsNetworkManager: start new network request"); 155428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen startNewNetworkRequestLocked(); 156428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen } 157c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen final long shouldEnd = SystemClock.elapsedRealtime() + NETWORK_ACQUIRE_TIMEOUT_MILLIS; 158c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen long waitTime = NETWORK_ACQUIRE_TIMEOUT_MILLIS; 159c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen while (waitTime > 0) { 160c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen try { 161c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen this.wait(waitTime); 162c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } catch (InterruptedException e) { 1638153aed48a84305533f26c06a07a51bd358cee41Ye Wen LogUtil.w(requestId, "MmsNetworkManager: acquire network wait interrupted"); 164c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } 165c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen if (mNetwork != null) { 166c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen // Success 167c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen return; 168c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } 169c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen // Calculate remaining waiting time to make sure we wait the full timeout period 170c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen waitTime = shouldEnd - SystemClock.elapsedRealtime(); 171c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } 172c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen // Timed out, so release the request and fail 1738153aed48a84305533f26c06a07a51bd358cee41Ye Wen LogUtil.e(requestId, "MmsNetworkManager: timed out"); 174f3debb19850814e9a857cd45f55cf48cf30f51e0Ye Wen releaseRequestLocked(mNetworkCallback); 175c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen throw new MmsNetworkException("Acquiring network timed out"); 176c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } 177c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } 178c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen 179c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen /** 180c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen * Release the MMS network when nobody is holding on to it. 1818153aed48a84305533f26c06a07a51bd358cee41Ye Wen * 1828153aed48a84305533f26c06a07a51bd358cee41Ye Wen * @param requestId request ID for logging 183f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan * @param shouldDelayRelease whether the release should be delayed for 5 seconds, the regular 184f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan * use case is to delay this for DownloadRequests to use the network 185f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan * for sending an acknowledgement on the same network 186c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen */ 187f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan public void releaseNetwork(final String requestId, final boolean shouldDelayRelease) { 188c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen synchronized (this) { 1890e6456d1c034d76bafeee5877327d32753eab13fYe Wen if (mMmsRequestCount > 0) { 1900e6456d1c034d76bafeee5877327d32753eab13fYe Wen mMmsRequestCount -= 1; 1918153aed48a84305533f26c06a07a51bd358cee41Ye Wen LogUtil.d(requestId, "MmsNetworkManager: release, count=" + mMmsRequestCount); 1920e6456d1c034d76bafeee5877327d32753eab13fYe Wen if (mMmsRequestCount < 1) { 193f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan if (shouldDelayRelease) { 194f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan // remove previously posted task and post a delayed task on the release 195f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan // handler to release the network 196f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan mReleaseHandler.removeCallbacks(mNetworkReleaseTask); 197f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan mReleaseHandler.postDelayed(mNetworkReleaseTask, 198f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan NETWORK_RELEASE_TIMEOUT_MILLIS); 199f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan } else { 200f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan releaseRequestLocked(mNetworkCallback); 201f37c91b2ad585acf86f843efc275a063615b0f3bSahin Caliskan } 202c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } 203c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } 204c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } 205c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } 206c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen 207c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen /** 208c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen * Start a new {@link android.net.NetworkRequest} for MMS 209c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen */ 210428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen private void startNewNetworkRequestLocked() { 2112eca933b79d40eb677e878eebb3433dcf2f9db72Ye Wen final ConnectivityManager connectivityManager = getConnectivityManager(); 212428fa0b017e40c2cd210a4c974e57c5e85584441Ye Wen mNetworkCallback = new NetworkRequestCallback(); 2130e6456d1c034d76bafeee5877327d32753eab13fYe Wen connectivityManager.requestNetwork( 2140e6456d1c034d76bafeee5877327d32753eab13fYe Wen mNetworkRequest, mNetworkCallback, NETWORK_REQUEST_TIMEOUT_MILLIS); 215c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } 216c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen 217c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen /** 218c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen * Release the current {@link android.net.NetworkRequest} for MMS 2190e6456d1c034d76bafeee5877327d32753eab13fYe Wen * 2200e6456d1c034d76bafeee5877327d32753eab13fYe Wen * @param callback the {@link android.net.ConnectivityManager.NetworkCallback} to unregister 2210e6456d1c034d76bafeee5877327d32753eab13fYe Wen */ 222f3debb19850814e9a857cd45f55cf48cf30f51e0Ye Wen private void releaseRequestLocked(ConnectivityManager.NetworkCallback callback) { 2230e6456d1c034d76bafeee5877327d32753eab13fYe Wen if (callback != null) { 2242eca933b79d40eb677e878eebb3433dcf2f9db72Ye Wen final ConnectivityManager connectivityManager = getConnectivityManager(); 2257109ffadcf870446f6d606513ac6ca66b2ec83b4Ye Wen try { 2267109ffadcf870446f6d606513ac6ca66b2ec83b4Ye Wen connectivityManager.unregisterNetworkCallback(callback); 2277109ffadcf870446f6d606513ac6ca66b2ec83b4Ye Wen } catch (IllegalArgumentException e) { 2287109ffadcf870446f6d606513ac6ca66b2ec83b4Ye Wen // It is possible ConnectivityManager.requestNetwork may fail silently due 2297109ffadcf870446f6d606513ac6ca66b2ec83b4Ye Wen // to RemoteException. When that happens, we may get an invalid 2307109ffadcf870446f6d606513ac6ca66b2ec83b4Ye Wen // NetworkCallback, which causes an IllegalArgumentexception when we try to 2317109ffadcf870446f6d606513ac6ca66b2ec83b4Ye Wen // unregisterNetworkCallback. This exception in turn causes 2327109ffadcf870446f6d606513ac6ca66b2ec83b4Ye Wen // MmsNetworkManager to skip resetLocked() in the below. Thus MMS service 2337109ffadcf870446f6d606513ac6ca66b2ec83b4Ye Wen // would get stuck in the bad state until the device restarts. This fix 2347109ffadcf870446f6d606513ac6ca66b2ec83b4Ye Wen // catches the exception so that state clean up can be executed. 2357109ffadcf870446f6d606513ac6ca66b2ec83b4Ye Wen LogUtil.w("Unregister network callback exception", e); 2367109ffadcf870446f6d606513ac6ca66b2ec83b4Ye Wen } 2370e6456d1c034d76bafeee5877327d32753eab13fYe Wen } 238f3debb19850814e9a857cd45f55cf48cf30f51e0Ye Wen resetLocked(); 2390e6456d1c034d76bafeee5877327d32753eab13fYe Wen } 2400e6456d1c034d76bafeee5877327d32753eab13fYe Wen 2410e6456d1c034d76bafeee5877327d32753eab13fYe Wen /** 2420e6456d1c034d76bafeee5877327d32753eab13fYe Wen * Reset the state 243c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen */ 244db7f2fadc52aeaad26450d3a59c1dc9df539780cYe Wen private void resetLocked() { 2450e6456d1c034d76bafeee5877327d32753eab13fYe Wen mNetworkCallback = null; 2460e6456d1c034d76bafeee5877327d32753eab13fYe Wen mNetwork = null; 2470e6456d1c034d76bafeee5877327d32753eab13fYe Wen mMmsRequestCount = 0; 248bdb6fe1cfbc8ecb7ed56798f49de7ba62019fd72Ye Wen mMmsHttpClient = null; 249c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen } 250b07ae2f78ac69a1e7bcfb1ce62e69d7283b46295Ye Wen 2512eca933b79d40eb677e878eebb3433dcf2f9db72Ye Wen private ConnectivityManager getConnectivityManager() { 2522eca933b79d40eb677e878eebb3433dcf2f9db72Ye Wen if (mConnectivityManager == null) { 2532eca933b79d40eb677e878eebb3433dcf2f9db72Ye Wen mConnectivityManager = (ConnectivityManager) mContext.getSystemService( 2542eca933b79d40eb677e878eebb3433dcf2f9db72Ye Wen Context.CONNECTIVITY_SERVICE); 2552eca933b79d40eb677e878eebb3433dcf2f9db72Ye Wen } 2562eca933b79d40eb677e878eebb3433dcf2f9db72Ye Wen return mConnectivityManager; 2572eca933b79d40eb677e878eebb3433dcf2f9db72Ye Wen } 2582eca933b79d40eb677e878eebb3433dcf2f9db72Ye Wen 259bdb6fe1cfbc8ecb7ed56798f49de7ba62019fd72Ye Wen /** 260bdb6fe1cfbc8ecb7ed56798f49de7ba62019fd72Ye Wen * Get an MmsHttpClient for the current network 261bdb6fe1cfbc8ecb7ed56798f49de7ba62019fd72Ye Wen * 262bdb6fe1cfbc8ecb7ed56798f49de7ba62019fd72Ye Wen * @return The MmsHttpClient instance 263bdb6fe1cfbc8ecb7ed56798f49de7ba62019fd72Ye Wen */ 264bdb6fe1cfbc8ecb7ed56798f49de7ba62019fd72Ye Wen public MmsHttpClient getOrCreateHttpClient() { 265bdb6fe1cfbc8ecb7ed56798f49de7ba62019fd72Ye Wen synchronized (this) { 266bdb6fe1cfbc8ecb7ed56798f49de7ba62019fd72Ye Wen if (mMmsHttpClient == null) { 267bdb6fe1cfbc8ecb7ed56798f49de7ba62019fd72Ye Wen if (mNetwork != null) { 268bdb6fe1cfbc8ecb7ed56798f49de7ba62019fd72Ye Wen // Create new MmsHttpClient for the current Network 269eeb364a1e8916609bee877b893443bd940ea87daYe Wen mMmsHttpClient = new MmsHttpClient(mContext, mNetwork, mConnectivityManager); 270bdb6fe1cfbc8ecb7ed56798f49de7ba62019fd72Ye Wen } 271bdb6fe1cfbc8ecb7ed56798f49de7ba62019fd72Ye Wen } 272bdb6fe1cfbc8ecb7ed56798f49de7ba62019fd72Ye Wen return mMmsHttpClient; 273bdb6fe1cfbc8ecb7ed56798f49de7ba62019fd72Ye Wen } 274bdb6fe1cfbc8ecb7ed56798f49de7ba62019fd72Ye Wen } 275068f2012ef6f6e58f06bfbe7c88604a176d69657Tony Hill 276068f2012ef6f6e58f06bfbe7c88604a176d69657Tony Hill /** 277068f2012ef6f6e58f06bfbe7c88604a176d69657Tony Hill * Get the APN name for the active network 278068f2012ef6f6e58f06bfbe7c88604a176d69657Tony Hill * 279068f2012ef6f6e58f06bfbe7c88604a176d69657Tony Hill * @return The APN name if available, otherwise null 280068f2012ef6f6e58f06bfbe7c88604a176d69657Tony Hill */ 281068f2012ef6f6e58f06bfbe7c88604a176d69657Tony Hill public String getApnName() { 282068f2012ef6f6e58f06bfbe7c88604a176d69657Tony Hill Network network = null; 283068f2012ef6f6e58f06bfbe7c88604a176d69657Tony Hill synchronized (this) { 284068f2012ef6f6e58f06bfbe7c88604a176d69657Tony Hill if (mNetwork == null) { 285068f2012ef6f6e58f06bfbe7c88604a176d69657Tony Hill return null; 286068f2012ef6f6e58f06bfbe7c88604a176d69657Tony Hill } 287068f2012ef6f6e58f06bfbe7c88604a176d69657Tony Hill network = mNetwork; 288068f2012ef6f6e58f06bfbe7c88604a176d69657Tony Hill } 289068f2012ef6f6e58f06bfbe7c88604a176d69657Tony Hill String apnName = null; 290068f2012ef6f6e58f06bfbe7c88604a176d69657Tony Hill final ConnectivityManager connectivityManager = getConnectivityManager(); 2918153aed48a84305533f26c06a07a51bd358cee41Ye Wen final NetworkInfo mmsNetworkInfo = connectivityManager.getNetworkInfo(network); 292068f2012ef6f6e58f06bfbe7c88604a176d69657Tony Hill if (mmsNetworkInfo != null) { 293068f2012ef6f6e58f06bfbe7c88604a176d69657Tony Hill apnName = mmsNetworkInfo.getExtraInfo(); 294068f2012ef6f6e58f06bfbe7c88604a176d69657Tony Hill } 295068f2012ef6f6e58f06bfbe7c88604a176d69657Tony Hill return apnName; 296068f2012ef6f6e58f06bfbe7c88604a176d69657Tony Hill } 297c91cc9d4a5aa12a570a3b35a12b3e34a6a9eeb51Ye Wen} 298