Select VVM network transport base on carrier config
Copied from ag/822719 and removed the wifi settings part
+ OmtpVvmSyncService and FetchVoicemailReceiver now let
VvmNetworkRequestCallback choose which network to use,
based on carrier config.
It was originally based on protocol type, which is just a
coincidence for the current supported carrier.
+ Add a timeout checker for VvmNetworkRequestCallback. The
timeout overload of ConnectivityManager.requestNetwork() is not
triggering a timeout for some unknown reason, and since it's a
hidden method, choose to implement one our own.
NO_SQ:Submit Queue doesn't pull in dependent changes so it fail
every time.
Change-Id: I9b5037e2dcb875a4e6c60f01ab4b18a287bc3b54
diff --git a/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelper.java b/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelper.java
index 9f39db1..9393f81 100644
--- a/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelper.java
+++ b/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelper.java
@@ -88,6 +88,14 @@
}
}
+ public boolean isCellularDataRequired() {
+ if (mCarrierConfig == null) {
+ return false;
+ }
+ return mCarrierConfig
+ .getBoolean(CarrierConfigManager.KEY_VVM_CELLULAR_DATA_REQUIRED_BOOLEAN);
+ }
+
public void startActivation() {
OmtpMessageSender messageSender = getMessageSender();
if (messageSender != null) {
diff --git a/src/com/android/phone/vvm/omtp/fetch/FetchVoicemailReceiver.java b/src/com/android/phone/vvm/omtp/fetch/FetchVoicemailReceiver.java
index 0f9a41f..da60ad1 100644
--- a/src/com/android/phone/vvm/omtp/fetch/FetchVoicemailReceiver.java
+++ b/src/com/android/phone/vvm/omtp/fetch/FetchVoicemailReceiver.java
@@ -22,7 +22,6 @@
import android.database.Cursor;
import android.net.ConnectivityManager;
import android.net.Network;
-import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.net.Uri;
import android.provider.VoicemailContract;
@@ -36,16 +35,18 @@
import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
import com.android.phone.vvm.omtp.imap.ImapHelper;
import com.android.phone.vvm.omtp.sync.OmtpVvmSourceManager;
+import com.android.phone.vvm.omtp.sync.VvmNetworkRequestCallback;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class FetchVoicemailReceiver extends BroadcastReceiver {
+
private static final String TAG = "FetchVoicemailReceiver";
final static String[] PROJECTION = new String[] {
- Voicemails.SOURCE_DATA, // 0
- Voicemails.PHONE_ACCOUNT_ID, // 1
+ Voicemails.SOURCE_DATA, // 0
+ Voicemails.PHONE_ACCOUNT_ID, // 1
};
public static final int SOURCE_DATA = 0;
@@ -60,7 +61,7 @@
private ContentResolver mContentResolver;
private Uri mUri;
private NetworkRequest mNetworkRequest;
- private OmtpVvmNetworkRequestCallback mNetworkCallback;
+ private VvmNetworkRequestCallback mNetworkCallback;
private Context mContext;
private String mUid;
private ConnectivityManager mConnectivityManager;
@@ -115,18 +116,9 @@
OmtpVvmCarrierConfigHelper carrierConfigHelper =
new OmtpVvmCarrierConfigHelper(context, subId);
- if (TelephonyManager.VVM_TYPE_CVVM.equals(carrierConfigHelper.getVvmType())) {
- fetchVoicemail(null);
- } else {
- mNetworkRequest = new NetworkRequest.Builder()
- .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
- .setNetworkSpecifier(Integer.toString(subId))
- .build();
-
- mNetworkCallback = new OmtpVvmNetworkRequestCallback();
- requestNetwork();
- }
+ mNetworkCallback = new fetchVoicemailNetworkRequestCallback(context,
+ mPhoneAccount);
+ mNetworkCallback.requestNetwork();
}
} finally {
cursor.close();
@@ -134,21 +126,18 @@
}
}
- private class OmtpVvmNetworkRequestCallback extends ConnectivityManager.NetworkCallback {
+ private class fetchVoicemailNetworkRequestCallback extends VvmNetworkRequestCallback {
+
+ public fetchVoicemailNetworkRequestCallback(Context context,
+ PhoneAccountHandle phoneAccount) {
+ super(context, phoneAccount);
+ }
+
@Override
public void onAvailable(final Network network) {
+ super.onAvailable(network);
fetchVoicemail(network);
}
-
- @Override
- public void onLost(Network network) {
- releaseNetwork();
- }
-
- @Override
- public void onUnavailable() {
- releaseNetwork();
- }
}
private void fetchVoicemail(final Network network) {
@@ -156,44 +145,28 @@
executor.execute(new Runnable() {
@Override
public void run() {
- while (mRetryCount > 0) {
- ImapHelper imapHelper = new ImapHelper(mContext, mPhoneAccount, network);
- if (!imapHelper.isSuccessfullyInitialized()) {
- Log.w(TAG, "Can't retrieve Imap credentials.");
- // releaseNetwork() will check if the network callback exists
- releaseNetwork();
- return;
- }
+ try {
+ while (mRetryCount > 0) {
+ ImapHelper imapHelper = new ImapHelper(mContext, mPhoneAccount, network);
+ if (!imapHelper.isSuccessfullyInitialized()) {
+ Log.w(TAG, "Can't retrieve Imap credentials.");
+ return;
+ }
- boolean success = imapHelper.fetchVoicemailPayload(
- new VoicemailFetchedCallback(mContext, mUri), mUid);
- if (!success && mRetryCount > 0) {
- mRetryCount--;
- } else {
- releaseNetwork();
- return;
+ boolean success = imapHelper.fetchVoicemailPayload(
+ new VoicemailFetchedCallback(mContext, mUri), mUid);
+ if (!success && mRetryCount > 0) {
+ mRetryCount--;
+ } else {
+ return;
+ }
+ }
+ } finally {
+ if (mNetworkCallback != null) {
+ mNetworkCallback.releaseNetwork();
}
}
}
});
}
-
- private void requestNetwork() {
- getConnectivityManager().requestNetwork(
- mNetworkRequest, mNetworkCallback, NETWORK_REQUEST_TIMEOUT_MILLIS);
- }
-
- private void releaseNetwork() {
- if (mNetworkCallback != null) {
- getConnectivityManager().unregisterNetworkCallback(mNetworkCallback);
- }
- }
-
- private ConnectivityManager getConnectivityManager() {
- if (mConnectivityManager == null) {
- mConnectivityManager = (ConnectivityManager) mContext.getSystemService(
- Context.CONNECTIVITY_SERVICE);
- }
- return mConnectivityManager;
- }
}
diff --git a/src/com/android/phone/vvm/omtp/sync/OmtpVvmNetworkRequestCallback.java b/src/com/android/phone/vvm/omtp/sync/OmtpVvmNetworkRequestCallback.java
deleted file mode 100644
index 7ee38ed..0000000
--- a/src/com/android/phone/vvm/omtp/sync/OmtpVvmNetworkRequestCallback.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-package com.android.phone.vvm.omtp.sync;
-
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
-import android.telecom.PhoneAccountHandle;
-
-import com.android.phone.PhoneUtils;
-/**
- * Base class for network request call backs for visual voicemail syncing with the Imap server.
- * This handles retries and network requests.
- */
-public abstract class OmtpVvmNetworkRequestCallback extends ConnectivityManager.NetworkCallback {
- // Timeout used to call ConnectivityManager.requestNetwork
- private static final int NETWORK_REQUEST_TIMEOUT_MILLIS = 60 * 1000;
-
- protected Context mContext;
- protected PhoneAccountHandle mPhoneAccount;
- protected String mAction;
- protected NetworkRequest mNetworkRequest;
- private ConnectivityManager mConnectivityManager;
-
- public OmtpVvmNetworkRequestCallback(Context context, PhoneAccountHandle phoneAccount,
- String action) {
- mContext = context;
- mPhoneAccount = phoneAccount;
- mAction = action;
- mNetworkRequest = new NetworkRequest.Builder()
- .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
- .setNetworkSpecifier(
- Integer.toString(PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccount)))
- .build();
- }
-
- public NetworkRequest getNetworkRequest() {
- return mNetworkRequest;
- }
-
- @Override
- public void onLost(Network network) {
- releaseNetwork();
- }
-
- @Override
- public void onUnavailable() {
- releaseNetwork();
- }
-
- public void requestNetwork() {
- getConnectivityManager().requestNetwork(getNetworkRequest(), this,
- NETWORK_REQUEST_TIMEOUT_MILLIS);
- }
-
- public void releaseNetwork() {
- getConnectivityManager().unregisterNetworkCallback(this);
- }
-
- private ConnectivityManager getConnectivityManager() {
- if (mConnectivityManager == null) {
- mConnectivityManager = (ConnectivityManager) mContext.getSystemService(
- Context.CONNECTIVITY_SERVICE);
- }
- return mConnectivityManager;
- }
-}
diff --git a/src/com/android/phone/vvm/omtp/sync/OmtpVvmSyncService.java b/src/com/android/phone/vvm/omtp/sync/OmtpVvmSyncService.java
index 1f6412b..c2e0687 100644
--- a/src/com/android/phone/vvm/omtp/sync/OmtpVvmSyncService.java
+++ b/src/com/android/phone/vvm/omtp/sync/OmtpVvmSyncService.java
@@ -21,17 +21,15 @@
import android.content.Context;
import android.content.Intent;
import android.net.Network;
+import android.net.NetworkInfo;
import android.provider.VoicemailContract;
import android.telecom.PhoneAccountHandle;
import android.telecom.Voicemail;
-import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
-import com.android.phone.PhoneUtils;
import com.android.phone.settings.VisualVoicemailSettingsUtil;
import com.android.phone.vvm.omtp.LocalLogHelper;
-import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
import com.android.phone.vvm.omtp.imap.ImapHelper;
import java.util.HashMap;
@@ -43,6 +41,7 @@
* Sync OMTP visual voicemail.
*/
public class OmtpVvmSyncService extends IntentService {
+
private static final String TAG = OmtpVvmSyncService.class.getSimpleName();
// Number of retries
@@ -189,57 +188,47 @@
this, phoneAccount, currentTime);
}
- int subId = PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccount);
- OmtpVvmCarrierConfigHelper carrierConfigHelper =
- new OmtpVvmCarrierConfigHelper(this, subId);
-
- if (TelephonyManager.VVM_TYPE_CVVM.equals(carrierConfigHelper.getVvmType())) {
- if (voicemail == null) {
- doSync(null, null, phoneAccount, voicemail, action);
- }
- } else {
- OmtpVvmNetworkRequestCallback networkCallback =
- new SyncAllNetworkRequestCallback(this, phoneAccount, voicemail, action);
- networkCallback.requestNetwork();
- }
+ VvmNetworkRequestCallback networkCallback = new SyncNetworkRequestCallback(this,
+ phoneAccount, voicemail, action);
+ networkCallback.requestNetwork();
}
- private void doSync(Network network, OmtpVvmNetworkRequestCallback callback,
+ private void doSync(Network network, VvmNetworkRequestCallback callback,
PhoneAccountHandle phoneAccount, Voicemail voicemail, String action) {
int retryCount = NETWORK_RETRY_COUNT;
- while (retryCount > 0) {
- ImapHelper imapHelper = new ImapHelper(this, phoneAccount, network);
- if (!imapHelper.isSuccessfullyInitialized()) {
- Log.w(TAG, "Can't retrieve Imap credentials.");
- if (callback != null) {
- callback.releaseNetwork();
+ try {
+ while (retryCount > 0) {
+ ImapHelper imapHelper = new ImapHelper(this, phoneAccount, network);
+ if (!imapHelper.isSuccessfullyInitialized()) {
+ Log.w(TAG, "Can't retrieve Imap credentials.");
+ VisualVoicemailSettingsUtil.resetVisualVoicemailRetryInterval(this,
+ phoneAccount);
+ return;
}
- VisualVoicemailSettingsUtil.resetVisualVoicemailRetryInterval(this,
- phoneAccount);
- return;
- }
- boolean success = true;
- if (voicemail == null) {
- success = syncAll(action, imapHelper);
- } else {
- success = syncOne(imapHelper, voicemail);
- }
-
- // Need to check again for whether visual voicemail is enabled because it could have
- // been disabled while waiting for the response from the network.
- if (VisualVoicemailSettingsUtil.isVisualVoicemailEnabled(this, phoneAccount) &&
- !success) {
- retryCount--;
- Log.v(TAG, "Retrying " + action);
- } else {
- // Nothing more to do here, just exit.
- if (callback != null) {
- callback.releaseNetwork();
+ boolean success = true;
+ if (voicemail == null) {
+ success = syncAll(action, imapHelper);
+ } else {
+ success = syncOne(imapHelper, voicemail);
}
- VisualVoicemailSettingsUtil.resetVisualVoicemailRetryInterval(this,
- phoneAccount);
- return;
+
+ // Need to check again for whether visual voicemail is enabled because it could have
+ // been disabled while waiting for the response from the network.
+ if (VisualVoicemailSettingsUtil.isVisualVoicemailEnabled(this, phoneAccount) &&
+ !success) {
+ retryCount--;
+ Log.v(TAG, "Retrying " + action);
+ } else {
+ // Nothing more to do here, just exit.
+ VisualVoicemailSettingsUtil.resetVisualVoicemailRetryInterval(this,
+ phoneAccount);
+ return;
+ }
+ }
+ } finally {
+ if (callback != null) {
+ callback.releaseNetwork();
}
}
}
@@ -255,7 +244,7 @@
downloadSuccess = download(imapHelper);
}
- Log.v(TAG, "upload succeeded: ["+ String.valueOf(uploadSuccess)
+ Log.v(TAG, "upload succeeded: [" + String.valueOf(uploadSuccess)
+ "] download succeeded: [" + String.valueOf(downloadSuccess) + "]");
boolean success = uploadSuccess && downloadSuccess;
@@ -276,19 +265,26 @@
voicemail.getSourceData());
}
- private class SyncAllNetworkRequestCallback extends OmtpVvmNetworkRequestCallback {
- Voicemail mVoicemail;
+ private class SyncNetworkRequestCallback extends VvmNetworkRequestCallback {
- public SyncAllNetworkRequestCallback(Context context, PhoneAccountHandle phoneAccount,
+ Voicemail mVoicemail;
+ private String mAction;
+
+ public SyncNetworkRequestCallback(Context context, PhoneAccountHandle phoneAccount,
Voicemail voicemail, String action) {
- super(context, phoneAccount, action);
+ super(context, phoneAccount);
+ mAction = action;
mVoicemail = voicemail;
}
@Override
public void onAvailable(Network network) {
+ super.onAvailable(network);
+ NetworkInfo info = getConnectivityManager().getNetworkInfo(network);
+ Log.d(TAG, "Network Type: " + info.getTypeName());
doSync(network, this, mPhoneAccount, mVoicemail, mAction);
}
+
}
private boolean upload(ImapHelper imapHelper) {
@@ -368,7 +364,7 @@
long retryInterval = VisualVoicemailSettingsUtil.getVisualVoicemailRetryInterval(this,
phoneAccount);
- Log.v(TAG, "Retrying "+ action + " in " + retryInterval + "ms");
+ Log.v(TAG, "Retrying " + action + " in " + retryInterval + "ms");
AlarmManager alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC, System.currentTimeMillis() + retryInterval,
@@ -390,6 +386,7 @@
}
public class TranscriptionFetchedCallback {
+
private Context mContext;
private Voicemail mVoicemail;
diff --git a/src/com/android/phone/vvm/omtp/sync/VvmNetworkRequestCallback.java b/src/com/android/phone/vvm/omtp/sync/VvmNetworkRequestCallback.java
new file mode 100644
index 0000000..8bef9dc
--- /dev/null
+++ b/src/com/android/phone/vvm/omtp/sync/VvmNetworkRequestCallback.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.phone.vvm.omtp.sync;
+
+import android.annotation.CallSuper;
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
+import android.os.Handler;
+import android.os.Looper;
+import android.telecom.PhoneAccountHandle;
+import android.util.Log;
+
+import com.android.phone.PhoneUtils;
+import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
+
+/**
+ * Base class for network request call backs for visual voicemail syncing with the Imap server. This
+ * handles retries and network requests.
+ */
+public abstract class VvmNetworkRequestCallback extends ConnectivityManager.NetworkCallback {
+
+ private static final String TAG = "VvmNetworkRequest";
+
+ // Timeout used to call ConnectivityManager.requestNetwork
+ private static final int NETWORK_REQUEST_TIMEOUT_MILLIS = 60 * 1000;
+
+ public static final String NETWORK_REQUEST_FAILED_TIMEOUT = "timeout";
+ public static final String NETWORK_REQUEST_FAILED_LOST = "lost";
+
+ protected Context mContext;
+ protected PhoneAccountHandle mPhoneAccount;
+ protected NetworkRequest mNetworkRequest;
+ private ConnectivityManager mConnectivityManager;
+
+ private boolean mRequestSent = false;
+ private boolean mResultReceived = false;
+
+ public VvmNetworkRequestCallback(Context context, PhoneAccountHandle phoneAccount) {
+ mContext = context;
+ mPhoneAccount = phoneAccount;
+ mNetworkRequest = getNetworkRequest(context, phoneAccount);
+ }
+
+ /**
+ * @return NetworkRequest for a proper transport type. Use only cellular network if the carrier
+ * requires it. Otherwise use whatever available.
+ */
+ private NetworkRequest getNetworkRequest(Context context, PhoneAccountHandle phoneAccount) {
+ int subId = PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccount);
+ OmtpVvmCarrierConfigHelper carrierConfigHelper =
+ new OmtpVvmCarrierConfigHelper(context, subId);
+
+ NetworkRequest.Builder builder = new NetworkRequest.Builder()
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+
+ if (carrierConfigHelper.isCellularDataRequired()) {
+ Log.d(TAG, "Transport type: CELLULAR");
+ builder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
+ .setNetworkSpecifier(Integer.toString(subId));
+ } else {
+ Log.d(TAG, "Transport type: ANY");
+ }
+ return builder.build();
+ }
+
+ public NetworkRequest getNetworkRequest() {
+ return mNetworkRequest;
+ }
+
+ @Override
+ @CallSuper
+ public void onLost(Network network) {
+ Log.d(TAG, "onLost");
+ mResultReceived = true;
+ onFailed(NETWORK_REQUEST_FAILED_LOST);
+ }
+
+ @Override
+ @CallSuper
+ public void onAvailable(Network network) {
+ super.onAvailable(network);
+ mResultReceived = true;
+ }
+
+ @Override
+ @CallSuper
+ public void onUnavailable() {
+ mResultReceived = true;
+ onFailed(NETWORK_REQUEST_FAILED_TIMEOUT);
+ }
+
+ public void requestNetwork() {
+ if (mRequestSent == true) {
+ Log.e(TAG, "requestNetwork() called twice");
+ return;
+ }
+ mRequestSent = true;
+ getConnectivityManager().requestNetwork(getNetworkRequest(), this);
+ /**
+ * Somehow requestNetwork() with timeout doesn't work, and it's a hidden method.
+ * Implement our own timeout mechanism instead.
+ */
+ Handler handler = new Handler(Looper.getMainLooper());
+ handler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ if (mResultReceived == false) {
+ onFailed(NETWORK_REQUEST_FAILED_TIMEOUT);
+ }
+ }
+ }, NETWORK_REQUEST_TIMEOUT_MILLIS);
+ }
+
+ public void releaseNetwork() {
+ Log.d(TAG, "releaseNetwork");
+ getConnectivityManager().unregisterNetworkCallback(this);
+ }
+
+ public ConnectivityManager getConnectivityManager() {
+ if (mConnectivityManager == null) {
+ mConnectivityManager = (ConnectivityManager) mContext.getSystemService(
+ Context.CONNECTIVITY_SERVICE);
+ }
+ return mConnectivityManager;
+ }
+
+ @CallSuper
+ public void onFailed(String reason) {
+ Log.d(TAG, "onFailed: " + reason);
+ // TODO: Notify the user sync has failed?
+ releaseNetwork();
+ }
+}