From d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9 Mon Sep 17 00:00:00 2001 From: Eric Erfanian Date: Wed, 15 Mar 2017 14:41:07 -0700 Subject: Update Dialer source from latest green build. * Refactor voicemail component * Add new enriched calling components Test: treehugger, manual aosp testing Change-Id: I521a0f86327d4b42e14d93927c7d613044ed5942 --- .../voicemailomtp/sync/OmtpVvmSourceManager.java | 120 --------- .../voicemailomtp/sync/OmtpVvmSyncReceiver.java | 61 ----- .../voicemailomtp/sync/OmtpVvmSyncService.java | 278 --------------------- .../android/voicemailomtp/sync/SyncOneTask.java | 82 ------ java/com/android/voicemailomtp/sync/SyncTask.java | 79 ------ .../com/android/voicemailomtp/sync/UploadTask.java | 68 ----- .../sync/VoicemailProviderChangeReceiver.java | 41 --- .../sync/VoicemailStatusQueryHelper.java | 113 --------- .../voicemailomtp/sync/VoicemailsQueryHelper.java | 244 ------------------ .../voicemailomtp/sync/VvmNetworkRequest.java | 118 --------- .../sync/VvmNetworkRequestCallback.java | 171 ------------- 11 files changed, 1375 deletions(-) delete mode 100644 java/com/android/voicemailomtp/sync/OmtpVvmSourceManager.java delete mode 100644 java/com/android/voicemailomtp/sync/OmtpVvmSyncReceiver.java delete mode 100644 java/com/android/voicemailomtp/sync/OmtpVvmSyncService.java delete mode 100644 java/com/android/voicemailomtp/sync/SyncOneTask.java delete mode 100644 java/com/android/voicemailomtp/sync/SyncTask.java delete mode 100644 java/com/android/voicemailomtp/sync/UploadTask.java delete mode 100644 java/com/android/voicemailomtp/sync/VoicemailProviderChangeReceiver.java delete mode 100644 java/com/android/voicemailomtp/sync/VoicemailStatusQueryHelper.java delete mode 100644 java/com/android/voicemailomtp/sync/VoicemailsQueryHelper.java delete mode 100644 java/com/android/voicemailomtp/sync/VvmNetworkRequest.java delete mode 100644 java/com/android/voicemailomtp/sync/VvmNetworkRequestCallback.java (limited to 'java/com/android/voicemailomtp/sync') diff --git a/java/com/android/voicemailomtp/sync/OmtpVvmSourceManager.java b/java/com/android/voicemailomtp/sync/OmtpVvmSourceManager.java deleted file mode 100644 index ad3c025cf..000000000 --- a/java/com/android/voicemailomtp/sync/OmtpVvmSourceManager.java +++ /dev/null @@ -1,120 +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.voicemailomtp.sync; - -import android.content.Context; -import android.telecom.PhoneAccountHandle; -import android.telephony.PhoneStateListener; -import android.telephony.TelephonyManager; - -import com.android.voicemailomtp.VoicemailStatus; -import com.android.voicemailomtp.VvmPhoneStateListener; - -import java.util.Collections; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -/** - * A singleton class designed to remember the active OMTP visual voicemail sources. Because a - * voicemail source is tied 1:1 to a phone account, the phone account handle is used as the key - * for each voicemail source and the associated data. - */ -public class OmtpVvmSourceManager { - public static final String TAG = "OmtpVvmSourceManager"; - - private static OmtpVvmSourceManager sInstance = new OmtpVvmSourceManager(); - - private Context mContext; - private TelephonyManager mTelephonyManager; - // Each phone account is associated with a phone state listener for updates to whether the - // device is able to sync. - private Set mActiveVvmSources; - private Map mPhoneStateListenerMap; - - /** - * Private constructor. Instance should only be acquired through getInstance(). - */ - private OmtpVvmSourceManager() {} - - public static OmtpVvmSourceManager getInstance(Context context) { - sInstance.setup(context); - return sInstance; - } - - /** - * Set the context and system services so they do not need to be retrieved every time. - * @param context The context to get the subscription and telephony manager for. - */ - private void setup(Context context) { - if (mContext == null) { - mContext = context; - mTelephonyManager = (TelephonyManager) - mContext.getSystemService(Context.TELEPHONY_SERVICE); - mActiveVvmSources = Collections.newSetFromMap( - new ConcurrentHashMap(8, 0.9f, 1)); - mPhoneStateListenerMap = - new ConcurrentHashMap(8, 0.9f, 1); - } - } - - public void addSource(PhoneAccountHandle phoneAccount) { - mActiveVvmSources.add(phoneAccount); - } - - public void removeSource(PhoneAccountHandle phoneAccount) { - // TODO: should use OmtpVvmCarrierConfigHelper to handle the event. But currently it - // couldn't handle events on removed SIMs - VoicemailStatus.disable(mContext, phoneAccount); - removePhoneStateListener(phoneAccount); - mActiveVvmSources.remove(phoneAccount); - } - - public void addPhoneStateListener(PhoneAccountHandle phoneAccount) { - if (!mPhoneStateListenerMap.containsKey(phoneAccount)) { - VvmPhoneStateListener phoneStateListener = new VvmPhoneStateListener(mContext, - phoneAccount); - mPhoneStateListenerMap.put(phoneAccount, phoneStateListener); - mTelephonyManager.createForPhoneAccountHandle(phoneAccount) - .listen(phoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE); - } - } - - public void removePhoneStateListener(PhoneAccountHandle phoneAccount) { - PhoneStateListener phoneStateListener = - mPhoneStateListenerMap.remove(phoneAccount); - mTelephonyManager.createForPhoneAccountHandle(phoneAccount).listen(phoneStateListener, 0); - } - - public Set getOmtpVvmSources() { - return mActiveVvmSources; - } - - /** - * Check if a certain account is registered. - * - * @param phoneAccount The account to look for. - * @return {@code true} if the account is in the list of registered OMTP voicemail sources. - * {@code false} otherwise. - */ - public boolean isVvmSourceRegistered(PhoneAccountHandle phoneAccount) { - if (phoneAccount == null) { - return false; - } - - return mActiveVvmSources.contains(phoneAccount); - } -} \ No newline at end of file diff --git a/java/com/android/voicemailomtp/sync/OmtpVvmSyncReceiver.java b/java/com/android/voicemailomtp/sync/OmtpVvmSyncReceiver.java deleted file mode 100644 index 971a1c5a8..000000000 --- a/java/com/android/voicemailomtp/sync/OmtpVvmSyncReceiver.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2016 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.voicemailomtp.sync; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.provider.VoicemailContract; -import android.telecom.PhoneAccountHandle; -import android.telecom.TelecomManager; - -import com.android.voicemailomtp.ActivationTask; -import com.android.voicemailomtp.VvmLog; -import com.android.voicemailomtp.settings.VisualVoicemailSettingsUtil; - -import java.util.List; - -public class OmtpVvmSyncReceiver extends BroadcastReceiver { - - private static final String TAG = "OmtpVvmSyncReceiver"; - - @Override - public void onReceive(final Context context, Intent intent) { - if (VoicemailContract.ACTION_SYNC_VOICEMAIL.equals(intent.getAction())) { - VvmLog.v(TAG, "Sync intent received"); - for (PhoneAccountHandle source : OmtpVvmSourceManager.getInstance(context) - .getOmtpVvmSources()) { - SyncTask.start(context, source, OmtpVvmSyncService.SYNC_FULL_SYNC); - } - activateUnactivatedAccounts(context); - } - } - - private static void activateUnactivatedAccounts(Context context) { - List accounts = - context.getSystemService(TelecomManager.class).getCallCapablePhoneAccounts(); - for (PhoneAccountHandle phoneAccount : accounts) { - if (!VisualVoicemailSettingsUtil.isEnabled(context, phoneAccount)) { - continue; - } - if (!OmtpVvmSourceManager.getInstance(context).isVvmSourceRegistered(phoneAccount)) { - VvmLog.i(TAG, "Unactivated account " + phoneAccount + " found, activating"); - ActivationTask.start(context, phoneAccount, null); - } - } - } -} diff --git a/java/com/android/voicemailomtp/sync/OmtpVvmSyncService.java b/java/com/android/voicemailomtp/sync/OmtpVvmSyncService.java deleted file mode 100644 index a3418cc28..000000000 --- a/java/com/android/voicemailomtp/sync/OmtpVvmSyncService.java +++ /dev/null @@ -1,278 +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.voicemailomtp.sync; - -import android.annotation.TargetApi; -import android.content.Context; -import android.net.Network; -import android.net.Uri; -import android.os.Build.VERSION_CODES; -import android.telecom.PhoneAccountHandle; -import android.text.TextUtils; -import com.android.voicemailomtp.ActivationTask; -import com.android.voicemailomtp.Assert; -import com.android.voicemailomtp.OmtpEvents; -import com.android.voicemailomtp.OmtpVvmCarrierConfigHelper; -import com.android.voicemailomtp.Voicemail; -import com.android.voicemailomtp.VoicemailStatus; -import com.android.voicemailomtp.VvmLog; -import com.android.voicemailomtp.fetch.VoicemailFetchedCallback; -import com.android.voicemailomtp.imap.ImapHelper; -import com.android.voicemailomtp.imap.ImapHelper.InitializingException; -import com.android.voicemailomtp.scheduling.BaseTask; -import com.android.voicemailomtp.settings.VisualVoicemailSettingsUtil; -import com.android.voicemailomtp.sync.VvmNetworkRequest.NetworkWrapper; -import com.android.voicemailomtp.sync.VvmNetworkRequest.RequestFailedException; -import com.android.voicemailomtp.utils.VoicemailDatabaseUtil; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** Sync OMTP visual voicemail. */ -@TargetApi(VERSION_CODES.CUR_DEVELOPMENT) -public class OmtpVvmSyncService { - - private static final String TAG = OmtpVvmSyncService.class.getSimpleName(); - - /** - * Signifies a sync with both uploading to the server and downloading from the server. - */ - public static final String SYNC_FULL_SYNC = "full_sync"; - /** - * Only upload to the server. - */ - public static final String SYNC_UPLOAD_ONLY = "upload_only"; - /** - * Only download from the server. - */ - public static final String SYNC_DOWNLOAD_ONLY = "download_only"; - /** - * Only download single voicemail transcription. - */ - public static final String SYNC_DOWNLOAD_ONE_TRANSCRIPTION = - "download_one_transcription"; - - private final Context mContext; - - // Record the timestamp of the last full sync so that duplicate syncs can be reduced. - private static final String LAST_FULL_SYNC_TIMESTAMP = "last_full_sync_timestamp"; - // Constant indicating that there has never been a full sync. - public static final long NO_PRIOR_FULL_SYNC = -1; - - private VoicemailsQueryHelper mQueryHelper; - - public OmtpVvmSyncService(Context context) { - mContext = context; - mQueryHelper = new VoicemailsQueryHelper(mContext); - } - - public void sync(BaseTask task, String action, PhoneAccountHandle phoneAccount, - Voicemail voicemail, VoicemailStatus.Editor status) { - Assert.isTrue(phoneAccount != null); - VvmLog.v(TAG, "Sync requested: " + action + " - for account: " + phoneAccount); - setupAndSendRequest(task, phoneAccount, voicemail, action, status); - } - - private void setupAndSendRequest(BaseTask task, PhoneAccountHandle phoneAccount, - Voicemail voicemail, String action, VoicemailStatus.Editor status) { - if (!VisualVoicemailSettingsUtil.isEnabled(mContext, phoneAccount)) { - VvmLog.v(TAG, "Sync requested for disabled account"); - return; - } - if (!OmtpVvmSourceManager.getInstance(mContext).isVvmSourceRegistered(phoneAccount)) { - ActivationTask.start(mContext, phoneAccount, null); - return; - } - - OmtpVvmCarrierConfigHelper config = new OmtpVvmCarrierConfigHelper(mContext, phoneAccount); - // DATA_IMAP_OPERATION_STARTED posting should not be deferred. This event clears all data - // channel errors, which should happen when the task starts, not when it ends. It is the - // "Sync in progress..." status. - config.handleEvent(VoicemailStatus.edit(mContext, phoneAccount), - OmtpEvents.DATA_IMAP_OPERATION_STARTED); - try (NetworkWrapper network = VvmNetworkRequest.getNetwork(config, phoneAccount, status)) { - if (network == null) { - VvmLog.e(TAG, "unable to acquire network"); - task.fail(); - return; - } - doSync(task, network.get(), phoneAccount, voicemail, action, status); - } catch (RequestFailedException e) { - config.handleEvent(status, OmtpEvents.DATA_NO_CONNECTION_CELLULAR_REQUIRED); - task.fail(); - } - } - - private void doSync(BaseTask task, Network network, PhoneAccountHandle phoneAccount, - Voicemail voicemail, String action, VoicemailStatus.Editor status) { - try (ImapHelper imapHelper = new ImapHelper(mContext, phoneAccount, network, status)) { - boolean success; - if (voicemail == null) { - success = syncAll(action, imapHelper, phoneAccount); - } else { - success = syncOne(imapHelper, voicemail, phoneAccount); - } - if (success) { - // TODO: b/30569269 failure should interrupt all subsequent task via exceptions - imapHelper.updateQuota(); - imapHelper.handleEvent(OmtpEvents.DATA_IMAP_OPERATION_COMPLETED); - } else { - task.fail(); - } - } catch (InitializingException e) { - VvmLog.w(TAG, "Can't retrieve Imap credentials.", e); - return; - } - } - - private boolean syncAll(String action, ImapHelper imapHelper, PhoneAccountHandle account) { - boolean uploadSuccess = true; - boolean downloadSuccess = true; - - if (SYNC_FULL_SYNC.equals(action) || SYNC_UPLOAD_ONLY.equals(action)) { - uploadSuccess = upload(imapHelper); - } - if (SYNC_FULL_SYNC.equals(action) || SYNC_DOWNLOAD_ONLY.equals(action)) { - downloadSuccess = download(imapHelper, account); - } - - VvmLog.v(TAG, "upload succeeded: [" + String.valueOf(uploadSuccess) - + "] download succeeded: [" + String.valueOf(downloadSuccess) + "]"); - - return uploadSuccess && downloadSuccess; - } - - private boolean syncOne(ImapHelper imapHelper, Voicemail voicemail, - PhoneAccountHandle account) { - if (shouldPerformPrefetch(account, imapHelper)) { - VoicemailFetchedCallback callback = new VoicemailFetchedCallback(mContext, - voicemail.getUri(), account); - imapHelper.fetchVoicemailPayload(callback, voicemail.getSourceData()); - } - - return imapHelper.fetchTranscription( - new TranscriptionFetchedCallback(mContext, voicemail), - voicemail.getSourceData()); - } - - private boolean upload(ImapHelper imapHelper) { - List readVoicemails = mQueryHelper.getReadVoicemails(); - List deletedVoicemails = mQueryHelper.getDeletedVoicemails(); - - boolean success = true; - - if (deletedVoicemails.size() > 0) { - if (imapHelper.markMessagesAsDeleted(deletedVoicemails)) { - // We want to delete selectively instead of all the voicemails for this provider - // in case the state changed since the IMAP query was completed. - mQueryHelper.deleteFromDatabase(deletedVoicemails); - } else { - success = false; - } - } - - if (readVoicemails.size() > 0) { - if (imapHelper.markMessagesAsRead(readVoicemails)) { - mQueryHelper.markCleanInDatabase(readVoicemails); - } else { - success = false; - } - } - - return success; - } - - private boolean download(ImapHelper imapHelper, PhoneAccountHandle account) { - List serverVoicemails = imapHelper.fetchAllVoicemails(); - List localVoicemails = mQueryHelper.getAllVoicemails(); - - if (localVoicemails == null || serverVoicemails == null) { - // Null value means the query failed. - return false; - } - - Map remoteMap = buildMap(serverVoicemails); - - // Go through all the local voicemails and check if they are on the server. - // They may be read or deleted on the server but not locally. Perform the - // appropriate local operation if the status differs from the server. Remove - // the messages that exist both locally and on the server to know which server - // messages to insert locally. - for (int i = 0; i < localVoicemails.size(); i++) { - Voicemail localVoicemail = localVoicemails.get(i); - Voicemail remoteVoicemail = remoteMap.remove(localVoicemail.getSourceData()); - if (remoteVoicemail == null) { - mQueryHelper.deleteFromDatabase(localVoicemail); - } else { - if (remoteVoicemail.isRead() != localVoicemail.isRead()) { - mQueryHelper.markReadInDatabase(localVoicemail); - } - - if (!TextUtils.isEmpty(remoteVoicemail.getTranscription()) && - TextUtils.isEmpty(localVoicemail.getTranscription())) { - mQueryHelper.updateWithTranscription(localVoicemail, - remoteVoicemail.getTranscription()); - } - } - } - - // The leftover messages are messages that exist on the server but not locally. - boolean prefetchEnabled = shouldPerformPrefetch(account, imapHelper); - for (Voicemail remoteVoicemail : remoteMap.values()) { - Uri uri = VoicemailDatabaseUtil.insert(mContext, remoteVoicemail); - if (prefetchEnabled) { - VoicemailFetchedCallback fetchedCallback = - new VoicemailFetchedCallback(mContext, uri, account); - imapHelper.fetchVoicemailPayload(fetchedCallback, remoteVoicemail.getSourceData()); - } - } - - return true; - } - - private boolean shouldPerformPrefetch(PhoneAccountHandle account, ImapHelper imapHelper) { - OmtpVvmCarrierConfigHelper carrierConfigHelper = - new OmtpVvmCarrierConfigHelper(mContext, account); - return carrierConfigHelper.isPrefetchEnabled() && !imapHelper.isRoaming(); - } - - /** - * Builds a map from provider data to message for the given collection of voicemails. - */ - private Map buildMap(List messages) { - Map map = new HashMap(); - for (Voicemail message : messages) { - map.put(message.getSourceData(), message); - } - return map; - } - - public class TranscriptionFetchedCallback { - - private Context mContext; - private Voicemail mVoicemail; - - public TranscriptionFetchedCallback(Context context, Voicemail voicemail) { - mContext = context; - mVoicemail = voicemail; - } - - public void setVoicemailTranscription(String transcription) { - VoicemailsQueryHelper queryHelper = new VoicemailsQueryHelper(mContext); - queryHelper.updateWithTranscription(mVoicemail, transcription); - } - } -} diff --git a/java/com/android/voicemailomtp/sync/SyncOneTask.java b/java/com/android/voicemailomtp/sync/SyncOneTask.java deleted file mode 100644 index 9264e6c08..000000000 --- a/java/com/android/voicemailomtp/sync/SyncOneTask.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2016 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.voicemailomtp.sync; - -import android.content.Context; -import android.content.Intent; -import android.telecom.PhoneAccountHandle; - -import com.android.voicemailomtp.Voicemail; -import com.android.voicemailomtp.VoicemailStatus; -import com.android.voicemailomtp.scheduling.BaseTask; -import com.android.voicemailomtp.scheduling.RetryPolicy; - -/** - * Task to download a single voicemail from the server. This task is initiated by a SMS notifying - * the new voicemail arrival, and ignores the duplicated tasks constraint. - */ -public class SyncOneTask extends BaseTask { - - private static final int RETRY_TIMES = 2; - private static final int RETRY_INTERVAL_MILLIS = 5_000; - - private static final String EXTRA_PHONE_ACCOUNT_HANDLE = "extra_phone_account_handle"; - private static final String EXTRA_SYNC_TYPE = "extra_sync_type"; - private static final String EXTRA_VOICEMAIL = "extra_voicemail"; - - private PhoneAccountHandle mPhone; - private String mSyncType; - private Voicemail mVoicemail; - - public static void start(Context context, PhoneAccountHandle phone, Voicemail voicemail) { - Intent intent = BaseTask - .createIntent(context, SyncOneTask.class, phone); - intent.putExtra(EXTRA_PHONE_ACCOUNT_HANDLE, phone); - intent.putExtra(EXTRA_SYNC_TYPE, OmtpVvmSyncService.SYNC_DOWNLOAD_ONE_TRANSCRIPTION); - intent.putExtra(EXTRA_VOICEMAIL, voicemail); - context.startService(intent); - } - - public SyncOneTask() { - super(TASK_ALLOW_DUPLICATES); - addPolicy(new RetryPolicy(RETRY_TIMES, RETRY_INTERVAL_MILLIS)); - } - - public void onCreate(Context context, Intent intent, int flags, int startId) { - super.onCreate(context, intent, flags, startId); - mPhone = intent.getParcelableExtra(EXTRA_PHONE_ACCOUNT_HANDLE); - mSyncType = intent.getStringExtra(EXTRA_SYNC_TYPE); - mVoicemail = intent.getParcelableExtra(EXTRA_VOICEMAIL); - } - - @Override - public void onExecuteInBackgroundThread() { - OmtpVvmSyncService service = new OmtpVvmSyncService(getContext()); - service.sync(this, mSyncType, mPhone, mVoicemail, - VoicemailStatus.edit(getContext(), mPhone)); - } - - @Override - public Intent createRestartIntent() { - Intent intent = super.createRestartIntent(); - intent.putExtra(EXTRA_PHONE_ACCOUNT_HANDLE, mPhone); - intent.putExtra(EXTRA_SYNC_TYPE, mSyncType); - intent.putExtra(EXTRA_VOICEMAIL, mVoicemail); - return intent; - } - -} diff --git a/java/com/android/voicemailomtp/sync/SyncTask.java b/java/com/android/voicemailomtp/sync/SyncTask.java deleted file mode 100644 index 41b22f22c..000000000 --- a/java/com/android/voicemailomtp/sync/SyncTask.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2016 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.voicemailomtp.sync; - -import android.content.Context; -import android.content.Intent; -import android.telecom.PhoneAccountHandle; - -import com.android.voicemailomtp.scheduling.BaseTask; -import com.android.voicemailomtp.scheduling.MinimalIntervalPolicy; -import com.android.voicemailomtp.scheduling.RetryPolicy; - -/** - * System initiated sync request. - */ -public class SyncTask extends BaseTask { - - // Try sync for a total of 5 times, should take around 5 minutes before finally giving up. - private static final int RETRY_TIMES = 4; - private static final int RETRY_INTERVAL_MILLIS = 5_000; - private static final int MINIMAL_INTERVAL_MILLIS = 60_000; - - private static final String EXTRA_PHONE_ACCOUNT_HANDLE = "extra_phone_account_handle"; - private static final String EXTRA_SYNC_TYPE = "extra_sync_type"; - - private final RetryPolicy mRetryPolicy; - - private PhoneAccountHandle mPhone; - private String mSyncType; - - public static void start(Context context, PhoneAccountHandle phone, String syncType) { - Intent intent = BaseTask - .createIntent(context, SyncTask.class, phone); - intent.putExtra(EXTRA_PHONE_ACCOUNT_HANDLE, phone); - intent.putExtra(EXTRA_SYNC_TYPE, syncType); - context.startService(intent); - } - - public SyncTask() { - super(TASK_SYNC); - mRetryPolicy = new RetryPolicy(RETRY_TIMES, RETRY_INTERVAL_MILLIS); - addPolicy(mRetryPolicy); - addPolicy(new MinimalIntervalPolicy(MINIMAL_INTERVAL_MILLIS)); - } - - public void onCreate(Context context, Intent intent, int flags, int startId) { - super.onCreate(context, intent, flags, startId); - mPhone = intent.getParcelableExtra(EXTRA_PHONE_ACCOUNT_HANDLE); - mSyncType = intent.getStringExtra(EXTRA_SYNC_TYPE); - } - - @Override - public void onExecuteInBackgroundThread() { - OmtpVvmSyncService service = new OmtpVvmSyncService(getContext()); - service.sync(this, mSyncType, mPhone, null, mRetryPolicy.getVoicemailStatusEditor()); - } - - @Override - public Intent createRestartIntent() { - Intent intent = super.createRestartIntent(); - intent.putExtra(EXTRA_PHONE_ACCOUNT_HANDLE, mPhone); - intent.putExtra(EXTRA_SYNC_TYPE, mSyncType); - return intent; - } -} diff --git a/java/com/android/voicemailomtp/sync/UploadTask.java b/java/com/android/voicemailomtp/sync/UploadTask.java deleted file mode 100644 index 30a16812b..000000000 --- a/java/com/android/voicemailomtp/sync/UploadTask.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2016 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.voicemailomtp.sync; - -import android.content.Context; -import android.content.Intent; -import android.telecom.PhoneAccountHandle; - -import com.android.voicemailomtp.VoicemailStatus; -import com.android.voicemailomtp.VvmLog; -import com.android.voicemailomtp.scheduling.BaseTask; -import com.android.voicemailomtp.scheduling.PostponePolicy; - -/** - * Upload task triggered by database changes. Will wait until the database has been stable for - * {@link #POSTPONE_MILLIS} to execute. - */ -public class UploadTask extends BaseTask { - - private static final String TAG = "VvmUploadTask"; - - private static final int POSTPONE_MILLIS = 5_000; - - public UploadTask() { - super(TASK_UPLOAD); - addPolicy(new PostponePolicy(POSTPONE_MILLIS)); - } - - public static void start(Context context, PhoneAccountHandle phoneAccountHandle) { - Intent intent = BaseTask - .createIntent(context, UploadTask.class, phoneAccountHandle); - context.startService(intent); - } - - @Override - public void onCreate(Context context, Intent intent, int flags, int startId) { - super.onCreate(context, intent, flags, startId); - } - - @Override - public void onExecuteInBackgroundThread() { - OmtpVvmSyncService service = new OmtpVvmSyncService(getContext()); - - PhoneAccountHandle phoneAccountHandle = getPhoneAccountHandle(); - if (phoneAccountHandle == null) { - // This should never happen - VvmLog.e(TAG, "null phone account for phoneAccountHandle " + getPhoneAccountHandle()); - return; - } - service.sync(this, OmtpVvmSyncService.SYNC_UPLOAD_ONLY, - phoneAccountHandle, null, - VoicemailStatus.edit(getContext(), phoneAccountHandle)); - } -} diff --git a/java/com/android/voicemailomtp/sync/VoicemailProviderChangeReceiver.java b/java/com/android/voicemailomtp/sync/VoicemailProviderChangeReceiver.java deleted file mode 100644 index ade9ef12d..000000000 --- a/java/com/android/voicemailomtp/sync/VoicemailProviderChangeReceiver.java +++ /dev/null @@ -1,41 +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.voicemailomtp.sync; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.provider.VoicemailContract; -import android.telecom.PhoneAccountHandle; - -/** - * Receives changes to the voicemail provider so they can be sent to the voicemail server. - */ -public class VoicemailProviderChangeReceiver extends BroadcastReceiver { - - @Override - public void onReceive(Context context, Intent intent) { - boolean isSelfChanged = intent.getBooleanExtra(VoicemailContract.EXTRA_SELF_CHANGE, false); - OmtpVvmSourceManager vvmSourceManager = - OmtpVvmSourceManager.getInstance(context); - if (vvmSourceManager.getOmtpVvmSources().size() > 0 && !isSelfChanged) { - for (PhoneAccountHandle source : OmtpVvmSourceManager.getInstance(context) - .getOmtpVvmSources()) { - UploadTask.start(context, source); - } - } - } -} diff --git a/java/com/android/voicemailomtp/sync/VoicemailStatusQueryHelper.java b/java/com/android/voicemailomtp/sync/VoicemailStatusQueryHelper.java deleted file mode 100644 index 89ba0b494..000000000 --- a/java/com/android/voicemailomtp/sync/VoicemailStatusQueryHelper.java +++ /dev/null @@ -1,113 +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.voicemailomtp.sync; - -import android.content.ContentResolver; -import android.content.Context; -import android.database.Cursor; -import android.net.Uri; -import android.provider.VoicemailContract; -import android.provider.VoicemailContract.Status; -import android.telecom.PhoneAccountHandle; - -/** - * Construct queries to interact with the voicemail status table. - */ -public class VoicemailStatusQueryHelper { - - final static String[] PROJECTION = new String[] { - Status._ID, // 0 - Status.CONFIGURATION_STATE, // 1 - Status.NOTIFICATION_CHANNEL_STATE, // 2 - Status.SOURCE_PACKAGE // 3 - }; - - public static final int _ID = 0; - public static final int CONFIGURATION_STATE = 1; - public static final int NOTIFICATION_CHANNEL_STATE = 2; - public static final int SOURCE_PACKAGE = 3; - - private Context mContext; - private ContentResolver mContentResolver; - private Uri mSourceUri; - - public VoicemailStatusQueryHelper(Context context) { - mContext = context; - mContentResolver = context.getContentResolver(); - mSourceUri = VoicemailContract.Status.buildSourceUri(mContext.getPackageName()); - } - - /** - * Check if the configuration state for the voicemail source is "ok", meaning that the - * source is set up. - * - * @param phoneAccount The phone account for the voicemail source to check. - * @return {@code true} if the voicemail source is configured, {@code} false otherwise, - * including if the voicemail source is not registered in the table. - */ - public boolean isVoicemailSourceConfigured(PhoneAccountHandle phoneAccount) { - return isFieldEqualTo(phoneAccount, CONFIGURATION_STATE, Status.CONFIGURATION_STATE_OK); - } - - /** - * Check if the notifications channel of a voicemail source is active. That is, when a new - * voicemail is available, if the server able to notify the device. - * - * @return {@code true} if notifications channel is active, {@code false} otherwise. - */ - public boolean isNotificationsChannelActive(PhoneAccountHandle phoneAccount) { - return isFieldEqualTo(phoneAccount, NOTIFICATION_CHANNEL_STATE, - Status.NOTIFICATION_CHANNEL_STATE_OK); - } - - /** - * Check if a field for an entry in the status table is equal to a specific value. - * - * @param phoneAccount The phone account of the voicemail source to query for. - * @param columnIndex The column index of the field in the returned query. - * @param value The value to compare against. - * @return {@code true} if the stored value is equal to the provided value. {@code false} - * otherwise. - */ - private boolean isFieldEqualTo(PhoneAccountHandle phoneAccount, int columnIndex, int value) { - Cursor cursor = null; - if (phoneAccount != null) { - String phoneAccountComponentName = phoneAccount.getComponentName().flattenToString(); - String phoneAccountId = phoneAccount.getId(); - if (phoneAccountComponentName == null || phoneAccountId == null) { - return false; - } - try { - String whereClause = - Status.PHONE_ACCOUNT_COMPONENT_NAME + "=? AND " + - Status.PHONE_ACCOUNT_ID + "=? AND " + Status.SOURCE_PACKAGE + "=?"; - String[] whereArgs = { phoneAccountComponentName, phoneAccountId, - mContext.getPackageName()}; - cursor = mContentResolver.query( - mSourceUri, PROJECTION, whereClause, whereArgs, null); - if (cursor != null && cursor.moveToFirst()) { - return cursor.getInt(columnIndex) == value; - } - } - finally { - if (cursor != null) { - cursor.close(); - } - } - } - return false; - } -} diff --git a/java/com/android/voicemailomtp/sync/VoicemailsQueryHelper.java b/java/com/android/voicemailomtp/sync/VoicemailsQueryHelper.java deleted file mode 100644 index 1450e3d1b..000000000 --- a/java/com/android/voicemailomtp/sync/VoicemailsQueryHelper.java +++ /dev/null @@ -1,244 +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.voicemailomtp.sync; - -import android.content.ContentResolver; -import android.content.ContentUris; -import android.content.ContentValues; -import android.content.Context; -import android.database.Cursor; -import android.net.Uri; -import android.provider.VoicemailContract; -import android.provider.VoicemailContract.Voicemails; -import android.telecom.PhoneAccountHandle; -import com.android.voicemailomtp.Voicemail; -import java.util.ArrayList; -import java.util.List; - -/** - * Construct queries to interact with the voicemails table. - */ -public class VoicemailsQueryHelper { - final static String[] PROJECTION = new String[] { - Voicemails._ID, // 0 - Voicemails.SOURCE_DATA, // 1 - Voicemails.IS_READ, // 2 - Voicemails.DELETED, // 3 - Voicemails.TRANSCRIPTION // 4 - }; - - public static final int _ID = 0; - public static final int SOURCE_DATA = 1; - public static final int IS_READ = 2; - public static final int DELETED = 3; - public static final int TRANSCRIPTION = 4; - - final static String READ_SELECTION = Voicemails.DIRTY + "=1 AND " - + Voicemails.DELETED + "!=1 AND " + Voicemails.IS_READ + "=1"; - final static String DELETED_SELECTION = Voicemails.DELETED + "=1"; - - private Context mContext; - private ContentResolver mContentResolver; - private Uri mSourceUri; - - public VoicemailsQueryHelper(Context context) { - mContext = context; - mContentResolver = context.getContentResolver(); - mSourceUri = VoicemailContract.Voicemails.buildSourceUri(mContext.getPackageName()); - } - - /** - * Get all the local read voicemails that have not been synced to the server. - * - * @return A list of read voicemails. - */ - public List getReadVoicemails() { - return getLocalVoicemails(READ_SELECTION); - } - - /** - * Get all the locally deleted voicemails that have not been synced to the server. - * - * @return A list of deleted voicemails. - */ - public List getDeletedVoicemails() { - return getLocalVoicemails(DELETED_SELECTION); - } - - /** - * Get all voicemails locally stored. - * - * @return A list of all locally stored voicemails. - */ - public List getAllVoicemails() { - return getLocalVoicemails(null); - } - - /** - * Utility method to make queries to the voicemail database. - * - * @param selection A filter declaring which rows to return. {@code null} returns all rows. - * @return A list of voicemails according to the selection statement. - */ - private List getLocalVoicemails(String selection) { - Cursor cursor = mContentResolver.query(mSourceUri, PROJECTION, selection, null, null); - if (cursor == null) { - return null; - } - try { - List voicemails = new ArrayList(); - while (cursor.moveToNext()) { - final long id = cursor.getLong(_ID); - final String sourceData = cursor.getString(SOURCE_DATA); - final boolean isRead = cursor.getInt(IS_READ) == 1; - final String transcription = cursor.getString(TRANSCRIPTION); - Voicemail voicemail = Voicemail - .createForUpdate(id, sourceData) - .setIsRead(isRead) - .setTranscription(transcription).build(); - voicemails.add(voicemail); - } - return voicemails; - } finally { - cursor.close(); - } - } - - /** - * Deletes a list of voicemails from the voicemail content provider. - * - * @param voicemails The list of voicemails to delete - * @return The number of voicemails deleted - */ - public int deleteFromDatabase(List voicemails) { - int count = voicemails.size(); - if (count == 0) { - return 0; - } - - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < count; i++) { - if (i > 0) { - sb.append(","); - } - sb.append(voicemails.get(i).getId()); - } - - String selectionStatement = String.format(Voicemails._ID + " IN (%s)", sb.toString()); - return mContentResolver.delete(Voicemails.CONTENT_URI, selectionStatement, null); - } - - /** - * Utility method to delete a single voicemail. - */ - public void deleteFromDatabase(Voicemail voicemail) { - mContentResolver.delete(Voicemails.CONTENT_URI, Voicemails._ID + "=?", - new String[] { Long.toString(voicemail.getId()) }); - } - - public int markReadInDatabase(List voicemails) { - int count = voicemails.size(); - for (int i = 0; i < count; i++) { - markReadInDatabase(voicemails.get(i)); - } - return count; - } - - /** - * Utility method to mark single message as read. - */ - public void markReadInDatabase(Voicemail voicemail) { - Uri uri = ContentUris.withAppendedId(mSourceUri, voicemail.getId()); - ContentValues contentValues = new ContentValues(); - contentValues.put(Voicemails.IS_READ, "1"); - mContentResolver.update(uri, contentValues, null, null); - } - - /** - * Sends an update command to the voicemail content provider for a list of voicemails. From the - * view of the provider, since the updater is the owner of the entry, a blank "update" means - * that the voicemail source is indicating that the server has up-to-date information on the - * voicemail. This flips the "dirty" bit to "0". - * - * @param voicemails The list of voicemails to update - * @return The number of voicemails updated - */ - public int markCleanInDatabase(List voicemails) { - int count = voicemails.size(); - for (int i = 0; i < count; i++) { - markCleanInDatabase(voicemails.get(i)); - } - return count; - } - - /** - * Utility method to mark single message as clean. - */ - public void markCleanInDatabase(Voicemail voicemail) { - Uri uri = ContentUris.withAppendedId(mSourceUri, voicemail.getId()); - ContentValues contentValues = new ContentValues(); - mContentResolver.update(uri, contentValues, null, null); - } - - /** - * Utility method to add a transcription to the voicemail. - */ - public void updateWithTranscription(Voicemail voicemail, String transcription) { - Uri uri = ContentUris.withAppendedId(mSourceUri, voicemail.getId()); - ContentValues contentValues = new ContentValues(); - contentValues.put(Voicemails.TRANSCRIPTION, transcription); - mContentResolver.update(uri, contentValues, null, null); - } - - /** - * Voicemail is unique if the tuple of (phone account component name, phone account id, source - * data) is unique. If the phone account is missing, we also consider this unique since it's - * simply an "unknown" account. - * @param voicemail The voicemail to check if it is unique. - * @return {@code true} if the voicemail is unique, {@code false} otherwise. - */ - public boolean isVoicemailUnique(Voicemail voicemail) { - Cursor cursor = null; - PhoneAccountHandle phoneAccount = voicemail.getPhoneAccount(); - if (phoneAccount != null) { - String phoneAccountComponentName = phoneAccount.getComponentName().flattenToString(); - String phoneAccountId = phoneAccount.getId(); - String sourceData = voicemail.getSourceData(); - if (phoneAccountComponentName == null || phoneAccountId == null || sourceData == null) { - return true; - } - try { - String whereClause = - Voicemails.PHONE_ACCOUNT_COMPONENT_NAME + "=? AND " + - Voicemails.PHONE_ACCOUNT_ID + "=? AND " + Voicemails.SOURCE_DATA + "=?"; - String[] whereArgs = { phoneAccountComponentName, phoneAccountId, sourceData }; - cursor = mContentResolver.query( - mSourceUri, PROJECTION, whereClause, whereArgs, null); - if (cursor.getCount() == 0) { - return true; - } else { - return false; - } - } - finally { - if (cursor != null) { - cursor.close(); - } - } - } - return true; - } -} diff --git a/java/com/android/voicemailomtp/sync/VvmNetworkRequest.java b/java/com/android/voicemailomtp/sync/VvmNetworkRequest.java deleted file mode 100644 index 966b940c2..000000000 --- a/java/com/android/voicemailomtp/sync/VvmNetworkRequest.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (C) 2016 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.voicemailomtp.sync; - -import android.annotation.TargetApi; -import android.net.Network; -import android.os.Build.VERSION_CODES; -import android.support.annotation.NonNull; -import android.telecom.PhoneAccountHandle; -import com.android.voicemailomtp.OmtpVvmCarrierConfigHelper; -import com.android.voicemailomtp.VoicemailStatus; -import com.android.voicemailomtp.VvmLog; -import java.io.Closeable; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; - -/** - * Class to retrieve a {@link Network} synchronously. {@link #getNetwork(OmtpVvmCarrierConfigHelper, - * PhoneAccountHandle)} will block until a suitable network is retrieved or it has failed. - */ -@SuppressWarnings("AndroidApiChecker") /* CompletableFuture is java8*/ -@TargetApi(VERSION_CODES.CUR_DEVELOPMENT) -public class VvmNetworkRequest { - - private static final String TAG = "VvmNetworkRequest"; - - /** - * A wrapper around a Network returned by a {@link VvmNetworkRequestCallback}, which should be - * closed once not needed anymore. - */ - public static class NetworkWrapper implements Closeable { - - private final Network mNetwork; - private final VvmNetworkRequestCallback mCallback; - - private NetworkWrapper(Network network, VvmNetworkRequestCallback callback) { - mNetwork = network; - mCallback = callback; - } - - public Network get() { - return mNetwork; - } - - @Override - public void close() { - mCallback.releaseNetwork(); - } - } - - public static class RequestFailedException extends Exception { - - private RequestFailedException(Throwable cause) { - super(cause); - } - } - - @NonNull - public static NetworkWrapper getNetwork(OmtpVvmCarrierConfigHelper config, - PhoneAccountHandle handle, VoicemailStatus.Editor status) throws RequestFailedException { - FutureNetworkRequestCallback callback = new FutureNetworkRequestCallback(config, handle, - status); - callback.requestNetwork(); - try { - return callback.getFuture().get(); - } catch (InterruptedException | ExecutionException e) { - callback.releaseNetwork(); - VvmLog.e(TAG, "can't get future network", e); - throw new RequestFailedException(e); - } - } - - private static class FutureNetworkRequestCallback extends VvmNetworkRequestCallback { - - /** - * {@link CompletableFuture#get()} will block until {@link CompletableFuture# - * complete(Object) } has been called on the other thread. - */ - private final CompletableFuture mFuture = new CompletableFuture<>(); - - public FutureNetworkRequestCallback(OmtpVvmCarrierConfigHelper config, - PhoneAccountHandle phoneAccount, VoicemailStatus.Editor status) { - super(config, phoneAccount, status); - } - - public Future getFuture() { - return mFuture; - } - - @Override - public void onAvailable(Network network) { - super.onAvailable(network); - mFuture.complete(new NetworkWrapper(network, this)); - } - - @Override - public void onFailed(String reason) { - super.onFailed(reason); - mFuture.complete(null); - } - - } -} diff --git a/java/com/android/voicemailomtp/sync/VvmNetworkRequestCallback.java b/java/com/android/voicemailomtp/sync/VvmNetworkRequestCallback.java deleted file mode 100644 index 8481a9d16..000000000 --- a/java/com/android/voicemailomtp/sync/VvmNetworkRequestCallback.java +++ /dev/null @@ -1,171 +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.voicemailomtp.sync; - -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.support.annotation.CallSuper; -import android.telecom.PhoneAccountHandle; - -import com.android.voicemailomtp.OmtpEvents; -import com.android.voicemailomtp.OmtpVvmCarrierConfigHelper; -import com.android.voicemailomtp.TelephonyManagerStub; -import com.android.voicemailomtp.VoicemailStatus; -import com.android.voicemailomtp.VvmLog; - -/** - * 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 final OmtpVvmCarrierConfigHelper mCarrierConfigHelper; - private final VoicemailStatus.Editor mStatus; - private boolean mRequestSent = false; - private boolean mResultReceived = false; - - public VvmNetworkRequestCallback(Context context, PhoneAccountHandle phoneAccount, - VoicemailStatus.Editor status) { - mContext = context; - mPhoneAccount = phoneAccount; - mStatus = status; - mCarrierConfigHelper = new OmtpVvmCarrierConfigHelper(context, mPhoneAccount); - mNetworkRequest = createNetworkRequest(); - } - - public VvmNetworkRequestCallback(OmtpVvmCarrierConfigHelper config, - PhoneAccountHandle phoneAccount, VoicemailStatus.Editor status) { - mContext = config.getContext(); - mPhoneAccount = phoneAccount; - mStatus = status; - mCarrierConfigHelper = config; - mNetworkRequest = createNetworkRequest(); - } - - public VoicemailStatus.Editor getVoicemailStatusEditor() { - return mStatus; - } - - /** - * @return NetworkRequest for a proper transport type. Use only cellular network if the carrier - * requires it. Otherwise use whatever available. - */ - private NetworkRequest createNetworkRequest() { - - NetworkRequest.Builder builder = new NetworkRequest.Builder() - .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); - - if (mCarrierConfigHelper.isCellularDataRequired()) { - VvmLog.d(TAG, "Transport type: CELLULAR"); - builder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) - .setNetworkSpecifier(TelephonyManagerStub - .getNetworkSpecifierForPhoneAccountHandle(mContext, mPhoneAccount)); - } else { - VvmLog.d(TAG, "Transport type: ANY"); - } - return builder.build(); - } - - public NetworkRequest getNetworkRequest() { - return mNetworkRequest; - } - - @Override - @CallSuper - public void onLost(Network network) { - VvmLog.d(TAG, "onLost"); - mResultReceived = true; - onFailed(NETWORK_REQUEST_FAILED_LOST); - } - - @Override - @CallSuper - public void onAvailable(Network network) { - super.onAvailable(network); - mResultReceived = true; - } - - @CallSuper - public void onUnavailable() { - // TODO: b/32637799 this is hidden, do we really need this? - mResultReceived = true; - onFailed(NETWORK_REQUEST_FAILED_TIMEOUT); - } - - public void requestNetwork() { - if (mRequestSent == true) { - VvmLog.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() { - VvmLog.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) { - VvmLog.d(TAG, "onFailed: " + reason); - if (mCarrierConfigHelper.isCellularDataRequired()) { - mCarrierConfigHelper - .handleEvent(mStatus, OmtpEvents.DATA_NO_CONNECTION_CELLULAR_REQUIRED); - } else { - mCarrierConfigHelper.handleEvent(mStatus, OmtpEvents.DATA_NO_CONNECTION); - } - releaseNetwork(); - } -} -- cgit v1.2.3