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