• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 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 
17 package com.android.internal.telephony.dataconnection;
18 
19 import android.app.PendingIntent;
20 import android.content.res.Resources;
21 import android.net.ConnectivityManager;
22 import android.net.NetworkCapabilities;
23 import android.net.NetworkConfig;
24 import android.net.NetworkRequest;
25 import android.telephony.Rlog;
26 import android.text.TextUtils;
27 import android.util.LocalLog;
28 import android.util.SparseIntArray;
29 
30 import com.android.internal.R;
31 import com.android.internal.telephony.DctConstants;
32 import com.android.internal.telephony.Phone;
33 import com.android.internal.telephony.PhoneConstants;
34 import com.android.internal.telephony.RetryManager;
35 import com.android.internal.util.IndentingPrintWriter;
36 
37 import java.io.FileDescriptor;
38 import java.io.PrintWriter;
39 import java.util.ArrayDeque;
40 import java.util.ArrayList;
41 import java.util.List;
42 import java.util.concurrent.atomic.AtomicBoolean;
43 import java.util.concurrent.atomic.AtomicInteger;
44 
45 /**
46  * Maintain the Apn context
47  */
48 public class ApnContext {
49 
50     public final String LOG_TAG;
51     private final static String SLOG_TAG = "ApnContext";
52 
53     protected static final boolean DBG = false;
54 
55     private final Phone mPhone;
56 
57     private final String mApnType;
58 
59     private DctConstants.State mState;
60 
61     public final int priority;
62 
63     private ApnSetting mApnSetting;
64 
65     DcAsyncChannel mDcAc;
66 
67     String mReason;
68 
69     PendingIntent mReconnectAlarmIntent;
70 
71     /**
72      * user/app requested connection on this APN
73      */
74     AtomicBoolean mDataEnabled;
75 
76     private final Object mRefCountLock = new Object();
77     private int mRefCount = 0;
78 
79     /**
80      * carrier requirements met
81      */
82     AtomicBoolean mDependencyMet;
83 
84     private final DcTracker mDcTracker;
85 
86     /**
87      * Remember this as a change in this value to a more permissive state
88      * should cause us to retry even permanent failures
89      */
90     private boolean mConcurrentVoiceAndDataAllowed;
91 
92     /**
93      * used to track a single connection request so disconnects can get ignored if
94      * obsolete.
95      */
96     private final AtomicInteger mConnectionGeneration = new AtomicInteger(0);
97 
98     /**
99      * Retry manager that handles the APN retry and delays.
100      */
101     private final RetryManager mRetryManager;
102 
103     /**
104      * AonContext constructor
105      * @param phone phone object
106      * @param apnType APN type (e.g. default, supl, mms, etc...)
107      * @param logTag Tag for logging
108      * @param config Network configuration
109      * @param tracker Data call tracker
110      */
ApnContext(Phone phone, String apnType, String logTag, NetworkConfig config, DcTracker tracker)111     public ApnContext(Phone phone, String apnType, String logTag, NetworkConfig config,
112             DcTracker tracker) {
113         mPhone = phone;
114         mApnType = apnType;
115         mState = DctConstants.State.IDLE;
116         setReason(Phone.REASON_DATA_ENABLED);
117         mDataEnabled = new AtomicBoolean(false);
118         mDependencyMet = new AtomicBoolean(config.dependencyMet);
119         priority = config.priority;
120         LOG_TAG = logTag;
121         mDcTracker = tracker;
122         mRetryManager = new RetryManager(phone, apnType);
123     }
124 
125     /**
126      * Get the APN type
127      * @return The APN type
128      */
getApnType()129     public String getApnType() {
130         return mApnType;
131     }
132 
133     /**
134      * Get the data call async channel.
135      * @return The data call async channel
136      */
getDcAc()137     public synchronized DcAsyncChannel getDcAc() {
138         return mDcAc;
139     }
140 
141     /**
142      * Set the data call async channel.
143      * @param dcac The data call async channel
144      */
setDataConnectionAc(DcAsyncChannel dcac)145     public synchronized void setDataConnectionAc(DcAsyncChannel dcac) {
146         if (DBG) {
147             log("setDataConnectionAc: old dcac=" + mDcAc + " new dcac=" + dcac
148                     + " this=" + this);
149         }
150         mDcAc = dcac;
151     }
152 
153     /**
154      * Release data connection.
155      * @param reason The reason of releasing data connection
156      */
releaseDataConnection(String reason)157     public synchronized void releaseDataConnection(String reason) {
158         if (mDcAc != null) {
159             mDcAc.tearDown(this, reason, null);
160             mDcAc = null;
161         }
162         setState(DctConstants.State.IDLE);
163     }
164 
165     /**
166      * Get the reconnect intent.
167      * @return The reconnect intent
168      */
getReconnectIntent()169     public synchronized PendingIntent getReconnectIntent() {
170         return mReconnectAlarmIntent;
171     }
172 
173     /**
174      * Save the reconnect intent which can be used for cancelling later.
175      * @param intent The reconnect intent
176      */
setReconnectIntent(PendingIntent intent)177     public synchronized void setReconnectIntent(PendingIntent intent) {
178         mReconnectAlarmIntent = intent;
179     }
180 
181     /**
182      * Get the current APN setting.
183      * @return APN setting
184      */
getApnSetting()185     public synchronized ApnSetting getApnSetting() {
186         if (DBG) log("getApnSetting: apnSetting=" + mApnSetting);
187         return mApnSetting;
188     }
189 
190     /**
191      * Set the APN setting.
192      * @param apnSetting APN setting
193      */
setApnSetting(ApnSetting apnSetting)194     public synchronized void setApnSetting(ApnSetting apnSetting) {
195         if (DBG) log("setApnSetting: apnSetting=" + apnSetting);
196         mApnSetting = apnSetting;
197     }
198 
199     /**
200      * Set the list of APN candidates which will be used for data call setup later.
201      * @param waitingApns List of APN candidates
202      */
setWaitingApns(ArrayList<ApnSetting> waitingApns)203     public synchronized void setWaitingApns(ArrayList<ApnSetting> waitingApns) {
204         mRetryManager.setWaitingApns(waitingApns);
205     }
206 
207     /**
208      * Get the next available APN to try.
209      * @return APN setting which will be used for data call setup. Return null if there is no
210      * APN can be retried.
211      */
getNextApnSetting()212     public ApnSetting getNextApnSetting() {
213         return mRetryManager.getNextApnSetting();
214     }
215 
216     /**
217      * Save the modem suggested delay for retrying the current APN.
218      * This method is called when we get the suggested delay from RIL.
219      * @param delay The delay in milliseconds
220      */
setModemSuggestedDelay(long delay)221     public void setModemSuggestedDelay(long delay) {
222         mRetryManager.setModemSuggestedDelay(delay);
223     }
224 
225     /**
226      * Get the delay for trying the next APN setting if the current one failed.
227      * @param failFastEnabled True if fail fast mode enabled. In this case we'll use a shorter
228      *                        delay.
229      * @return The delay in milliseconds
230      */
getDelayForNextApn(boolean failFastEnabled)231     public long getDelayForNextApn(boolean failFastEnabled) {
232         return mRetryManager.getDelayForNextApn(failFastEnabled || isFastRetryReason());
233     }
234 
235     /**
236      * Mark the current APN setting permanently failed, which means it will not be retried anymore.
237      * @param apn APN setting
238      */
markApnPermanentFailed(ApnSetting apn)239     public void markApnPermanentFailed(ApnSetting apn) {
240         mRetryManager.markApnPermanentFailed(apn);
241     }
242 
243     /**
244      * Get the list of waiting APNs.
245      * @return the list of waiting APNs
246      */
getWaitingApns()247     public ArrayList<ApnSetting> getWaitingApns() {
248         return mRetryManager.getWaitingApns();
249     }
250 
251     /**
252      * Save the state indicating concurrent voice/data allowed.
253      * @param allowed True if concurrent voice/data is allowed
254      */
setConcurrentVoiceAndDataAllowed(boolean allowed)255     public synchronized void setConcurrentVoiceAndDataAllowed(boolean allowed) {
256         mConcurrentVoiceAndDataAllowed = allowed;
257     }
258 
259     /**
260      * Get the state indicating concurrent voice/data allowed.
261      * @return True if concurrent voice/data is allowed
262      */
isConcurrentVoiceAndDataAllowed()263     public synchronized boolean isConcurrentVoiceAndDataAllowed() {
264         return mConcurrentVoiceAndDataAllowed;
265     }
266 
267     /**
268      * Set the current data call state.
269      * @param s Current data call state
270      */
setState(DctConstants.State s)271     public synchronized void setState(DctConstants.State s) {
272         if (DBG) {
273             log("setState: " + s + ", previous state:" + mState);
274         }
275 
276         mState = s;
277 
278         if (mState == DctConstants.State.FAILED) {
279             if (mRetryManager.getWaitingApns() != null) {
280                 mRetryManager.getWaitingApns().clear(); // when teardown the connection and set to IDLE
281             }
282         }
283     }
284 
285     /**
286      * Get the current data call state.
287      * @return The current data call state
288      */
getState()289     public synchronized DctConstants.State getState() {
290         return mState;
291     }
292 
293     /**
294      * Check whether the data call is disconnected or not.
295      * @return True if the data call is disconnected
296      */
isDisconnected()297     public boolean isDisconnected() {
298         DctConstants.State currentState = getState();
299         return ((currentState == DctConstants.State.IDLE) ||
300                     currentState == DctConstants.State.FAILED);
301     }
302 
303     /**
304      * Set the reason for data call connection.
305      * @param reason Reason for data call connection
306      */
setReason(String reason)307     public synchronized void setReason(String reason) {
308         if (DBG) {
309             log("set reason as " + reason + ",current state " + mState);
310         }
311         mReason = reason;
312     }
313 
314     /**
315      * Get the reason for data call connection.
316      * @return The reason for data call connection
317      */
getReason()318     public synchronized String getReason() {
319         return mReason;
320     }
321 
322     /**
323      * Check if ready for data call connection
324      * @return True if ready, otherwise false.
325      */
isReady()326     public boolean isReady() {
327         return mDataEnabled.get() && mDependencyMet.get();
328     }
329 
330     /**
331      * Check if the data call is in the state which allow connecting.
332      * @return True if allowed, otherwise false.
333      */
isConnectable()334     public boolean isConnectable() {
335         return isReady() && ((mState == DctConstants.State.IDLE)
336                                 || (mState == DctConstants.State.SCANNING)
337                                 || (mState == DctConstants.State.RETRYING)
338                                 || (mState == DctConstants.State.FAILED));
339     }
340 
341     /**
342      * Check if apn reason is fast retry reason which should apply shorter delay between apn re-try.
343      * @return True if it is fast retry reason, otherwise false.
344      */
isFastRetryReason()345     private boolean isFastRetryReason() {
346         return Phone.REASON_NW_TYPE_CHANGED.equals(mReason) ||
347                 Phone.REASON_APN_CHANGED.equals(mReason);
348     }
349 
350     /** Check if the data call is in connected or connecting state.
351      * @return True if the data call is in connected or connecting state
352      */
isConnectedOrConnecting()353     public boolean isConnectedOrConnecting() {
354         return isReady() && ((mState == DctConstants.State.CONNECTED)
355                                 || (mState == DctConstants.State.CONNECTING)
356                                 || (mState == DctConstants.State.SCANNING)
357                                 || (mState == DctConstants.State.RETRYING));
358     }
359 
360     /**
361      * Set data call enabled/disabled state.
362      * @param enabled True if data call is enabled
363      */
setEnabled(boolean enabled)364     public void setEnabled(boolean enabled) {
365         if (DBG) {
366             log("set enabled as " + enabled + ", current state is " + mDataEnabled.get());
367         }
368         mDataEnabled.set(enabled);
369     }
370 
371     /**
372      * Check if the data call is enabled or not.
373      * @return True if enabled
374      */
isEnabled()375     public boolean isEnabled() {
376         return mDataEnabled.get();
377     }
378 
setDependencyMet(boolean met)379     public void setDependencyMet(boolean met) {
380         if (DBG) {
381             log("set mDependencyMet as " + met + " current state is " + mDependencyMet.get());
382         }
383         mDependencyMet.set(met);
384     }
385 
getDependencyMet()386     public boolean getDependencyMet() {
387        return mDependencyMet.get();
388     }
389 
isProvisioningApn()390     public boolean isProvisioningApn() {
391         String provisioningApn = mPhone.getContext().getResources()
392                 .getString(R.string.mobile_provisioning_apn);
393         if (!TextUtils.isEmpty(provisioningApn) &&
394                 (mApnSetting != null) && (mApnSetting.apn != null)) {
395             return (mApnSetting.apn.equals(provisioningApn));
396         } else {
397             return false;
398         }
399     }
400 
401     private final ArrayList<LocalLog> mLocalLogs = new ArrayList<>();
402     private final ArrayList<NetworkRequest> mNetworkRequests = new ArrayList<>();
403     private final ArrayDeque<LocalLog> mHistoryLogs = new ArrayDeque<>();
404     private final static int MAX_HISTORY_LOG_COUNT = 4;
405 
requestLog(String str)406     public void requestLog(String str) {
407         synchronized (mRefCountLock) {
408             for (LocalLog l : mLocalLogs) {
409                 l.log(str);
410             }
411         }
412     }
413 
requestNetwork(NetworkRequest networkRequest, LocalLog log)414     public void requestNetwork(NetworkRequest networkRequest, LocalLog log) {
415         synchronized (mRefCountLock) {
416             if (mLocalLogs.contains(log) || mNetworkRequests.contains(networkRequest)) {
417                 log.log("ApnContext.requestNetwork has duplicate add - " + mNetworkRequests.size());
418             } else {
419                 mLocalLogs.add(log);
420                 mNetworkRequests.add(networkRequest);
421                 mDcTracker.setEnabled(apnIdForApnName(mApnType), true);
422             }
423         }
424     }
425 
releaseNetwork(NetworkRequest networkRequest, LocalLog log)426     public void releaseNetwork(NetworkRequest networkRequest, LocalLog log) {
427         synchronized (mRefCountLock) {
428             if (mLocalLogs.contains(log) == false) {
429                 log.log("ApnContext.releaseNetwork can't find this log");
430             } else {
431                 mLocalLogs.remove(log);
432             }
433             if (mNetworkRequests.contains(networkRequest) == false) {
434                 log.log("ApnContext.releaseNetwork can't find this request ("
435                         + networkRequest + ")");
436             } else {
437                 mNetworkRequests.remove(networkRequest);
438                 log.log("ApnContext.releaseNetwork left with " + mNetworkRequests.size() +
439                         " requests.");
440                 if (mNetworkRequests.size() == 0) {
441                     mDcTracker.setEnabled(apnIdForApnName(mApnType), false);
442                 }
443             }
444         }
445     }
446 
getNetworkRequests()447     public List<NetworkRequest> getNetworkRequests() {
448         synchronized (mRefCountLock) {
449             return new ArrayList<NetworkRequest>(mNetworkRequests);
450         }
451     }
452 
hasNoRestrictedRequests(boolean excludeDun)453     public boolean hasNoRestrictedRequests(boolean excludeDun) {
454         synchronized (mRefCountLock) {
455             for (NetworkRequest nr : mNetworkRequests) {
456                 if (excludeDun &&
457                         nr.networkCapabilities.hasCapability(
458                         NetworkCapabilities.NET_CAPABILITY_DUN)) {
459                     continue;
460                 }
461                 if (nr.networkCapabilities.hasCapability(
462                         NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED) == false) {
463                     return false;
464                 }
465             }
466         }
467         return true;
468     }
469 
470     private final SparseIntArray mRetriesLeftPerErrorCode = new SparseIntArray();
471 
resetErrorCodeRetries()472     public void resetErrorCodeRetries() {
473         requestLog("ApnContext.resetErrorCodeRetries");
474         if (DBG) log("ApnContext.resetErrorCodeRetries");
475 
476         String[] config = mPhone.getContext().getResources().getStringArray(
477                 com.android.internal.R.array.config_cell_retries_per_error_code);
478         synchronized (mRetriesLeftPerErrorCode) {
479             mRetriesLeftPerErrorCode.clear();
480 
481             for (String c : config) {
482                 String errorValue[] = c.split(",");
483                 if (errorValue != null && errorValue.length == 2) {
484                     int count = 0;
485                     int errorCode = 0;
486                     try {
487                         errorCode = Integer.parseInt(errorValue[0]);
488                         count = Integer.parseInt(errorValue[1]);
489                     } catch (NumberFormatException e) {
490                         log("Exception parsing config_retries_per_error_code: " + e);
491                         continue;
492                     }
493                     if (count > 0 && errorCode > 0) {
494                         mRetriesLeftPerErrorCode.put(errorCode, count);
495                     }
496                 } else {
497                     log("Exception parsing config_retries_per_error_code: " + c);
498                 }
499             }
500         }
501     }
502 
restartOnError(int errorCode)503     public boolean restartOnError(int errorCode) {
504         boolean result = false;
505         int retriesLeft = 0;
506         synchronized(mRetriesLeftPerErrorCode) {
507             retriesLeft = mRetriesLeftPerErrorCode.get(errorCode);
508             switch (retriesLeft) {
509                 case 0: {
510                     // not set, never restart modem
511                     break;
512                 }
513                 case 1: {
514                     resetErrorCodeRetries();
515                     result = true;
516                     break;
517                 }
518                 default: {
519                     mRetriesLeftPerErrorCode.put(errorCode, retriesLeft - 1);
520                     result = false;
521                 }
522             }
523         }
524         String str = "ApnContext.restartOnError(" + errorCode + ") found " + retriesLeft +
525                 " and returned " + result;
526         if (DBG) log(str);
527         requestLog(str);
528         return result;
529     }
530 
incAndGetConnectionGeneration()531     public int incAndGetConnectionGeneration() {
532         return mConnectionGeneration.incrementAndGet();
533     }
534 
getConnectionGeneration()535     public int getConnectionGeneration() {
536         return mConnectionGeneration.get();
537     }
538 
getInterApnDelay(boolean failFastEnabled)539     public long getInterApnDelay(boolean failFastEnabled) {
540         return mRetryManager.getInterApnDelay(failFastEnabled || isFastRetryReason());
541     }
542 
apnIdForType(int networkType)543     public static int apnIdForType(int networkType) {
544         switch (networkType) {
545         case ConnectivityManager.TYPE_MOBILE:
546             return DctConstants.APN_DEFAULT_ID;
547         case ConnectivityManager.TYPE_MOBILE_MMS:
548             return DctConstants.APN_MMS_ID;
549         case ConnectivityManager.TYPE_MOBILE_SUPL:
550             return DctConstants.APN_SUPL_ID;
551         case ConnectivityManager.TYPE_MOBILE_DUN:
552             return DctConstants.APN_DUN_ID;
553         case ConnectivityManager.TYPE_MOBILE_FOTA:
554             return DctConstants.APN_FOTA_ID;
555         case ConnectivityManager.TYPE_MOBILE_IMS:
556             return DctConstants.APN_IMS_ID;
557         case ConnectivityManager.TYPE_MOBILE_CBS:
558             return DctConstants.APN_CBS_ID;
559         case ConnectivityManager.TYPE_MOBILE_IA:
560             return DctConstants.APN_IA_ID;
561         case ConnectivityManager.TYPE_MOBILE_EMERGENCY:
562             return DctConstants.APN_EMERGENCY_ID;
563         default:
564             return DctConstants.APN_INVALID_ID;
565         }
566     }
567 
apnIdForNetworkRequest(NetworkRequest nr)568     public static int apnIdForNetworkRequest(NetworkRequest nr) {
569         NetworkCapabilities nc = nr.networkCapabilities;
570         // For now, ignore the bandwidth stuff
571         if (nc.getTransportTypes().length > 0 &&
572                 nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) == false) {
573             return DctConstants.APN_INVALID_ID;
574         }
575 
576         // in the near term just do 1-1 matches.
577         // TODO - actually try to match the set of capabilities
578         int apnId = DctConstants.APN_INVALID_ID;
579         boolean error = false;
580 
581         if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
582             apnId = DctConstants.APN_DEFAULT_ID;
583         }
584         if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) {
585             if (apnId != DctConstants.APN_INVALID_ID) error = true;
586             apnId = DctConstants.APN_MMS_ID;
587         }
588         if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
589             if (apnId != DctConstants.APN_INVALID_ID) error = true;
590             apnId = DctConstants.APN_SUPL_ID;
591         }
592         if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) {
593             if (apnId != DctConstants.APN_INVALID_ID) error = true;
594             apnId = DctConstants.APN_DUN_ID;
595         }
596         if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) {
597             if (apnId != DctConstants.APN_INVALID_ID) error = true;
598             apnId = DctConstants.APN_FOTA_ID;
599         }
600         if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
601             if (apnId != DctConstants.APN_INVALID_ID) error = true;
602             apnId = DctConstants.APN_IMS_ID;
603         }
604         if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
605             if (apnId != DctConstants.APN_INVALID_ID) error = true;
606             apnId = DctConstants.APN_CBS_ID;
607         }
608         if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_IA)) {
609             if (apnId != DctConstants.APN_INVALID_ID) error = true;
610             apnId = DctConstants.APN_IA_ID;
611         }
612         if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_RCS)) {
613             if (apnId != DctConstants.APN_INVALID_ID) error = true;
614 
615             Rlog.d(SLOG_TAG, "RCS APN type not yet supported");
616         }
617         if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_XCAP)) {
618             if (apnId != DctConstants.APN_INVALID_ID) error = true;
619 
620             Rlog.d(SLOG_TAG, "XCAP APN type not yet supported");
621         }
622         if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)) {
623             if (apnId != DctConstants.APN_INVALID_ID) error = true;
624             apnId = DctConstants.APN_EMERGENCY_ID;
625         }
626         if (error) {
627             // TODO: If this error condition is removed, the framework's handling of
628             // NET_CAPABILITY_NOT_RESTRICTED will need to be updated so requests for
629             // say FOTA and INTERNET are marked as restricted.  This is not how
630             // NetworkCapabilities.maybeMarkCapabilitiesRestricted currently works.
631             Rlog.d(SLOG_TAG, "Multiple apn types specified in request - result is unspecified!");
632         }
633         if (apnId == DctConstants.APN_INVALID_ID) {
634             Rlog.d(SLOG_TAG, "Unsupported NetworkRequest in Telephony: nr=" + nr);
635         }
636         return apnId;
637     }
638 
639     // TODO - kill The use of these strings
apnIdForApnName(String type)640     public static int apnIdForApnName(String type) {
641         switch (type) {
642             case PhoneConstants.APN_TYPE_DEFAULT:
643                 return DctConstants.APN_DEFAULT_ID;
644             case PhoneConstants.APN_TYPE_MMS:
645                 return DctConstants.APN_MMS_ID;
646             case PhoneConstants.APN_TYPE_SUPL:
647                 return DctConstants.APN_SUPL_ID;
648             case PhoneConstants.APN_TYPE_DUN:
649                 return DctConstants.APN_DUN_ID;
650             case PhoneConstants.APN_TYPE_HIPRI:
651                 return DctConstants.APN_HIPRI_ID;
652             case PhoneConstants.APN_TYPE_IMS:
653                 return DctConstants.APN_IMS_ID;
654             case PhoneConstants.APN_TYPE_FOTA:
655                 return DctConstants.APN_FOTA_ID;
656             case PhoneConstants.APN_TYPE_CBS:
657                 return DctConstants.APN_CBS_ID;
658             case PhoneConstants.APN_TYPE_IA:
659                 return DctConstants.APN_IA_ID;
660             case PhoneConstants.APN_TYPE_EMERGENCY:
661                 return DctConstants.APN_EMERGENCY_ID;
662             default:
663                 return DctConstants.APN_INVALID_ID;
664         }
665     }
666 
apnNameForApnId(int id)667     private static String apnNameForApnId(int id) {
668         switch (id) {
669             case DctConstants.APN_DEFAULT_ID:
670                 return PhoneConstants.APN_TYPE_DEFAULT;
671             case DctConstants.APN_MMS_ID:
672                 return PhoneConstants.APN_TYPE_MMS;
673             case DctConstants.APN_SUPL_ID:
674                 return PhoneConstants.APN_TYPE_SUPL;
675             case DctConstants.APN_DUN_ID:
676                 return PhoneConstants.APN_TYPE_DUN;
677             case DctConstants.APN_HIPRI_ID:
678                 return PhoneConstants.APN_TYPE_HIPRI;
679             case DctConstants.APN_IMS_ID:
680                 return PhoneConstants.APN_TYPE_IMS;
681             case DctConstants.APN_FOTA_ID:
682                 return PhoneConstants.APN_TYPE_FOTA;
683             case DctConstants.APN_CBS_ID:
684                 return PhoneConstants.APN_TYPE_CBS;
685             case DctConstants.APN_IA_ID:
686                 return PhoneConstants.APN_TYPE_IA;
687             case DctConstants.APN_EMERGENCY_ID:
688                 return PhoneConstants.APN_TYPE_EMERGENCY;
689             default:
690                 Rlog.d(SLOG_TAG, "Unknown id (" + id + ") in apnIdToType");
691                 return PhoneConstants.APN_TYPE_DEFAULT;
692         }
693     }
694 
695     @Override
toString()696     public synchronized String toString() {
697         // We don't print mDataConnection because its recursive.
698         return "{mApnType=" + mApnType + " mState=" + getState() + " mWaitingApns={" +
699                 mRetryManager.getWaitingApns() + "}" + " mApnSetting={" + mApnSetting +
700                 "} mReason=" + mReason + " mDataEnabled=" + mDataEnabled + " mDependencyMet=" +
701                 mDependencyMet + "}";
702     }
703 
log(String s)704     private void log(String s) {
705         Rlog.d(LOG_TAG, "[ApnContext:" + mApnType + "] " + s);
706     }
707 
dump(FileDescriptor fd, PrintWriter printWriter, String[] args)708     public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
709         final IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
710         synchronized (mRefCountLock) {
711             pw.println(toString());
712             if (mNetworkRequests.size() > 0) {
713                 pw.println("NetworkRequests:");
714                 pw.increaseIndent();
715                 for (NetworkRequest nr : mNetworkRequests) {
716                     pw.println(nr);
717                 }
718                 pw.decreaseIndent();
719             }
720             pw.increaseIndent();
721             for (LocalLog l : mLocalLogs) {
722                 l.dump(fd, pw, args);
723             }
724             if (mHistoryLogs.size() > 0) pw.println("Historical Logs:");
725             for (LocalLog l : mHistoryLogs) {
726                 l.dump(fd, pw, args);
727             }
728             pw.decreaseIndent();
729             pw.println("mRetryManager={" + mRetryManager.toString() + "}");
730         }
731     }
732 }
733