ApnContext.java revision f3ab6ab303e1da929ce26b7c5d63565bff136221
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.content.Context;
21import android.net.NetworkConfig;
22import android.telephony.Rlog;
23
24import com.android.internal.R;
25import com.android.internal.telephony.DctConstants;
26import com.android.internal.telephony.Phone;
27
28import java.io.FileDescriptor;
29import java.io.PrintWriter;
30import java.util.ArrayList;
31import java.util.concurrent.atomic.AtomicBoolean;
32import java.util.concurrent.atomic.AtomicInteger;
33
34/**
35 * Maintain the Apn context
36 */
37public 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