• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License
15  */
16 package com.android.phone.vvm.omtp.sync;
17 
18 import android.annotation.CallSuper;
19 import android.content.Context;
20 import android.net.ConnectivityManager;
21 import android.net.Network;
22 import android.net.NetworkCapabilities;
23 import android.net.NetworkRequest;
24 import android.os.Handler;
25 import android.os.Looper;
26 import android.telecom.PhoneAccountHandle;
27 import com.android.phone.PhoneUtils;
28 import com.android.phone.VoicemailStatus;
29 import com.android.phone.vvm.omtp.OmtpEvents;
30 import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
31 import com.android.phone.vvm.omtp.VvmLog;
32 
33 /**
34  * Base class for network request call backs for visual voicemail syncing with the Imap server. This
35  * handles retries and network requests.
36  */
37 public abstract class VvmNetworkRequestCallback extends ConnectivityManager.NetworkCallback {
38 
39     private static final String TAG = "VvmNetworkRequest";
40 
41     // Timeout used to call ConnectivityManager.requestNetwork
42     private static final int NETWORK_REQUEST_TIMEOUT_MILLIS = 60 * 1000;
43 
44     public static final String NETWORK_REQUEST_FAILED_TIMEOUT = "timeout";
45     public static final String NETWORK_REQUEST_FAILED_LOST = "lost";
46 
47     protected Context mContext;
48     protected PhoneAccountHandle mPhoneAccount;
49     protected NetworkRequest mNetworkRequest;
50     private ConnectivityManager mConnectivityManager;
51     private final OmtpVvmCarrierConfigHelper mCarrierConfigHelper;
52     private final int mSubId;
53     private final VoicemailStatus.Editor mStatus;
54     private boolean mRequestSent = false;
55     private boolean mResultReceived = false;
56 
VvmNetworkRequestCallback(Context context, PhoneAccountHandle phoneAccount, VoicemailStatus.Editor status)57     public VvmNetworkRequestCallback(Context context, PhoneAccountHandle phoneAccount,
58         VoicemailStatus.Editor status) {
59         mContext = context;
60         mPhoneAccount = phoneAccount;
61         mSubId = PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccount);
62         mStatus = status;
63         mCarrierConfigHelper = new OmtpVvmCarrierConfigHelper(context, mSubId);
64         mNetworkRequest = createNetworkRequest();
65     }
66 
VvmNetworkRequestCallback(OmtpVvmCarrierConfigHelper config, PhoneAccountHandle phoneAccount, VoicemailStatus.Editor status)67     public VvmNetworkRequestCallback(OmtpVvmCarrierConfigHelper config,
68         PhoneAccountHandle phoneAccount, VoicemailStatus.Editor status) {
69         mContext = config.getContext();
70         mPhoneAccount = phoneAccount;
71         mSubId = config.getSubId();
72         mStatus = status;
73         mCarrierConfigHelper = config;
74         mNetworkRequest = createNetworkRequest();
75     }
76 
getVoicemailStatusEditor()77     public VoicemailStatus.Editor getVoicemailStatusEditor() {
78         return mStatus;
79     }
80 
81     /**
82      * @return NetworkRequest for a proper transport type. Use only cellular network if the carrier
83      * requires it. Otherwise use whatever available.
84      */
createNetworkRequest()85     private NetworkRequest createNetworkRequest() {
86 
87         NetworkRequest.Builder builder = new NetworkRequest.Builder()
88                 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
89 
90         if (mCarrierConfigHelper.isCellularDataRequired()) {
91             VvmLog.d(TAG, "Transport type: CELLULAR");
92             builder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
93                     .setNetworkSpecifier(Integer.toString(mSubId));
94         } else {
95             VvmLog.d(TAG, "Transport type: ANY");
96         }
97         return builder.build();
98     }
99 
getNetworkRequest()100     public NetworkRequest getNetworkRequest() {
101         return mNetworkRequest;
102     }
103 
104     @Override
105     @CallSuper
onLost(Network network)106     public void onLost(Network network) {
107         VvmLog.d(TAG, "onLost");
108         mResultReceived = true;
109         onFailed(NETWORK_REQUEST_FAILED_LOST);
110     }
111 
112     @Override
113     @CallSuper
onAvailable(Network network)114     public void onAvailable(Network network) {
115         super.onAvailable(network);
116         mResultReceived = true;
117     }
118 
119     @Override
120     @CallSuper
onUnavailable()121     public void onUnavailable() {
122         mResultReceived = true;
123         onFailed(NETWORK_REQUEST_FAILED_TIMEOUT);
124     }
125 
requestNetwork()126     public void requestNetwork() {
127         if (mRequestSent == true) {
128             VvmLog.e(TAG, "requestNetwork() called twice");
129             return;
130         }
131         mRequestSent = true;
132         getConnectivityManager().requestNetwork(getNetworkRequest(), this);
133         /**
134          * Somehow requestNetwork() with timeout doesn't work, and it's a hidden method.
135          * Implement our own timeout mechanism instead.
136          */
137         Handler handler = new Handler(Looper.getMainLooper());
138         handler.postDelayed(new Runnable() {
139             @Override
140             public void run() {
141                 if (mResultReceived == false) {
142                     onFailed(NETWORK_REQUEST_FAILED_TIMEOUT);
143                 }
144             }
145         }, NETWORK_REQUEST_TIMEOUT_MILLIS);
146     }
147 
releaseNetwork()148     public void releaseNetwork() {
149         VvmLog.d(TAG, "releaseNetwork");
150         getConnectivityManager().unregisterNetworkCallback(this);
151     }
152 
getConnectivityManager()153     public ConnectivityManager getConnectivityManager() {
154         if (mConnectivityManager == null) {
155             mConnectivityManager = (ConnectivityManager) mContext.getSystemService(
156                     Context.CONNECTIVITY_SERVICE);
157         }
158         return mConnectivityManager;
159     }
160 
161     @CallSuper
onFailed(String reason)162     public void onFailed(String reason) {
163         VvmLog.d(TAG, "onFailed: " + reason);
164         if (mCarrierConfigHelper.isCellularDataRequired()) {
165             mCarrierConfigHelper
166                 .handleEvent(mStatus, OmtpEvents.DATA_NO_CONNECTION_CELLULAR_REQUIRED);
167         } else {
168             mCarrierConfigHelper.handleEvent(mStatus, OmtpEvents.DATA_NO_CONNECTION);
169         }
170         releaseNetwork();
171     }
172 }
173