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     private final Object mRefCountLock = new Object();
     70     private int mRefCount = 0;
     71 
     72     /**
     73      * carrier requirements met
     74      */
     75     AtomicBoolean mDependencyMet;
     76 
     77     private final DcTrackerBase mDcTracker;
     78 
     79     public ApnContext(Context context, String apnType, String logTag, NetworkConfig config,
     80             DcTrackerBase tracker) {
     81         mContext = context;
     82         mApnType = apnType;
     83         mState = DctConstants.State.IDLE;
     84         setReason(Phone.REASON_DATA_ENABLED);
     85         mDataEnabled = new AtomicBoolean(false);
     86         mDependencyMet = new AtomicBoolean(config.dependencyMet);
     87         mWaitingApnsPermanentFailureCountDown = new AtomicInteger(0);
     88         priority = config.priority;
     89         LOG_TAG = logTag;
     90         mDcTracker = tracker;
     91     }
     92 
     93     public String getApnType() {
     94         return mApnType;
     95     }
     96 
     97     public synchronized DcAsyncChannel getDcAc() {
     98         return mDcAc;
     99     }
    100 
    101     public synchronized void setDataConnectionAc(DcAsyncChannel dcac) {
    102         if (DBG) {
    103             log("setDataConnectionAc: old dcac=" + mDcAc + " new dcac=" + dcac
    104                     + " this=" + this);
    105         }
    106         mDcAc = dcac;
    107     }
    108 
    109     public synchronized PendingIntent getReconnectIntent() {
    110         return mReconnectAlarmIntent;
    111     }
    112 
    113     public synchronized void setReconnectIntent(PendingIntent intent) {
    114         mReconnectAlarmIntent = intent;
    115     }
    116 
    117     public synchronized ApnSetting getApnSetting() {
    118         log("getApnSetting: apnSetting=" + mApnSetting);
    119         return mApnSetting;
    120     }
    121 
    122     public synchronized void setApnSetting(ApnSetting apnSetting) {
    123         log("setApnSetting: apnSetting=" + apnSetting);
    124         mApnSetting = apnSetting;
    125     }
    126 
    127     public synchronized void setWaitingApns(ArrayList<ApnSetting> waitingApns) {
    128         mWaitingApns = waitingApns;
    129         mWaitingApnsPermanentFailureCountDown.set(mWaitingApns.size());
    130     }
    131 
    132     public int getWaitingApnsPermFailCount() {
    133         return mWaitingApnsPermanentFailureCountDown.get();
    134     }
    135 
    136     public void decWaitingApnsPermFailCount() {
    137         mWaitingApnsPermanentFailureCountDown.decrementAndGet();
    138     }
    139 
    140     public synchronized ApnSetting getNextWaitingApn() {
    141         ArrayList<ApnSetting> list = mWaitingApns;
    142         ApnSetting apn = null;
    143 
    144         if (list != null) {
    145             if (!list.isEmpty()) {
    146                 apn = list.get(0);
    147             }
    148         }
    149         return apn;
    150     }
    151 
    152     public synchronized void removeWaitingApn(ApnSetting apn) {
    153         if (mWaitingApns != null) {
    154             mWaitingApns.remove(apn);
    155         }
    156     }
    157 
    158     public synchronized ArrayList<ApnSetting> getWaitingApns() {
    159         return mWaitingApns;
    160     }
    161 
    162     public synchronized void setState(DctConstants.State s) {
    163         if (DBG) {
    164             log("setState: " + s + ", previous state:" + mState);
    165         }
    166 
    167         mState = s;
    168 
    169         if (mState == DctConstants.State.FAILED) {
    170             if (mWaitingApns != null) {
    171                 mWaitingApns.clear(); // when teardown the connection and set to IDLE
    172             }
    173         }
    174     }
    175 
    176     public synchronized DctConstants.State getState() {
    177         return mState;
    178     }
    179 
    180     public boolean isDisconnected() {
    181         DctConstants.State currentState = getState();
    182         return ((currentState == DctConstants.State.IDLE) ||
    183                     currentState == DctConstants.State.FAILED);
    184     }
    185 
    186     public synchronized void setReason(String reason) {
    187         if (DBG) {
    188             log("set reason as " + reason + ",current state " + mState);
    189         }
    190         mReason = reason;
    191     }
    192 
    193     public synchronized String getReason() {
    194         return mReason;
    195     }
    196 
    197     public boolean isReady() {
    198         return mDataEnabled.get() && mDependencyMet.get();
    199     }
    200 
    201     public boolean isConnectable() {
    202         return isReady() && ((mState == DctConstants.State.IDLE)
    203                                 || (mState == DctConstants.State.SCANNING)
    204                                 || (mState == DctConstants.State.RETRYING)
    205                                 || (mState == DctConstants.State.FAILED));
    206     }
    207 
    208     public boolean isConnectedOrConnecting() {
    209         return isReady() && ((mState == DctConstants.State.CONNECTED)
    210                                 || (mState == DctConstants.State.CONNECTING)
    211                                 || (mState == DctConstants.State.SCANNING)
    212                                 || (mState == DctConstants.State.RETRYING));
    213     }
    214 
    215     public void setEnabled(boolean enabled) {
    216         if (DBG) {
    217             log("set enabled as " + enabled + ", current state is " + mDataEnabled.get());
    218         }
    219         mDataEnabled.set(enabled);
    220     }
    221 
    222     public boolean isEnabled() {
    223         return mDataEnabled.get();
    224     }
    225 
    226     public void setDependencyMet(boolean met) {
    227         if (DBG) {
    228             log("set mDependencyMet as " + met + " current state is " + mDependencyMet.get());
    229         }
    230         mDependencyMet.set(met);
    231     }
    232 
    233     public boolean getDependencyMet() {
    234        return mDependencyMet.get();
    235     }
    236 
    237     public boolean isProvisioningApn() {
    238         String provisioningApn = mContext.getResources()
    239                 .getString(R.string.mobile_provisioning_apn);
    240         if ((mApnSetting != null) && (mApnSetting.apn != null)) {
    241             return (mApnSetting.apn.equals(provisioningApn));
    242         } else {
    243             return false;
    244         }
    245     }
    246 
    247     public void incRefCount() {
    248         synchronized (mRefCountLock) {
    249             if (mRefCount++ == 0) {
    250                 mDcTracker.setEnabled(mDcTracker.apnTypeToId(mApnType), true);
    251             }
    252         }
    253     }
    254 
    255     public void decRefCount() {
    256         synchronized (mRefCountLock) {
    257             if (mRefCount-- == 1) {
    258                 mDcTracker.setEnabled(mDcTracker.apnTypeToId(mApnType), false);
    259             }
    260         }
    261     }
    262 
    263     @Override
    264     public synchronized String toString() {
    265         // We don't print mDataConnection because its recursive.
    266         return "{mApnType=" + mApnType + " mState=" + getState() + " mWaitingApns={" + mWaitingApns +
    267                 "} mWaitingApnsPermanentFailureCountDown=" + mWaitingApnsPermanentFailureCountDown +
    268                 " mApnSetting={" + mApnSetting + "} mReason=" + mReason +
    269                 " mDataEnabled=" + mDataEnabled + " mDependencyMet=" + mDependencyMet + "}";
    270     }
    271 
    272     protected void log(String s) {
    273         Rlog.d(LOG_TAG, "[ApnContext:" + mApnType + "] " + s);
    274     }
    275 
    276     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
    277         pw.println("ApnContext: " + this.toString());
    278     }
    279 }
    280