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