ApnContext.java revision ff4e317d24f0d23bdc0f306d53ddc51f2f1ecf6a
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
17package com.android.internal.telephony.dataconnection;
18
19import android.app.PendingIntent;
20import android.telephony.Rlog;
21
22import com.android.internal.telephony.DctConstants;
23import com.android.internal.telephony.Phone;
24
25import java.io.FileDescriptor;
26import java.io.PrintWriter;
27import java.util.ArrayList;
28import java.util.concurrent.atomic.AtomicBoolean;
29import java.util.concurrent.atomic.AtomicInteger;
30
31/**
32 * Maintain the Apn context
33 */
34public class ApnContext {
35
36    public final String LOG_TAG;
37
38    protected static final boolean DBG = false;
39
40    private final String mApnType;
41
42    private DctConstants.State mState;
43
44    private ArrayList<ApnSetting> mWaitingApns = null;
45
46    /** A zero indicates that all waiting APNs had a permanent error */
47    private AtomicInteger mWaitingApnsPermanentFailureCountDown;
48
49    private ApnSetting mApnSetting;
50
51    DataConnectionAc mDataConnectionAc;
52
53    String mReason;
54
55    PendingIntent mReconnectAlarmIntent;
56
57    /**
58     * user/app requested connection on this APN
59     */
60    AtomicBoolean mDataEnabled;
61
62    /**
63     * carrier requirements met
64     */
65    AtomicBoolean mDependencyMet;
66
67    public ApnContext(String apnType, String logTag) {
68        mApnType = apnType;
69        mState = DctConstants.State.IDLE;
70        setReason(Phone.REASON_DATA_ENABLED);
71        mDataEnabled = new AtomicBoolean(false);
72        mDependencyMet = new AtomicBoolean(true);
73        mWaitingApnsPermanentFailureCountDown = new AtomicInteger(0);
74        LOG_TAG = logTag;
75    }
76
77    public String getApnType() {
78        return mApnType;
79    }
80
81    public synchronized DataConnectionAc getDcAc() {
82        return mDataConnectionAc;
83    }
84
85    public synchronized void setDataConnectionAc(DataConnectionAc dcac) {
86        if (DBG) {
87            log("setDataConnectionAc: old dcac=" + mDataConnectionAc + " new dcac=" + dcac
88                    + " this=" + this);
89        }
90        if ((dcac == null) && (mDataConnectionAc != null)) {
91            // TODO: This tearDown should be done by caller, but for now we'll do it
92            if (DBG) log("setDataConnection: call tearDown");
93            mDataConnectionAc.tearDown(this, "", null);
94        }
95        mDataConnectionAc = 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    @Override
220    public String toString() {
221        // We don't print mDataConnection because its recursive.
222        return "{mApnType=" + mApnType + " mState=" + getState() + " mWaitingApns={" + mWaitingApns +
223                "} mWaitingApnsPermanentFailureCountDown=" + mWaitingApnsPermanentFailureCountDown +
224                " mApnSetting={" + mApnSetting + "} mReason=" + mReason +
225                " mDataEnabled=" + mDataEnabled + " mDependencyMet=" + mDependencyMet + "}";
226    }
227
228    protected void log(String s) {
229        Rlog.d(LOG_TAG, "[ApnContext:" + mApnType + "] " + s);
230    }
231
232    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
233        pw.println("ApnContext: " + this.toString());
234    }
235}
236