Home | History | Annotate | Download | only in dataconnection
      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.Context;
     21 import android.net.NetworkConfig;
     22 import android.telephony.Rlog;
     23 
     24 import com.android.internal.R;
     25 import com.android.internal.telephony.DctConstants;
     26 import com.android.internal.telephony.Phone;
     27 
     28 import java.io.FileDescriptor;
     29 import java.io.PrintWriter;
     30 import java.util.ArrayList;
     31 import java.util.concurrent.atomic.AtomicBoolean;
     32 import java.util.concurrent.atomic.AtomicInteger;
     33 
     34 /**
     35  * Maintain the Apn context
     36  */
     37 public class ApnContext {
     38 
     39     public final String LOG_TAG;
     40 
     41     protected static final boolean DBG = false;
     42 
     43     private final Context mContext;
     44 
     45     private final String mApnType;
     46 
     47     private DctConstants.State mState;
     48 
     49     private ArrayList<ApnSetting> mWaitingApns = null;
     50 
     51     public final int priority;
     52 
     53     /** A zero indicates that all waiting APNs had a permanent error */
     54     private AtomicInteger mWaitingApnsPermanentFailureCountDown;
     55 
     56     private ApnSetting mApnSetting;
     57 
     58     DcAsyncChannel mDcAc;
     59 
     60     String mReason;
     61 
     62     PendingIntent mReconnectAlarmIntent;
     63 
     64     /**
     65      * user/app requested connection on this APN
     66      */
     67     AtomicBoolean mDataEnabled;
     68 
     69     /**
     70      * carrier requirements met
     71      */
     72     AtomicBoolean mDependencyMet;
     73 
     74     public ApnContext(Context context, String apnType, String logTag, NetworkConfig config) {
     75         mContext = context;
     76         mApnType = apnType;
     77         mState = DctConstants.State.IDLE;
     78         setReason(Phone.REASON_DATA_ENABLED);
     79         mDataEnabled = new AtomicBoolean(false);
     80         mDependencyMet = new AtomicBoolean(config.dependencyMet);
     81         mWaitingApnsPermanentFailureCountDown = new AtomicInteger(0);
     82         priority = config.priority;
     83         LOG_TAG = logTag;
     84     }
     85 
     86     public String getApnType() {
     87         return mApnType;
     88     }
     89 
     90     public synchronized DcAsyncChannel getDcAc() {
     91         return mDcAc;
     92     }
     93 
     94     public synchronized void setDataConnectionAc(DcAsyncChannel dcac) {
     95         if (DBG) {
     96             log("setDataConnectionAc: old dcac=" + mDcAc + " new dcac=" + dcac
     97                     + " this=" + this);
     98         }
     99         mDcAc = dcac;
    100     }
    101 
    102     public synchronized PendingIntent getReconnectIntent() {
    103         return mReconnectAlarmIntent;
    104     }
    105 
    106     public synchronized void setReconnectIntent(PendingIntent intent) {
    107         mReconnectAlarmIntent = intent;
    108     }
    109 
    110     public synchronized ApnSetting getApnSetting() {
    111         log("getApnSetting: apnSetting=" + mApnSetting);
    112         return mApnSetting;
    113     }
    114 
    115     public synchronized void setApnSetting(ApnSetting apnSetting) {
    116         log("setApnSetting: apnSetting=" + apnSetting);
    117         mApnSetting = apnSetting;
    118     }
    119 
    120     public synchronized void setWaitingApns(ArrayList<ApnSetting> waitingApns) {
    121         mWaitingApns = waitingApns;
    122         mWaitingApnsPermanentFailureCountDown.set(mWaitingApns.size());
    123     }
    124 
    125     public int getWaitingApnsPermFailCount() {
    126         return mWaitingApnsPermanentFailureCountDown.get();
    127     }
    128 
    129     public void decWaitingApnsPermFailCount() {
    130         mWaitingApnsPermanentFailureCountDown.decrementAndGet();
    131     }
    132 
    133     public synchronized ApnSetting getNextWaitingApn() {
    134         ArrayList<ApnSetting> list = mWaitingApns;
    135         ApnSetting apn = null;
    136 
    137         if (list != null) {
    138             if (!list.isEmpty()) {
    139                 apn = list.get(0);
    140             }
    141         }
    142         return apn;
    143     }
    144 
    145     public synchronized void removeWaitingApn(ApnSetting apn) {
    146         if (mWaitingApns != null) {
    147             mWaitingApns.remove(apn);
    148         }
    149     }
    150 
    151     public synchronized ArrayList<ApnSetting> getWaitingApns() {
    152         return mWaitingApns;
    153     }
    154 
    155     public synchronized void setState(DctConstants.State s) {
    156         if (DBG) {
    157             log("setState: " + s + ", previous state:" + mState);
    158         }
    159 
    160         mState = s;
    161 
    162         if (mState == DctConstants.State.FAILED) {
    163             if (mWaitingApns != null) {
    164                 mWaitingApns.clear(); // when teardown the connection and set to IDLE
    165             }
    166         }
    167     }
    168 
    169     public synchronized DctConstants.State getState() {
    170         return mState;
    171     }
    172 
    173     public boolean isDisconnected() {
    174         DctConstants.State currentState = getState();
    175         return ((currentState == DctConstants.State.IDLE) ||
    176                     currentState == DctConstants.State.FAILED);
    177     }
    178 
    179     public synchronized void setReason(String reason) {
    180         if (DBG) {
    181             log("set reason as " + reason + ",current state " + mState);
    182         }
    183         mReason = reason;
    184     }
    185 
    186     public synchronized String getReason() {
    187         return mReason;
    188     }
    189 
    190     public boolean isReady() {
    191         return mDataEnabled.get() && mDependencyMet.get();
    192     }
    193 
    194     public boolean isConnectable() {
    195         return isReady() && ((mState == DctConstants.State.IDLE)
    196                                 || (mState == DctConstants.State.SCANNING)
    197                                 || (mState == DctConstants.State.RETRYING)
    198                                 || (mState == DctConstants.State.FAILED));
    199     }
    200 
    201     public boolean isConnectedOrConnecting() {
    202         return isReady() && ((mState == DctConstants.State.CONNECTED)
    203                                 || (mState == DctConstants.State.CONNECTING)
    204                                 || (mState == DctConstants.State.SCANNING)
    205                                 || (mState == DctConstants.State.RETRYING));
    206     }
    207 
    208     public void setEnabled(boolean enabled) {
    209         if (DBG) {
    210             log("set enabled as " + enabled + ", current state is " + mDataEnabled.get());
    211         }
    212         mDataEnabled.set(enabled);
    213     }
    214 
    215     public boolean isEnabled() {
    216         return mDataEnabled.get();
    217     }
    218 
    219     public void setDependencyMet(boolean met) {
    220         if (DBG) {
    221             log("set mDependencyMet as " + met + " current state is " + mDependencyMet.get());
    222         }
    223         mDependencyMet.set(met);
    224     }
    225 
    226     public boolean getDependencyMet() {
    227        return mDependencyMet.get();
    228     }
    229 
    230     public boolean isProvisioningApn() {
    231         String provisioningApn = mContext.getResources()
    232                 .getString(R.string.mobile_provisioning_apn);
    233         if ((mApnSetting != null) && (mApnSetting.apn != null)) {
    234             return (mApnSetting.apn.equals(provisioningApn));
    235         } else {
    236             return false;
    237         }
    238     }
    239 
    240     @Override
    241     public synchronized String toString() {
    242         // We don't print mDataConnection because its recursive.
    243         return "{mApnType=" + mApnType + " mState=" + getState() + " mWaitingApns={" + mWaitingApns +
    244                 "} mWaitingApnsPermanentFailureCountDown=" + mWaitingApnsPermanentFailureCountDown +
    245                 " mApnSetting={" + mApnSetting + "} mReason=" + mReason +
    246                 " mDataEnabled=" + mDataEnabled + " mDependencyMet=" + mDependencyMet + "}";
    247     }
    248 
    249     protected void log(String s) {
    250         Rlog.d(LOG_TAG, "[ApnContext:" + mApnType + "] " + s);
    251     }
    252 
    253     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
    254         pw.println("ApnContext: " + this.toString());
    255     }
    256 }
    257