Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 25cebe4f authored by Wink Saville's avatar Wink Saville
Browse files

Merge commit '43c93591' into manualmerge

* commit '43c93591':
  Add support for a provisioning apn.

Conflicts:
	src/java/com/android/internal/telephony/dataconnection/DcTracker.java

Change-Id: If78b4af0c466c6ca6939ef475726ad7a9688386a
parents a6855ef9 43c93591
Loading
Loading
Loading
Loading
+16 −1
Original line number Diff line number Diff line
@@ -17,8 +17,10 @@
package com.android.internal.telephony.dataconnection;

import android.app.PendingIntent;
import android.content.Context;
import android.telephony.Rlog;

import com.android.internal.R;
import com.android.internal.telephony.DctConstants;
import com.android.internal.telephony.Phone;

@@ -37,6 +39,8 @@ public class ApnContext {

    protected static final boolean DBG = false;

    private final Context mContext;

    private final String mApnType;

    private DctConstants.State mState;
@@ -64,7 +68,8 @@ public class ApnContext {
     */
    AtomicBoolean mDependencyMet;

    public ApnContext(String apnType, String logTag) {
    public ApnContext(Context context, String apnType, String logTag) {
        mContext = context;
        mApnType = apnType;
        mState = DctConstants.State.IDLE;
        setReason(Phone.REASON_DATA_ENABLED);
@@ -211,6 +216,16 @@ public class ApnContext {
       return mDependencyMet.get();
    }

    public boolean isProvisioningApn() {
        String provisioningApn = mContext.getResources()
                .getString(R.string.mobile_provisioning_apn);
        if (mApnSetting != null) {
            return (mApnSetting.apn.equals(provisioningApn));
        } else {
            return false;
        }
    }

    @Override
    public synchronized String toString() {
        // We don't print mDataConnection because its recursive.
+90 −15
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.internal.telephony.dataconnection;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.ActivityNotFoundException;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
@@ -38,6 +39,7 @@ import android.os.Message;
import android.os.Messenger;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.Settings;
import android.provider.Telephony;
import android.telephony.CellLocation;
@@ -53,6 +55,7 @@ import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneBase;
import com.android.internal.telephony.DctConstants;
import com.android.internal.telephony.EventLogTags;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.TelephonyProperties;
import com.android.internal.telephony.gsm.GSMPhone;
import com.android.internal.telephony.PhoneConstants;
@@ -225,7 +228,7 @@ public final class DcTracker extends DcTrackerBase {
    }

    private ApnContext addApnContext(String type) {
        ApnContext apnContext = new ApnContext(type, LOG_TAG);
        ApnContext apnContext = new ApnContext(mPhone.getContext(), type, LOG_TAG);
        apnContext.setDependencyMet(false);
        mApnContexts.put(type, apnContext);
        return apnContext;
@@ -365,6 +368,16 @@ public final class DcTracker extends DcTrackerBase {
        return DctConstants.State.FAILED;
    }

    // Return if apn type is a provisioning apn.
    @Override
    protected boolean isProvisioningApn(String apnType) {
        ApnContext apnContext = mApnContexts.get(apnType);
        if (apnContext != null) {
            return apnContext.isProvisioningApn();
        }
        return false;
    }

    // Return state of overall
    @Override
    public DctConstants.State getOverallState() {
@@ -610,7 +623,7 @@ public final class DcTracker extends DcTrackerBase {

        if (apnContext == null ){
            if (DBG) log("trySetupData new apn context for type:" + type);
            apnContext = new ApnContext(type, LOG_TAG);
            apnContext = new ApnContext(mPhone.getContext(), type, LOG_TAG);
            mApnContexts.put(type, apnContext);
        }
        apnContext.setReason(reason);
@@ -1141,18 +1154,6 @@ public final class DcTracker extends DcTrackerBase {
        if (DBG) log("onDataStateChanged(ar): X");
    }

    private void notifyDefaultData(ApnContext apnContext) {
        if (DBG) {
            log("notifyDefaultData: type=" + apnContext.getApnType()
                + ", reason:" + apnContext.getReason());
        }
        apnContext.setState(DctConstants.State.CONNECTED);
        // setState(DctConstants.State.CONNECTED);
        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
        startNetStatPoll();
        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
    }

    // TODO: For multiple Active APNs not exactly sure how to do this.
    @Override
    protected void gotoIdleAndNotifyDataConnection(String reason) {
@@ -1488,6 +1489,35 @@ public final class DcTracker extends DcTrackerBase {
        notifyOffApnsOfAvailability(null);
    }

    @Override
    protected void completeConnection(ApnContext apnContext) {
        boolean isProvApn = apnContext.isProvisioningApn();

        if (DBG) log("completeConnection: successful, notify the world apnContext=" + apnContext);

        if (mIsProvisioning && !TextUtils.isEmpty(mProvisioningUrl)) {
            if (DBG) {
                log("completeConnection: MOBILE_PROVISIONING_ACTION url="
                        + mProvisioningUrl);
            }
            Intent newIntent =
                    new Intent(Intent.ACTION_VIEW, Uri.parse(mProvisioningUrl));
            newIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |
                    Intent.FLAG_ACTIVITY_NEW_TASK);
            try {
                mPhone.getContext().startActivity(newIntent);
            } catch (ActivityNotFoundException e) {
                loge("completeConnection: startActivityAsUser failed" + e);
            }
        }
        mIsProvisioning = false;
        mProvisioningUrl = null;

        mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
        startNetStatPoll();
        startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
    }

    /**
     * A SETUP (aka bringUp) has completed, possibly with an error. If
     * there is an error this method will call {@link #onDataSetupCompleteError}.
@@ -1561,7 +1591,52 @@ public final class DcTracker extends DcTrackerBase {
                } else {
                    SystemProperties.set(PUPPET_MASTER_RADIO_STRESS_TEST, "false");
                }
                notifyDefaultData(apnContext);

                // A connection is setup
                apnContext.setState(DctConstants.State.CONNECTED);
                boolean isProvApn = apnContext.isProvisioningApn();
                if ((!isProvApn) || mIsProvisioning) {
                    // Complete the connection normally notifying the world we're connected.
                    // We do this if this isn't a special provisioning apn or if we've been
                    // told its time to provision.
                    completeConnection(apnContext);
                } else {
                    // This is a provisioning APN that we're reporting as connected. Later
                    // when the user desires to upgrade this to a "default" connection,
                    // mIsProvisioning == true, we'll go through the code path above.
                    // mIsProvisioning becomes true when CMD_ENABLE_MOBILE_PROVISIONING
                    // is sent to the DCT.
                    if (DBG) {
                        log("onDataSetupComplete: successful, BUT send connected to prov apn as"
                                + " mIsProvisioning:" + mIsProvisioning + " == false"
                                + " && (isProvisioningApn:" + isProvApn + " == true");
                    }

                    Intent intent = new Intent(
                            TelephonyIntents.ACTION_DATA_CONNECTION_CONNECTED_TO_PROVISIONING_APN);
                    intent.putExtra(PhoneConstants.DATA_APN_KEY, apnContext.getApnSetting().apn);
                    intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnContext.getApnType());

                    String apnType = apnContext.getApnType();
                    LinkProperties linkProperties = getLinkProperties(apnType);
                    if (linkProperties != null) {
                        intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties);
                        String iface = linkProperties.getInterfaceName();
                        if (iface != null) {
                            intent.putExtra(PhoneConstants.DATA_IFACE_NAME_KEY, iface);
                        }
                    }
                    LinkCapabilities linkCapabilities = getLinkCapabilities(apnType);
                    if (linkCapabilities != null) {
                        intent.putExtra(PhoneConstants.DATA_LINK_CAPABILITIES_KEY, linkCapabilities);
                    }

                    mPhone.getContext().sendBroadcastAsUser(intent, UserHandle.ALL);
                }
                if (DBG) {
                    log("onDataSetupComplete: SETUP complete type=" + apnContext.getApnType()
                        + ", reason:" + apnContext.getReason());
                }
            }
        } else {
            cause = (DcFailCause) (ar.result);
+75 −4
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.database.ContentObserver;
import android.net.ConnectivityManager;
import android.net.LinkCapabilities;
import android.net.LinkProperties;
import android.net.NetworkInfo;
@@ -49,6 +50,7 @@ import android.telephony.Rlog;

import com.android.internal.R;
import com.android.internal.telephony.DctConstants;
import com.android.internal.telephony.DctConstants.State;
import com.android.internal.telephony.EventLogTags;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneBase;
@@ -268,6 +270,14 @@ public abstract class DcTrackerBase extends Handler {

    protected ContentResolver mResolver;

    /* Set to true with CMD_ENABLE_MOBILE_PROVISIONING */
    protected boolean mIsProvisioning = false;

    /* Object parameter in CMD_ENABLE_MOBILE_PROVISIONING */
    protected String mProvisioningUrl = null;

    protected AsyncChannel mReplyAc = new AsyncChannel();

    protected BroadcastReceiver mIntentReceiver = new BroadcastReceiver ()
    {
        @Override
@@ -478,6 +488,8 @@ public abstract class DcTrackerBase extends Handler {
        sendMessage(msg);
    }

    ConnectivityManager mCm;

    /**
     * Default constructor
     */
@@ -490,6 +502,8 @@ public abstract class DcTrackerBase extends Handler {
        mUiccController.registerForIccChanged(this, DctConstants.EVENT_ICC_CHANGED, null);
        mAlarmManager =
                (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
        mCm = (ConnectivityManager) mPhone.getContext().getSystemService(
                Context.CONNECTIVITY_SERVICE);


        IntentFilter filter = new IntentFilter();
@@ -626,6 +640,7 @@ public abstract class DcTrackerBase extends Handler {
    protected abstract boolean isDataAllowed();
    protected abstract boolean isApnTypeAvailable(String type);
    public    abstract DctConstants.State getState(String apnType);
    protected abstract boolean isProvisioningApn(String apnType);
    protected abstract void setState(DctConstants.State s);
    protected abstract void gotoIdleAndNotifyDataConnection(String reason);

@@ -644,6 +659,7 @@ public abstract class DcTrackerBase extends Handler {
    protected abstract void onCleanUpAllConnections(String cause);
    public abstract boolean isDataPossible(String apnType);
    protected abstract void onUpdateIcc();
    protected abstract void completeConnection(ApnContext apnContext);

    @Override
    public void handleMessage(Message msg) {
@@ -767,9 +783,6 @@ public abstract class DcTrackerBase extends Handler {
                            + "sEnableFailFastRefCounter:" + sEnableFailFastRefCounter + " < 0";
                    loge(s);
                    sEnableFailFastRefCounter = 0;
                    if (Build.IS_DEBUGGABLE) {
                        throw new RuntimeException(s);
                    }
                }
                final boolean enabled = sEnableFailFastRefCounter > 0;
                if (DBG) {
@@ -795,6 +808,63 @@ public abstract class DcTrackerBase extends Handler {

                break;
            }
            case DctConstants.CMD_ENABLE_MOBILE_PROVISIONING: {
                // TODO: Right now we know when it ends "successfully" when
                // provisioning apn gets dropped, what happens if the user never
                // succeed, I assume there is a timeout and the network will drop
                // it after a period of time.
                Bundle bundle = msg.getData();
                if (bundle != null) {
                    try {
                        mProvisioningUrl = (String)bundle.get(DctConstants.PROVISIONING_URL_KEY);
                    } catch(ClassCastException e) {
                        loge("CMD_ENABLE_MOBILE_PROVISIONING: provisioning url not a string" + e);
                        mProvisioningUrl = null;
                    }
                }
                if (TextUtils.isEmpty(mProvisioningUrl)) {
                    loge("CMD_ENABLE_MOBILE_PROVISIONING: provisioning url is empty, ignoring");
                    mIsProvisioning = false;
                    mProvisioningUrl = null;
                } else {
                    ApnContext apnContext = mApnContexts.get(PhoneConstants.APN_TYPE_DEFAULT);
                    if (apnContext.isProvisioningApn() && apnContext.getState() == State.CONNECTED){
                        log("CMD_ENABLE_MOBILE_PROVISIONING: mIsProvisioning=true url="
                                + mProvisioningUrl);
                        mIsProvisioning = true;
                        completeConnection(mApnContexts.get(PhoneConstants.APN_TYPE_DEFAULT));                        
                    } else {
                        log("CMD_ENABLE_MOBILE_PROVISIONING: No longer connected");
                        mIsProvisioning = false;
                        mProvisioningUrl = null;
                    }
                }
                break;
            }
            case DctConstants.CMD_IS_PROVISIONING_APN: {
                if (DBG) log("CMD_IS_PROVISIONING_APN");
                boolean isProvApn;
                try {
                    String apnType = null;
                    Bundle bundle = msg.getData();
                    if (bundle != null) {
                        apnType = (String)bundle.get(DctConstants.APN_TYPE_KEY);
                    }
                    if (TextUtils.isEmpty(apnType)) {
                        loge("CMD_IS_PROVISIONING_APN: apnType is empty");
                        isProvApn = false;
                    } else {
                        isProvApn = isProvisioningApn(apnType);
                    }
                } catch (ClassCastException e) {
                    loge("CMD_IS_PROVISIONING_APN: NO provisioning url ignoring");
                    isProvApn = false;
                }
                if (DBG) log("CMD_IS_PROVISIONING_APN: ret=" + isProvApn);
                mReplyAc.replyToMessage(msg, DctConstants.CMD_IS_PROVISIONING_APN,
                        isProvApn ? DctConstants.ENABLED : DctConstants.DISABLED);
                break;
            }
            case DctConstants.EVENT_ICC_CHANGED: {
                onUpdateIcc();
                break;
@@ -989,11 +1059,12 @@ public abstract class DcTrackerBase extends Handler {
        }

        if (!isApnTypeAvailable(type)) {
            if (DBG) log("type not available");
            if (DBG) log("enableApnType: not available, type=" + type);
            return PhoneConstants.APN_TYPE_NOT_AVAILABLE;
        }

        if (isApnIdEnabled(id)) {
            if (DBG) log("enableApnType: already active, type=" + type);
            return PhoneConstants.APN_ALREADY_ACTIVE;
        } else {
            setEnabled(id, true);