diff --git a/src/com/android/phone/CallForwardEditPreference.java b/src/com/android/phone/CallForwardEditPreference.java
index bfeee7a..bdffb26 100644
--- a/src/com/android/phone/CallForwardEditPreference.java
+++ b/src/com/android/phone/CallForwardEditPreference.java
@@ -76,6 +76,11 @@
         mReplaceInvalidCFNumber = replaceInvalidCFNumber;
     }
 
+    void restoreCallForwardInfo(CallForwardInfo cf) {
+        handleCallForwardResult(cf);
+        updateSummaryText();
+    }
+
     @Override
     protected void onBindDialogView(View view) {
         // default the button clicked to be the cancel button.
@@ -100,7 +105,15 @@
             int action = (isToggled() || (mButtonClicked == DialogInterface.BUTTON_POSITIVE)) ?
                     CommandsInterface.CF_ACTION_REGISTRATION :
                     CommandsInterface.CF_ACTION_DISABLE;
-            int time = (reason != CommandsInterface.CF_REASON_NO_REPLY) ? 0 : 20;
+            int time = 0;
+            if (reason == CommandsInterface.CF_REASON_NO_REPLY) {
+                PersistableBundle carrierConfig = PhoneGlobals.getInstance()
+                        .getCarrierConfigForSubId(mPhone.getSubId());
+                if (carrierConfig.getBoolean(
+                        CarrierConfigManager.KEY_SUPPORT_NO_REPLY_TIMER_FOR_CFNRY_BOOL, true)) {
+                    time = 20;
+                }
+            }
             final String number = getPhoneNumber();
 
             Log.d(LOG_TAG, "callForwardInfo=" + callForwardInfo);
@@ -137,7 +150,7 @@
         }
     }
 
-    void handleCallForwardResult(CallForwardInfo cf) {
+    private void handleCallForwardResult(CallForwardInfo cf) {
         callForwardInfo = cf;
         Log.d(LOG_TAG, "handleGetCFResponse done, callForwardInfo=" + callForwardInfo);
         // In some cases, the network can send call forwarding URIs for voicemail that violate the
diff --git a/src/com/android/phone/GsmUmtsCallForwardOptions.java b/src/com/android/phone/GsmUmtsCallForwardOptions.java
index e562e46..6d80621 100644
--- a/src/com/android/phone/GsmUmtsCallForwardOptions.java
+++ b/src/com/android/phone/GsmUmtsCallForwardOptions.java
@@ -31,6 +31,7 @@
     private static final String KEY_TOGGLE = "toggle";
     private static final String KEY_STATUS = "status";
     private static final String KEY_NUMBER = "number";
+    private static final String KEY_ENABLE = "enable";
 
     private CallForwardEditPreference mButtonCFU;
     private CallForwardEditPreference mButtonCFB;
@@ -112,11 +113,12 @@
                 for (CallForwardEditPreference pref : mPreferences) {
                     Bundle bundle = mIcicle.getParcelable(pref.getKey());
                     pref.setToggled(bundle.getBoolean(KEY_TOGGLE));
+                    pref.setEnabled(bundle.getBoolean(KEY_ENABLE));
                     CallForwardInfo cf = new CallForwardInfo();
                     cf.number = bundle.getString(KEY_NUMBER);
                     cf.status = bundle.getInt(KEY_STATUS);
                     pref.init(this, mPhone, mReplaceInvalidCFNumbers);
-                    pref.handleCallForwardResult(cf);
+                    pref.restoreCallForwardInfo(cf);
                 }
             }
             mFirstResume = false;
@@ -131,6 +133,7 @@
         for (CallForwardEditPreference pref : mPreferences) {
             Bundle bundle = new Bundle();
             bundle.putBoolean(KEY_TOGGLE, pref.isToggled());
+            bundle.putBoolean(KEY_ENABLE, pref.isEnabled());
             if (pref.callForwardInfo != null) {
                 bundle.putString(KEY_NUMBER, pref.callForwardInfo.number);
                 bundle.putInt(KEY_STATUS, pref.callForwardInfo.status);
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index b1e061f..ba36f1b 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -62,6 +62,7 @@
 import com.android.internal.telephony.dataconnection.DataConnectionReasons;
 import com.android.internal.telephony.dataconnection.DataConnectionReasons.DataDisallowedReasonType;
 import com.android.internal.util.IndentingPrintWriter;
+import com.android.phone.anas.AlternativeNetworkAccessService;
 import com.android.phone.common.CallLogAsync;
 import com.android.phone.settings.SettingsConstants;
 import com.android.phone.vvm.CarrierVvmPackageInstalledReceiver;
@@ -333,6 +334,7 @@
             phoneMgr = PhoneInterfaceManager.init(this, PhoneFactory.getDefaultPhone());
 
             configLoader = CarrierConfigLoader.init(this);
+            AlternativeNetworkAccessService.initInstance(this);
 
             // Create the CallNotifier singleton, which handles
             // asynchronous events from the telephony layer (like
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index fd23fd2..abfa8d7 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -112,6 +112,8 @@
 import com.android.internal.telephony.RIL;
 import com.android.internal.telephony.RILConstants;
 import com.android.internal.telephony.ServiceStateTracker;
+import com.android.internal.telephony.SmsApplication;
+import com.android.internal.telephony.SmsApplication.SmsApplicationData;
 import com.android.internal.telephony.SubscriptionController;
 import com.android.internal.telephony.TelephonyPermissions;
 import com.android.internal.telephony.euicc.EuiccConnector;
@@ -135,6 +137,7 @@
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
@@ -3285,24 +3288,30 @@
         }
     }
 
-    /**
-     * Set the network selection mode to manual with the selected carrier.
+   /**
+     * Ask the radio to connect to the input network and change selection mode to manual.
+     *
+     * @param subId the id of the subscription.
+     * @param operatorInfo the operator information, included the PLMN, long name and short name of
+     * the operator to attach to.
+     * @param persistSelection whether the selection will persist until reboot. If true, only allows
+     * attaching to the selected PLMN until reboot; otherwise, attach to the chosen PLMN and resume
+     * normal network selection next time.
+     * @return {@code true} on success; {@code true} on any failure.
      */
     @Override
-    public boolean setNetworkSelectionModeManual(int subId, String operatorNumeric,
-            boolean persistSelection) {
+    public boolean setNetworkSelectionModeManual(
+            int subId, OperatorInfo operatorInfo, boolean persistSelection) {
         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
                 mApp, subId, "setNetworkSelectionModeManual");
-
         final long identity = Binder.clearCallingIdentity();
         try {
-            OperatorInfo operator = new OperatorInfo(
-                /* operatorAlphaLong */ "",
-                /* operatorAlphaShort */ "",
-                    operatorNumeric);
-            if (DBG) log("setNetworkSelectionModeManual: subId:" + subId + " operator:" + operator);
-            ManualNetworkSelectionArgument arg = new ManualNetworkSelectionArgument(operator,
+            ManualNetworkSelectionArgument arg = new ManualNetworkSelectionArgument(operatorInfo,
                     persistSelection);
+            if (DBG) {
+                log("setNetworkSelectionModeManual: subId: " + subId
+                        + " operator: " + operatorInfo);
+            }
             return (Boolean) sendRequest(CMD_SET_NETWORK_SELECTION_MODE_MANUAL, arg, subId);
         } finally {
             Binder.restoreCallingIdentity(identity);
@@ -5305,4 +5314,73 @@
             Binder.restoreCallingIdentity(identity);
         }
     }
+
+    private void ensureUserRunning(int userId) {
+        if (!mUserManager.isUserRunning(userId)) {
+            throw new IllegalStateException("User " + userId + " does not exist or not running");
+        }
+    }
+
+    /**
+     * Returns a list of SMS apps on a given user.
+     *
+     * Only the shell user (UID 2000 or 0) can call it.
+     * Target user must be running.
+     */
+    @Override
+    public String[] getSmsApps(int userId) {
+        TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "getSmsApps");
+        ensureUserRunning(userId);
+
+        final Collection<SmsApplicationData> apps =
+                SmsApplication.getApplicationCollectionAsUser(mApp, userId);
+
+        String[] ret = new String[apps.size()];
+        int i = 0;
+        for (SmsApplicationData app : apps) {
+            ret[i++] = app.mPackageName;
+        }
+        return ret;
+    }
+
+    /**
+     * Returns the default SMS app package name on a given user.
+     *
+     * Only the shell user (UID 2000 or 0) can call it.
+     * Target user must be running.
+     */
+    @Override
+    public String getDefaultSmsApp(int userId) {
+        TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "getDefaultSmsApp");
+        ensureUserRunning(userId);
+
+        final ComponentName cn = SmsApplication.getDefaultSmsApplicationAsUser(mApp,
+                /* updateIfNeeded= */ true, userId);
+        return cn == null ? null : cn.getPackageName();
+    }
+
+    /**
+     * Set a package as the default SMS app on a given user.
+     *
+     * Only the shell user (UID 2000 or 0) can call it.
+     * Target user must be running.
+     */
+    @Override
+    public void setDefaultSmsApp(int userId, String packageName) {
+        TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setDefaultSmsApp");
+        ensureUserRunning(userId);
+
+        boolean found = false;
+        for (String pkg : getSmsApps(userId)) {
+            if (TextUtils.equals(packageName, pkg)) {
+                found = true;
+                break;
+            }
+        }
+        if (!found) {
+            throw new IllegalArgumentException("Package " + packageName + " is not an SMS app");
+        }
+
+        SmsApplication.setDefaultApplicationAsUser(packageName, mApp, userId);
+    }
 }
diff --git a/src/com/android/phone/TelephonyShellCommand.java b/src/com/android/phone/TelephonyShellCommand.java
index 4acb46b..1a25ae3 100644
--- a/src/com/android/phone/TelephonyShellCommand.java
+++ b/src/com/android/phone/TelephonyShellCommand.java
@@ -18,6 +18,7 @@
 
 import android.os.RemoteException;
 import android.os.ShellCommand;
+import android.os.UserHandle;
 import android.telephony.SubscriptionManager;
 import android.util.Log;
 
@@ -39,11 +40,16 @@
     private static final int DEFAULT_PHONE_ID = 0;
 
     private static final String IMS_SUBCOMMAND = "ims";
+    private static final String SMS_SUBCOMMAND = "sms";
     private static final String IMS_SET_CARRIER_SERVICE = "set-ims-service";
     private static final String IMS_GET_CARRIER_SERVICE = "get-ims-service";
     private static final String IMS_ENABLE = "enable";
     private static final String IMS_DISABLE = "disable";
 
+    private static final String SMS_GET_APPS = "get-apps";
+    private static final String SMS_GET_DEFAULT_APP = "get-default-app";
+    private static final String SMS_SET_DEFAULT_APP = "set-default-app";
+
     // Take advantage of existing methods that already contain permissions checks when possible.
     private final ITelephony mInterface;
 
@@ -61,6 +67,9 @@
             case IMS_SUBCOMMAND: {
                 return handleImsCommand();
             }
+            case SMS_SUBCOMMAND: {
+                return handleSmsCommand();
+            }
             default: {
                 return handleDefaultCommands(cmd);
             }
@@ -75,7 +84,10 @@
         pw.println("    Print this help text.");
         pw.println("  ims");
         pw.println("    IMS Commands.");
+        pw.println("  sms");
+        pw.println("    SMS Commands.");
         onHelpIms();
+        onHelpSms();
     }
 
     private void onHelpIms() {
@@ -103,6 +115,17 @@
         pw.println("    slot if none is specified.");
     }
 
+    private void onHelpSms() {
+        PrintWriter pw = getOutPrintWriter();
+        pw.println("SMS Commands:");
+        pw.println("  sms get-apps [--user USER_ID]");
+        pw.println("    Print all SMS apps on a user.");
+        pw.println("  sms get-default-app [--user USER_ID]");
+        pw.println("    Get the default SMS app.");
+        pw.println("  sms set-default-app [--user USER_ID] PACKAGE_NAME");
+        pw.println("    Set PACKAGE_NAME as the default SMS app.");
+    }
+
     private int handleImsCommand() {
         String arg = getNextArg();
         if (arg == null) {
@@ -296,4 +319,85 @@
         }
         return slotId;
     }
+
+    private int handleSmsCommand() {
+        String arg = getNextArg();
+        if (arg == null) {
+            onHelpSms();
+            return 0;
+        }
+
+        try {
+            switch (arg) {
+                case SMS_GET_APPS: {
+                    return handleSmsGetApps();
+                }
+                case SMS_GET_DEFAULT_APP: {
+                    return handleSmsGetDefaultApp();
+                }
+                case SMS_SET_DEFAULT_APP: {
+                    return handleSmsSetDefaultApp();
+                }
+                default:
+                    getErrPrintWriter().println("Unknown command " + arg);
+            }
+        } catch (RemoteException e) {
+            getErrPrintWriter().println("RemoteException: " + e.getMessage());
+        }
+
+        return -1;
+    }
+
+    private int maybeParseUserIdArg() {
+        int userId = UserHandle.USER_SYSTEM;
+        String opt;
+        while ((opt = getNextOption()) != null) {
+            switch (opt) {
+                case "--user": {
+                    try {
+                        userId = Integer.parseInt(getNextArgRequired());
+                    } catch (NumberFormatException e) {
+                        getErrPrintWriter().println("Invalid user ID for --user");
+                        return -1;
+                    }
+                    break;
+                }
+            }
+        }
+        return userId;
+    }
+
+    private int handleSmsGetApps() throws RemoteException {
+        final int userId = maybeParseUserIdArg();
+        if (userId < 0) {
+            return -1;
+        }
+
+        for (String packageName : mInterface.getSmsApps(userId)) {
+            getOutPrintWriter().println(packageName);
+        }
+        return 0;
+    }
+
+    private int handleSmsGetDefaultApp() throws RemoteException {
+        final int userId = maybeParseUserIdArg();
+        if (userId < 0) {
+            return -1;
+        }
+
+        getOutPrintWriter().println(mInterface.getDefaultSmsApp(userId));
+        return 0;
+    }
+
+    private int handleSmsSetDefaultApp() throws RemoteException {
+        final int userId = maybeParseUserIdArg();
+        if (userId < 0) {
+            return -1;
+        }
+
+        String packageName = getNextArgRequired();
+        mInterface.setDefaultSmsApp(userId, packageName);
+        getOutPrintWriter().println("SMS app set to " + mInterface.getDefaultSmsApp(userId));
+        return 0;
+    }
 }
diff --git a/src/com/android/phone/anas/ANASNetworkScanCtlr.java b/src/com/android/phone/anas/ANASNetworkScanCtlr.java
new file mode 100644
index 0000000..6c75706
--- /dev/null
+++ b/src/com/android/phone/anas/ANASNetworkScanCtlr.java
@@ -0,0 +1,312 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone.anas;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.Message;
+import android.telephony.AccessNetworkConstants;
+import android.telephony.CellInfo;
+import android.telephony.CellInfoLte;
+import android.telephony.NetworkScan;
+import android.telephony.NetworkScanRequest;
+import android.telephony.RadioAccessSpecifier;
+import android.telephony.Rlog;
+import android.telephony.SubscriptionInfo;
+import android.telephony.TelephonyManager;
+import android.telephony.TelephonyScanManager;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Network Scan controller class which will scan for the specific bands as requested and
+ * provide results to caller when ready.
+ */
+public class ANASNetworkScanCtlr {
+    private static final String LOG_TAG = "ANASNetworkScanCtlr";
+    private static final boolean DBG = true;
+    private static final int SEARCH_PERIODICITY_SLOW = (int) TimeUnit.MINUTES.toSeconds(5);
+    private static final int SEARCH_PERIODICITY_FAST = (int) TimeUnit.MINUTES.toSeconds(1);
+    private static final int MAX_SEARCH_TIME = (int) TimeUnit.MINUTES.toSeconds(1);
+    private final Object mLock = new Object();
+
+    /* message  to handle scan responses from modem */
+    private static final int MSG_SCAN_RESULTS_AVAILABLE = 1;
+    private static final int MSG_SCAN_COMPLETE = 2;
+    private static final int MSG_SCAN_ERROR = 3;
+
+    /* scan object to keep track of current scan request */
+    private NetworkScan mCurrentScan;
+    private boolean mIsScanActive;
+    private NetworkScanRequest mCurrentScanRequest;
+    private List<String> mMccMncs;
+    private TelephonyManager mTelephonyManager;
+    @VisibleForTesting
+    protected NetworkAvailableCallBack mNetworkAvailableCallBack;
+
+    private Handler mHandler =  new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_SCAN_RESULTS_AVAILABLE:
+                    logDebug("Msg received for scan results");
+                    /* Todo: need to aggregate the results */
+                    analyzeScanResults((List<CellInfo>) msg.obj);
+                    break;
+                case MSG_SCAN_COMPLETE:
+                    logDebug("Msg received for scan complete");
+                    restartScan();
+                    break;
+                case MSG_SCAN_ERROR:
+                    logDebug("Msg received for scan error");
+                    invalidateScanOnError((int) msg.obj);
+                    break;
+                default:
+                    log("invalid message");
+                    break;
+            }
+        }
+    };
+
+    @VisibleForTesting
+    public TelephonyScanManager.NetworkScanCallback mNetworkScanCallback =
+            new TelephonyScanManager.NetworkScanCallback() {
+
+        @Override
+        public void onResults(List<CellInfo> results) {
+            logDebug("Total results :" + results.size());
+            for (CellInfo cellInfo : results) {
+                logDebug("cell info: " + cellInfo);
+            }
+
+            Message message = Message.obtain(mHandler, MSG_SCAN_RESULTS_AVAILABLE, results);
+            message.sendToTarget();
+        }
+
+        @Override
+        public void onComplete() {
+            logDebug("Scan completed!");
+            Message message = Message.obtain(mHandler, MSG_SCAN_COMPLETE, NetworkScan.SUCCESS);
+            message.sendToTarget();
+        }
+
+        @Override
+        public void onError(@NetworkScan.ScanErrorCode int error) {
+            logDebug("Scan error " + error);
+            Message message = Message.obtain(mHandler, MSG_SCAN_ERROR, error);
+            message.sendToTarget();
+        }
+    };
+
+    /**
+     * call back for network availability
+     */
+    public interface NetworkAvailableCallBack {
+
+        /**
+         * Returns the scan results to the user, this callback will be called multiple times.
+         */
+        void onNetworkAvailability(List<CellInfo> results);
+
+        /**
+         * on error
+         * @param error
+         */
+        void onError(int error);
+    }
+
+
+    /**
+     * analyze scan results
+     * @param results contains all available cells matching the scan request at current location.
+     */
+    public void analyzeScanResults(List<CellInfo> results) {
+        /* Inform registrants about availability of network */
+        if (results != null) {
+            List<CellInfo> filteredResults = new ArrayList<CellInfo>();
+            synchronized (mLock) {
+                for (CellInfo cellInfo : results) {
+                    if (mMccMncs.contains(getMccMnc(cellInfo))) {
+                        filteredResults.add(cellInfo);
+                    }
+                }
+            }
+
+            if ((filteredResults.size() >= 1) && (mNetworkAvailableCallBack != null)) {
+                /* Todo: change to aggregate results on success. */
+                mNetworkAvailableCallBack.onNetworkAvailability(filteredResults);
+            }
+        }
+    }
+
+    private void invalidateScanOnError(int error) {
+        logDebug("scan invalidated on error");
+        if (mNetworkAvailableCallBack != null) {
+            mNetworkAvailableCallBack.onError(error);
+        }
+
+        synchronized (mLock) {
+            mIsScanActive = false;
+            mCurrentScan = null;
+        }
+    }
+
+    public ANASNetworkScanCtlr(Context c, TelephonyManager telephonyManager,
+            NetworkAvailableCallBack networkAvailableCallBack) {
+        init(c, telephonyManager, networkAvailableCallBack);
+    }
+
+    /**
+     * initialize Network Scan controller
+     * @param c context
+     * @param telephonyManager Telephony manager instance
+     * @param networkAvailableCallBack callback to be called when network selection is done
+     */
+    public void init(Context c, TelephonyManager telephonyManager,
+            NetworkAvailableCallBack networkAvailableCallBack) {
+        log("init called");
+        mTelephonyManager = telephonyManager;
+        mNetworkAvailableCallBack = networkAvailableCallBack;
+    }
+
+    /* get mcc mnc from cell info if the cell is for LTE */
+    private String getMccMnc(CellInfo cellInfo) {
+        if (cellInfo instanceof CellInfoLte) {
+            return ((CellInfoLte) cellInfo).getCellIdentity().getMccString()
+                    + ((CellInfoLte) cellInfo).getCellIdentity().getMncString();
+        }
+
+        return null;
+    }
+
+    private NetworkScanRequest createNetworkScanRequest(List<SubscriptionInfo> subscriptionInfos,
+            int periodicity) {
+        RadioAccessSpecifier[] ras = new RadioAccessSpecifier[1];
+        int[] bands = new int[1];
+
+        /* hardcoding band for now, Todo b/113753823 */
+        bands[0] = AccessNetworkConstants.EutranBand.BAND_48;
+
+        ArrayList<String> mccMncs = new ArrayList<String>();
+        /* retrieve mcc mncs for a subscription id */
+        for (SubscriptionInfo subscriptionInfo : subscriptionInfos) {
+            mccMncs.add(subscriptionInfo.getMccString() + subscriptionInfo.getMncString());
+        }
+
+        /* create network scan request */
+        ras[0] = new RadioAccessSpecifier(AccessNetworkConstants.AccessNetworkType.EUTRAN, bands,
+                null);
+        NetworkScanRequest networkScanRequest = new NetworkScanRequest(
+                NetworkScanRequest.SCAN_TYPE_PERIODIC, ras, periodicity, MAX_SEARCH_TIME, false,
+                NetworkScanRequest.MAX_INCREMENTAL_PERIODICITY_SEC, mccMncs);
+        synchronized (mLock) {
+            mMccMncs = mccMncs;
+        }
+        return networkScanRequest;
+    }
+
+    /**
+     * start high interval network scan
+     * @param subscriptionInfos list of subscriptions for which the scanning needs to be started.
+     * @return true if successfully accepted request.
+     */
+    public boolean startSlowNetworkScan(List<SubscriptionInfo> subscriptionInfos) {
+        NetworkScanRequest networkScanRequest = createNetworkScanRequest(subscriptionInfos,
+                SEARCH_PERIODICITY_SLOW);
+        return startNetworkScan(networkScanRequest);
+    }
+
+    /**
+     * start less interval network scan
+     * @param subscriptionInfos list of subscriptions for which the scanning needs to be started.
+     * @return true if successfully accepted request.
+     */
+    public boolean startFastNetworkScan(List<SubscriptionInfo> subscriptionInfos) {
+        NetworkScanRequest networkScanRequest = createNetworkScanRequest(subscriptionInfos,
+                SEARCH_PERIODICITY_FAST);
+        return startNetworkScan(networkScanRequest);
+    }
+
+
+    private boolean startNetworkScan(NetworkScanRequest networkScanRequest) {
+        NetworkScan networkScan;
+        synchronized (mLock) {
+            /* if the request is same as existing one, then make sure to not proceed */
+            if (mIsScanActive && mCurrentScanRequest.equals(networkScanRequest)) {
+                return true;
+            }
+
+            /* Need to stop current scan if we already have one */
+            stopNetworkScan();
+
+            /* start new scan */
+            networkScan = mTelephonyManager.requestNetworkScan(networkScanRequest,
+                    mNetworkScanCallback);
+
+            mCurrentScan = networkScan;
+            mIsScanActive = true;
+            mCurrentScanRequest = networkScanRequest;
+        }
+
+        logDebug("startNetworkScan " + networkScanRequest);
+        return true;
+    }
+
+    private void restartScan() {
+        NetworkScan networkScan;
+        synchronized (mLock) {
+            if (mCurrentScanRequest != null) {
+                networkScan = mTelephonyManager.requestNetworkScan(mCurrentScanRequest,
+                        mNetworkScanCallback);
+                mIsScanActive = true;
+            }
+        }
+    }
+
+    /**
+     * stop network scan
+     */
+    public void stopNetworkScan() {
+        logDebug("stopNetworkScan");
+        synchronized (mLock) {
+            if (mIsScanActive && mCurrentScan != null) {
+                try {
+                    mCurrentScan.stopScan();
+                } catch (IllegalArgumentException iae) {
+                    logDebug("Scan failed with exception " + iae);
+                }
+                mIsScanActive = false;
+                mCurrentScan = null;
+                mCurrentScanRequest = null;
+            }
+        }
+    }
+
+    private static void log(String msg) {
+        Rlog.d(LOG_TAG, msg);
+    }
+
+    private static void logDebug(String msg) {
+        if (DBG) {
+            Rlog.d(LOG_TAG, msg);
+        }
+    }
+}
diff --git a/src/com/android/phone/anas/ANASProfileSelector.java b/src/com/android/phone/anas/ANASProfileSelector.java
new file mode 100644
index 0000000..d347cba
--- /dev/null
+++ b/src/com/android/phone/anas/ANASProfileSelector.java
@@ -0,0 +1,375 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone.anas;
+
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.AsyncTask;
+import android.os.Handler;
+import android.os.Message;
+import android.telephony.CellInfo;
+import android.telephony.CellInfoGsm;
+import android.telephony.CellInfoLte;
+import android.telephony.CellInfoWcdma;
+import android.telephony.Rlog;
+import android.telephony.SignalStrength;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * Profile selector class which will select the right profile based upon
+ * geographic information input and network scan results.
+ */
+public class ANASProfileSelector {
+    private static final String LOG_TAG = "ANASProfileSelector";
+    private static final boolean DBG = true;
+    private final Object mLock = new Object();
+
+    private static final int INVALID_SEQUENCE_ID = -1;
+    private static final int START_SEQUENCE_ID = 1;
+
+    /* message to indicate profile update */
+    private static final int MSG_PROFILE_UPDATE = 1;
+
+    /* message to indicate start of profile selection process */
+    private static final int MSG_START_PROFILE_SELECTION = 2;
+    private boolean mIsEnabled = false;
+
+    @VisibleForTesting
+    protected Context mContext;
+
+    @VisibleForTesting
+    protected TelephonyManager mTelephonyManager;
+
+    @VisibleForTesting
+    protected ANASNetworkScanCtlr mNetworkScanCtlr;
+
+    private SubscriptionManager mSubscriptionManager;
+    private ANASProfileSelectionCallback mProfileSelectionCallback;
+    private int mSequenceId;
+
+    /* monitor the subscription for registration */
+    private ANASServiceStateMonitor mRegMonitor;
+    public static final String ACTION_SUB_SWITCH =
+            "android.intent.action.SUBSCRIPTION_SWITCH_REPLY";
+
+    /* service monitor callback will get called for service state change on a particular subId. */
+    private ANASServiceStateMonitor.ANASServiceMonitorCallback mServiceMonitorCallback =
+            new ANASServiceStateMonitor.ANASServiceMonitorCallback() {
+                @Override
+                public void onServiceMonitorUpdate(int subId, int state) {
+                    switch (state) {
+                        case ANASServiceStateMonitor.EVALUATED_STATE_BAD:
+                            switchPreferredData(subId);
+                            break;
+                        default:
+                            break;
+                    }
+                }
+            };
+
+    private SubscriptionManager.OnOpportunisticSubscriptionsChangedListener mProfileChangeListener =
+            new SubscriptionManager.OnOpportunisticSubscriptionsChangedListener() {
+                @Override
+                public void onOpportunisticSubscriptionsChanged() {
+                    mHandler.sendEmptyMessage(MSG_PROFILE_UPDATE);
+                }
+            };
+
+    @VisibleForTesting
+    protected Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_PROFILE_UPDATE:
+                case MSG_START_PROFILE_SELECTION:
+                    logDebug("Msg received for profile update");
+                    checkProfileUpdate();
+                    break;
+                default:
+                    log("invalid message");
+                    break;
+            }
+        }
+    };
+
+    /**
+     * Broadcast receiver to receive intents
+     */
+    @VisibleForTesting
+    protected final BroadcastReceiver mProfileSelectorBroadcastReceiver =
+            new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    int sequenceId;
+                    int subId;
+                    String action = intent.getAction();
+                    if (!mIsEnabled || action == null) {
+                        return;
+                    }
+
+                    switch (action) {
+                        case ACTION_SUB_SWITCH:
+                            sequenceId = intent.getIntExtra("sequenceId",  INVALID_SEQUENCE_ID);
+                            subId = intent.getIntExtra("subId",
+                                    SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+                            if (sequenceId != mSequenceId) {
+                                return;
+                            }
+
+                            onSubSwitchComplete(subId);
+                            break;
+                    }
+                }
+            };
+
+    /**
+     * Network scan callback handler
+     */
+    @VisibleForTesting
+    protected ANASNetworkScanCtlr.NetworkAvailableCallBack mNetworkAvailableCallBack =
+            new ANASNetworkScanCtlr.NetworkAvailableCallBack() {
+                @Override
+                public void onNetworkAvailability(List<CellInfo> results) {
+                    /* sort the results according to signal strength level */
+                    Collections.sort(results, new Comparator<CellInfo>() {
+                        @Override
+                        public int compare(CellInfo cellInfo1, CellInfo cellInfo2) {
+                            return getSignalLevel(cellInfo1) - getSignalLevel(cellInfo2);
+                        }
+                    });
+
+                    /* get subscription id for the best network scan result */
+                    int subId = getSubId(getMcc(results.get(0)), getMnc(results.get(0)));
+                    if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+                        /* could not find any matching subscriptions */
+                        return;
+                    }
+
+                    /* if subscription is already active, proceed to data switch */
+                    if (mSubscriptionManager.isActiveSubId(subId)) {
+                        /* if subscription already is data subscription,
+                         complete the profile selection process */
+                        /* Todo: change to getPreferredDataSubscriptionId once ready */
+                        if (mSubscriptionManager.getDefaultDataSubscriptionId() == subId) {
+                            mProfileSelectionCallback.onProfileSelectionDone(subId,
+                                    mSubscriptionManager.getDefaultSubscriptionId());
+                        } else {
+                            switchPreferredData(subId);
+                        }
+                    } else {
+                        switchToSubscription(subId);
+                    }
+                }
+
+                @Override
+                public void onError(int error) {
+                    log("Network scan failed with error " + error);
+                }
+            };
+
+    /**
+     * interface call back to confirm profile selection
+     */
+    public interface ANASProfileSelectionCallback {
+
+        /**
+         * interface call back to confirm profile selection
+         */
+        void onProfileSelectionDone(int dataSubId, int voiceSubId);
+    }
+
+    /**
+     * ANASProfileSelector constructor
+     * @param c context
+     * @param profileSelectionCallback callback to be called once selection is done
+     */
+    public ANASProfileSelector(Context c, ANASProfileSelectionCallback profileSelectionCallback) {
+        init(c, profileSelectionCallback);
+        log("ANASProfileSelector init complete");
+    }
+
+    private int getSignalLevel(CellInfo cellInfo) {
+        if (cellInfo != null) {
+            return cellInfo.getCellSignalStrength().getLevel();
+        } else {
+            return SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+        }
+    }
+
+    private String getMcc(CellInfo cellInfo) {
+        String mcc = "";
+        if (cellInfo instanceof CellInfoGsm) {
+            mcc = ((CellInfoGsm) cellInfo).getCellIdentity().getMccString();
+        } else if (cellInfo instanceof CellInfoLte) {
+            mcc = ((CellInfoLte) cellInfo).getCellIdentity().getMccString();
+        } else if (cellInfo instanceof CellInfoWcdma) {
+            mcc = ((CellInfoWcdma) cellInfo).getCellIdentity().getMccString();
+        }
+
+        return mcc;
+    }
+
+    private String getMnc(CellInfo cellInfo) {
+        String mnc = "";
+        if (cellInfo instanceof CellInfoGsm) {
+            mnc = ((CellInfoGsm) cellInfo).getCellIdentity().getMncString();
+        } else if (cellInfo instanceof CellInfoLte) {
+            mnc = ((CellInfoLte) cellInfo).getCellIdentity().getMncString();
+        } else if (cellInfo instanceof CellInfoWcdma) {
+            mnc = ((CellInfoWcdma) cellInfo).getCellIdentity().getMncString();
+        }
+
+        return mnc;
+    }
+
+    private int getSubId(String mcc, String mnc) {
+        List<SubscriptionInfo> subscriptionInfos =
+                mSubscriptionManager.getOpportunisticSubscriptions(1);
+        for (SubscriptionInfo subscriptionInfo : subscriptionInfos) {
+            if (TextUtils.equals(subscriptionInfo.getMccString(), mcc)
+                    && TextUtils.equals(subscriptionInfo.getMncString(), mnc)) {
+                return subscriptionInfo.getSubscriptionId();
+            }
+        }
+
+        return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+    }
+
+    private void switchToSubscription(int subId) {
+        Intent callbackIntent = new Intent(ACTION_SUB_SWITCH);
+        callbackIntent.setClass(mContext, ANASProfileSelector.class);
+        callbackIntent.putExtra("sequenceId", getAndUpdateToken());
+        callbackIntent.putExtra("subId", subId);
+
+        PendingIntent replyIntent = PendingIntent.getService(mContext,
+                1, callbackIntent,
+                Intent.FILL_IN_ACTION);
+        mSubscriptionManager.switchToSubscription(subId, replyIntent);
+    }
+
+    private void switchPreferredData(int subId) {
+        mSubscriptionManager.setPreferredData(mSubscriptionManager.getSlotIndex(subId));
+        onDataSwitchComplete(subId);
+    }
+
+    private void onSubSwitchComplete(int subId) {
+        mRegMonitor.startListeningForNetworkConditionChange(subId);
+    }
+
+    private void onDataSwitchComplete(int subId) {
+        mProfileSelectionCallback.onProfileSelectionDone(subId,
+                mSubscriptionManager.getDefaultSubscriptionId());
+    }
+
+    private int getAndUpdateToken() {
+        synchronized (mLock) {
+            return mSequenceId++;
+        }
+    }
+
+    private void checkProfileUpdate() {
+        List<SubscriptionInfo> subscriptionInfos =
+                mSubscriptionManager.getOpportunisticSubscriptions(1);
+        if (subscriptionInfos == null) {
+            logDebug("received null subscription infos");
+            return;
+        }
+
+        if (subscriptionInfos.size() > 0) {
+            logDebug("opportunistic subscriptions size " + subscriptionInfos.size());
+
+            /* start scan immediately */
+            mNetworkScanCtlr.startFastNetworkScan(subscriptionInfos);
+        } else if (subscriptionInfos.size() == 0) {
+            /* check if no profile */
+            log("checkProfileUpdate 0 out");
+            mNetworkScanCtlr.stopNetworkScan();
+        }
+    }
+
+    /**
+     * start profile selection procedure
+     */
+    public void startProfileSelection() {
+        synchronized (mLock) {
+            if (!mIsEnabled) {
+                mIsEnabled = true;
+                mHandler.sendEmptyMessage(MSG_START_PROFILE_SELECTION);
+            }
+        }
+    }
+
+    /**
+     * select primary profile for data
+     */
+    public void selectPrimaryProfileForData() {
+        mSubscriptionManager.setPreferredData(mSubscriptionManager.getDefaultSubscriptionId());
+    }
+
+    /**
+     * stop profile selection procedure
+     */
+    public void stopProfileSelection() {
+        mNetworkScanCtlr.stopNetworkScan();
+        synchronized (mLock) {
+            mIsEnabled = false;
+        }
+    }
+
+    protected void init(Context c, ANASProfileSelectionCallback profileSelectionCallback) {
+        mContext = c;
+        mNetworkScanCtlr = new ANASNetworkScanCtlr(mContext, mTelephonyManager,
+                mNetworkAvailableCallBack);
+        mSequenceId = START_SEQUENCE_ID;
+        mProfileSelectionCallback = profileSelectionCallback;
+        mTelephonyManager = (TelephonyManager)
+                mContext.getSystemService(Context.TELEPHONY_SERVICE);
+        mSubscriptionManager = (SubscriptionManager)
+                mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
+        mRegMonitor = new ANASServiceStateMonitor(mContext, mServiceMonitorCallback);
+
+        /* register for profile update events */
+        mSubscriptionManager.addOnOpportunisticSubscriptionsChangedListener(
+                AsyncTask.SERIAL_EXECUTOR, mProfileChangeListener);
+
+        /* register for subscription switch intent */
+        mContext.registerReceiver(mProfileSelectorBroadcastReceiver,
+                new IntentFilter(ACTION_SUB_SWITCH));
+    }
+
+    private void log(String msg) {
+        Rlog.d(LOG_TAG, msg);
+    }
+
+    private void logDebug(String msg) {
+        if (DBG) {
+            Rlog.d(LOG_TAG, msg);
+        }
+    }
+}
diff --git a/src/com/android/phone/anas/ANASServiceStateEvaluator.java b/src/com/android/phone/anas/ANASServiceStateEvaluator.java
new file mode 100644
index 0000000..23549a4
--- /dev/null
+++ b/src/com/android/phone/anas/ANASServiceStateEvaluator.java
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone.anas;
+
+import android.app.AlarmManager;
+import android.content.Context;
+import android.os.Handler;
+import android.os.Message;
+import android.telephony.Rlog;
+import android.telephony.SubscriptionManager;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * ANASServiceStateEvaluator class which will evaluate the data service state of a subId
+ * compared to another.
+ */
+public class ANASServiceStateEvaluator {
+    private Context mContext;
+    private final Object mLock = new Object();
+    private int mOppDataSubId;
+    private int mPrimarySubId;
+    /* new opportunistic data service state */
+    private int mOppDataNewState = ANASServiceStateMonitor.EVALUATED_STATE_UNKNOWN;
+    private int mPrimaryNewState = ANASServiceStateMonitor.EVALUATED_STATE_UNKNOWN;
+    private boolean mIsWaitingForTimeout = false;
+
+    @VisibleForTesting
+    protected ANASServiceEvaluatorCallback mServiceEvaluatorCallback;
+
+    @VisibleForTesting
+    protected ANASServiceStateMonitor mOppDataSubMonitor;
+
+    @VisibleForTesting
+    protected ANASServiceStateMonitor mPrimarySubMonitor;
+
+    @VisibleForTesting
+    protected AlarmManager mAlarmManager;
+
+    private static final int WAIT_FOR_DATA_SERVICE_PERIOD = (int) TimeUnit.SECONDS.toMillis(10);
+    private static final String LOG_TAG = "ANASServiceStateEvaluator";
+    private static final boolean DBG = true;
+
+    /* message to indicate no data for WAIT_FOR_DATA_SERVICE_PERIOD */
+    private static final int MSG_WAIT_FOR_DATA_SERVICE_TIMOUT = 1;
+
+    /**
+     * call back to confirm service state evaluation
+     */
+    public interface ANASServiceEvaluatorCallback {
+
+        /**
+         * call back to confirm bad service
+         */
+        void onBadDataService();
+    }
+
+    private Handler mHandler = new Handler() {
+            @Override
+            public void handleMessage(Message msg) {
+                switch (msg.what) {
+                    case MSG_WAIT_FOR_DATA_SERVICE_TIMOUT:
+                        mIsWaitingForTimeout = false;
+                        logDebug("Msg received to get data");
+                        evaluateUpdatedState();
+                        break;
+
+                    default:
+                        log("invalid message");
+                        break;
+                }
+            }
+        };
+
+    public final AlarmManager.OnAlarmListener mDataServiceWaitTimer =
+            (AlarmManager.OnAlarmListener) () -> {
+                logDebug("Alarm fired");
+                mHandler.sendEmptyMessage(MSG_WAIT_FOR_DATA_SERVICE_TIMOUT);
+            };
+
+    /**
+     * set alarm to wait for data service
+     */
+    private void setDataServiceWaitAlarm() {
+        mAlarmManager.set(AlarmManager.RTC, System.currentTimeMillis()
+                + WAIT_FOR_DATA_SERVICE_PERIOD, LOG_TAG, mDataServiceWaitTimer, null);
+    }
+
+    /**
+     * stop the alarm
+     */
+    private void stopDataServiceWaitAlarm() {
+        mAlarmManager.cancel(mDataServiceWaitTimer);
+    }
+
+    private boolean evaluateIfBadOpportunisticDataService() {
+        /* if we have not received update on both subId, we can not take decision, yes */
+        log("evaluateIfBadOpportunisticDataService: mPrimaryNewState: "
+                + ANASServiceStateMonitor.getStateString(mPrimaryNewState) + " mOppDataNewState: "
+                + ANASServiceStateMonitor.getStateString(mOppDataNewState));
+
+        if ((mPrimaryNewState == ANASServiceStateMonitor.EVALUATED_STATE_UNKNOWN)
+                || (mOppDataNewState == ANASServiceStateMonitor.EVALUATED_STATE_UNKNOWN)) {
+            return false;
+        }
+
+        /* Evaluate if primary subscription has good service and if
+           opportunistic data subscription is not, if yes return true.
+         */
+        switch (mPrimaryNewState) {
+            case ANASServiceStateMonitor.EVALUATED_STATE_NO_SERVICE:
+                /* no need to make any change */
+                return false;
+            case ANASServiceStateMonitor.EVALUATED_STATE_BAD:
+                if ((mOppDataNewState == ANASServiceStateMonitor.EVALUATED_STATE_BAD)
+                        || (mOppDataNewState == ANASServiceStateMonitor.EVALUATED_STATE_GOOD)) {
+                    return false;
+                }
+
+                break;
+            case ANASServiceStateMonitor.EVALUATED_STATE_GOOD:
+                if (mOppDataNewState == ANASServiceStateMonitor.EVALUATED_STATE_GOOD) {
+                    return false;
+                }
+                break;
+            default:
+                log("invalid state");
+                break;
+        }
+
+        return true;
+    }
+
+    private void evaluateUpdatedState() {
+        logDebug("evaluateUpdatedState " + mIsWaitingForTimeout);
+        if (!mIsWaitingForTimeout && evaluateIfBadOpportunisticDataService()) {
+            mServiceEvaluatorCallback.onBadDataService();
+        }
+    }
+
+    /* service monitor callback will get called for service state change on a particular subId. */
+    ANASServiceStateMonitor.ANASServiceMonitorCallback mServiceMonitorCallback =
+            new ANASServiceStateMonitor.ANASServiceMonitorCallback() {
+                @Override
+                public void onServiceMonitorUpdate(int subId, int state) {
+                    logDebug("onServiceMonitorUpdate subId: " + subId + " state: "
+                            + ANASServiceStateMonitor.getStateString(state));
+                    synchronized (mLock) {
+                        if (mServiceEvaluatorCallback == null) {
+                            return;
+                        }
+
+                        if (subId == mPrimarySubId) {
+                            mPrimaryNewState = state;
+                        } else if (subId == mOppDataSubId) {
+                            mOppDataNewState = state;
+                        } else {
+                            logDebug("invalid sub id");
+                        }
+
+                        evaluateUpdatedState();
+                    }
+                }
+            };
+
+    public ANASServiceStateEvaluator(Context c,
+            ANASServiceEvaluatorCallback serviceEvaluatorCallback) {
+        init(c, serviceEvaluatorCallback);
+    }
+
+    protected void init(Context c, ANASServiceEvaluatorCallback serviceEvaluatorCallback) {
+        mContext = c;
+        mServiceEvaluatorCallback = serviceEvaluatorCallback;
+        mOppDataSubMonitor = new ANASServiceStateMonitor(mContext, mServiceMonitorCallback);
+        mPrimarySubMonitor = new ANASServiceStateMonitor(mContext, mServiceMonitorCallback);
+        mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
+    }
+
+    /**
+     * start service state evaluation for dataSubId compared to voiceSubId.
+     * This API evaluates the service state conditions of dataSubId and decides whether
+     * data service is bad compared to voiceSubId
+     * @param dataSubId current data subscription id
+     * @param voiceSubId voice subscription id
+     */
+    public void startEvaluation(int dataSubId, int voiceSubId) {
+        logDebug("Start evaluation");
+        /* make sure to clean up if there is any evaluation going on. */
+        stopEvaluation();
+        setDataServiceWaitAlarm();
+        synchronized (mLock) {
+            mIsWaitingForTimeout = true;
+            mOppDataSubId = dataSubId;
+            mPrimarySubId = voiceSubId;
+            mOppDataSubMonitor.startListeningForNetworkConditionChange(dataSubId);
+            mPrimarySubMonitor.startListeningForNetworkConditionChange(voiceSubId);
+        }
+    }
+
+    /**
+     * stop service state evaluation
+     */
+    public void stopEvaluation() {
+        logDebug("Stop evaluation");
+        synchronized (mLock) {
+            mOppDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+            mPrimarySubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+            if (mIsWaitingForTimeout) {
+                stopDataServiceWaitAlarm();
+            }
+            mIsWaitingForTimeout = false;
+            mOppDataSubMonitor.stopListeningForNetworkConditionChange();
+            mPrimarySubMonitor.stopListeningForNetworkConditionChange();
+            mOppDataNewState = ANASServiceStateMonitor.EVALUATED_STATE_UNKNOWN;
+            mPrimaryNewState = ANASServiceStateMonitor.EVALUATED_STATE_UNKNOWN;
+        }
+    }
+
+
+    private void log(String msg) {
+        Rlog.d(LOG_TAG, msg);
+    }
+
+    private void logDebug(String msg) {
+        if (DBG) {
+            Rlog.d(LOG_TAG, msg);
+        }
+    }
+}
diff --git a/src/com/android/phone/anas/ANASServiceStateMonitor.java b/src/com/android/phone/anas/ANASServiceStateMonitor.java
new file mode 100644
index 0000000..90a1564
--- /dev/null
+++ b/src/com/android/phone/anas/ANASServiceStateMonitor.java
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone.anas;
+
+import android.annotation.IntDef;
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.telephony.PhoneStateListener;
+import android.telephony.Rlog;
+import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
+import android.telephony.TelephonyManager;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * ANASServiceStateMonitor class which will monitor service state of a given subscription.
+ */
+public class ANASServiceStateMonitor {
+    @VisibleForTesting
+    protected Context mContext;
+
+    @VisibleForTesting
+    protected TelephonyManager mTelephonyManager;
+
+    @VisibleForTesting
+    protected ConnectivityManager mConnectivityManager;
+
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = {"EVALUATED_STATE_"},
+            value = {
+                    EVALUATED_STATE_UNKNOWN,
+                    EVALUATED_STATE_NO_SERVICE,
+                    EVALUATED_STATE_BAD,
+                    EVALUATED_STATE_GOOD})
+    public @interface EvaluatedState {}
+
+    /* service states to be used while reporting onServiceMonitorUpdate */
+    public static final int EVALUATED_STATE_UNKNOWN = 0;
+
+    /* network is not available */
+    public static final int EVALUATED_STATE_NO_SERVICE = 1;
+
+    /* network is available but not good */
+    public static final int EVALUATED_STATE_BAD = 2;
+
+    /* network is available and good */
+    public static final int EVALUATED_STATE_GOOD = 3;
+
+    private static final String LOG_TAG = "ANASServiceStateMonitor";
+    private static final boolean DBG = true;
+    private ANASServiceMonitorCallback mServiceMonitorCallback;
+    private PhoneStateListener mPhoneStateListener;
+    private int mSubId;
+    private @EvaluatedState int mSignalStrengthEvaluatedState;
+    private @EvaluatedState int mServiceStateEvaluatedState;
+    private final Object mLock = new Object();
+
+    protected void init(Context c, ANASServiceMonitorCallback serviceMonitorCallback) {
+        mContext = c;
+        mTelephonyManager = TelephonyManager.from(mContext);
+        mConnectivityManager = (ConnectivityManager) mContext.getSystemService(
+                Context.CONNECTIVITY_SERVICE);
+        mSignalStrengthEvaluatedState = EVALUATED_STATE_UNKNOWN;
+        mServiceStateEvaluatedState = EVALUATED_STATE_UNKNOWN;
+        mServiceMonitorCallback = serviceMonitorCallback;
+        logDebug("[ANASServiceStateMonitor] init by Context");
+    }
+
+    /**
+     * get the string name of a state
+     * @param state service state
+     * @return string name of a state
+     */
+    public static String getStateString(@EvaluatedState int state) {
+        switch (state) {
+            case EVALUATED_STATE_NO_SERVICE:
+                return "No Service";
+            case EVALUATED_STATE_BAD:
+                return "Bad Service";
+            case EVALUATED_STATE_GOOD:
+                return "Good Service";
+            default:
+                return "Unknown";
+        }
+    }
+
+    /**
+     * returns whether the fail reason is permanent
+     * @param failCause fail reason
+     * @return true if reason is permanent
+     */
+    @VisibleForTesting
+    public static boolean isFatalFailCause(String failCause) {
+        if (failCause == null || failCause.isEmpty()) {
+            return false;
+        }
+
+        switch (failCause) {
+            case "OPERATOR_BARRED":
+            case "USER_AUTHENTICATION":
+            case "ACTIVATION_REJECT_GGSN":
+            case "SERVICE_OPTION_NOT_SUPPORTED":
+            case "SERVICE_OPTION_NOT_SUBSCRIBED":
+            case "SERVICE_OPTION_OUT_OF_ORDER":
+            case "PROTOCOL_ERRORS":
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    private void updateCallbackOnFinalState() {
+        int evaluatedState = EVALUATED_STATE_UNKNOWN;
+
+        logDebug("mServiceStateEvaluatedState: " + getStateString(mServiceStateEvaluatedState)
+                + " mSignalStrengthEvaluatedState: "
+                + getStateString(mSignalStrengthEvaluatedState));
+
+        /* Service state has highest priority in this validation. If no service, no need to
+           check further. */
+        if (mServiceStateEvaluatedState == EVALUATED_STATE_GOOD) {
+            evaluatedState = EVALUATED_STATE_GOOD;
+        } else if (mServiceStateEvaluatedState == EVALUATED_STATE_NO_SERVICE) {
+            evaluatedState = EVALUATED_STATE_NO_SERVICE;
+            mServiceMonitorCallback.onServiceMonitorUpdate(mSubId, EVALUATED_STATE_NO_SERVICE);
+            return;
+        }
+
+        /* use signal strength to determine service quality only, i.e is good or bad. */
+        if (evaluatedState == EVALUATED_STATE_GOOD) {
+            if (mSignalStrengthEvaluatedState == EVALUATED_STATE_BAD) {
+                evaluatedState = EVALUATED_STATE_BAD;
+            }
+        }
+
+        if (evaluatedState != EVALUATED_STATE_UNKNOWN) {
+            mServiceMonitorCallback.onServiceMonitorUpdate(mSubId, evaluatedState);
+        }
+    }
+
+    private void analyzeSignalStrengthChange(SignalStrength signalStrength) {
+        if (mServiceMonitorCallback == null) {
+            return;
+        }
+
+        if (signalStrength.getLevel() <= SignalStrength.SIGNAL_STRENGTH_POOR) {
+            mSignalStrengthEvaluatedState = EVALUATED_STATE_BAD;
+        } else {
+            mSignalStrengthEvaluatedState = EVALUATED_STATE_GOOD;
+        }
+
+        updateCallbackOnFinalState();
+    }
+
+    private void analyzeServiceStateChange(ServiceState serviceState) {
+        logDebug("analyzeServiceStateChange state:"
+                + serviceState.getDataRegState());
+        if (mServiceMonitorCallback == null) {
+            return;
+        }
+
+        if ((serviceState.getDataRegState() == ServiceState.STATE_OUT_OF_SERVICE)
+                || (serviceState.getState() == ServiceState.STATE_EMERGENCY_ONLY)) {
+            mServiceStateEvaluatedState = EVALUATED_STATE_NO_SERVICE;
+        } else if (serviceState.getDataRegState() == ServiceState.STATE_IN_SERVICE) {
+            mServiceStateEvaluatedState = EVALUATED_STATE_GOOD;
+        }
+
+        updateCallbackOnFinalState();
+    }
+
+    /**
+     * Implements phone state listener
+     */
+    @VisibleForTesting
+    public class PhoneStateListenerImpl extends PhoneStateListener {
+        PhoneStateListenerImpl(int subId) {
+            super(subId);
+        }
+
+        private boolean shouldIgnore() {
+            if (PhoneStateListenerImpl.this.mSubId != ANASServiceStateMonitor.this.mSubId) {
+                return true;
+            }
+
+            return false;
+        }
+
+        @Override
+        public void onSignalStrengthsChanged(SignalStrength signalStrength) {
+            synchronized (mLock) {
+                if (shouldIgnore()) {
+                    return;
+                }
+
+                analyzeSignalStrengthChange(signalStrength);
+            }
+        }
+
+        @Override
+        public void onServiceStateChanged(ServiceState serviceState) {
+            synchronized (mLock) {
+                if (shouldIgnore()) {
+                    return;
+                }
+
+                analyzeServiceStateChange(serviceState);
+            }
+        }
+    };
+
+    /**
+     * get phone state listener instance
+     * @param subId subscription id
+     * @return the listener instance
+     */
+    @VisibleForTesting
+    public PhoneStateListener getPhoneStateListener(int subId) {
+        synchronized (mLock) {
+            if (mPhoneStateListener != null && subId == mSubId) {
+                return mPhoneStateListener;
+            }
+
+            mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
+            mSubId = subId;
+            mPhoneStateListener = (PhoneStateListener) new PhoneStateListenerImpl(subId);
+        }
+        return mPhoneStateListener;
+    }
+
+    /**
+     * call back interface
+     */
+    public interface ANASServiceMonitorCallback {
+        /**
+         * call back interface
+         */
+        void onServiceMonitorUpdate(int subId, @EvaluatedState int state);
+    }
+
+    /**
+     * request to start listening for network changes.
+     */
+    public void startListeningForNetworkConditionChange(int subId) {
+
+        logDebug("start network condition listen for " + subId);
+        /* monitor service state, signal strength and data connection state */
+        synchronized (mLock) {
+            int events = PhoneStateListener.LISTEN_SERVICE_STATE
+                    | PhoneStateListener.LISTEN_SIGNAL_STRENGTH;
+            mTelephonyManager.listen(getPhoneStateListener(subId), events);
+        }
+    }
+
+    /**
+     * request to stop listening for network changes.
+     */
+    public void stopListeningForNetworkConditionChange() {
+        logDebug("stop network condition listen for " + mSubId);
+        synchronized (mLock) {
+            if (mPhoneStateListener != null) {
+                mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
+            }
+            mSignalStrengthEvaluatedState = EVALUATED_STATE_UNKNOWN;
+            mServiceStateEvaluatedState = EVALUATED_STATE_UNKNOWN;
+        }
+    }
+
+    public ANASServiceStateMonitor(Context c, ANASServiceMonitorCallback serviceMonitorCallback) {
+        init(c, serviceMonitorCallback);
+    }
+
+    private static void log(String msg) {
+        Rlog.d(LOG_TAG, msg);
+    }
+
+    private static void logDebug(String msg) {
+        if (DBG) {
+            Rlog.d(LOG_TAG, msg);
+        }
+    }
+}
diff --git a/src/com/android/phone/anas/AlternativeNetworkAccessService.java b/src/com/android/phone/anas/AlternativeNetworkAccessService.java
new file mode 100644
index 0000000..b972813
--- /dev/null
+++ b/src/com/android/phone/anas/AlternativeNetworkAccessService.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone.anas;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.os.Binder;
+import android.os.ServiceManager;
+import android.telephony.Rlog;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.IAnas;
+import com.android.internal.telephony.TelephonyPermissions;
+
+/**
+ * AlternativeNetworkAccessService implements ianas.
+ * It scans network and matches the results with opportunistic subscriptions.
+ * Use the same to provide user opportunistic data in areas with corresponding networks
+ */
+public class AlternativeNetworkAccessService extends IAnas.Stub {
+    private Context mContext;
+    private TelephonyManager mTelephonyManager;
+    private SubscriptionManager mSubsriptionManager;
+
+    private final Object mLock = new Object();
+    private boolean mIsEnabled;
+    private ANASProfileSelector mProfileSelector;
+    private ANASServiceStateEvaluator mServiceStateEvaluator;
+    private SharedPreferences mSharedPref;
+
+    /** The singleton instance. */
+    private static AlternativeNetworkAccessService sInstance = null;
+    private static final String TAG = "ANAS";
+    private static final String PREF_NAME = TAG;
+    private static final String PREF_ENABLED = "isEnabled";
+    private static final boolean DBG = true;
+
+    /**
+     * Profile selection callback. Will be called once Profile selector decides on
+     * the opportunistic data profile.
+     */
+    private ANASProfileSelector.ANASProfileSelectionCallback  mProfileSelectionCallback =
+            new ANASProfileSelector.ANASProfileSelectionCallback() {
+
+                @Override
+                public void onProfileSelectionDone(int dataSubId, int voiceSubId) {
+                    logDebug("profile selection done");
+                    mProfileSelector.stopProfileSelection();
+                    mServiceStateEvaluator.startEvaluation(dataSubId, voiceSubId);
+                }
+            };
+
+    /**
+     * Service state evaluator callback. Will be called once service state evaluator thinks
+     * that current opportunistic data is not providing good service.
+     */
+    private ANASServiceStateEvaluator.ANASServiceEvaluatorCallback mServiceEvaluatorCallback =
+            new ANASServiceStateEvaluator.ANASServiceEvaluatorCallback() {
+                @Override
+                public void onBadDataService() {
+                    logDebug("Bad opportunistic data service");
+                    mServiceStateEvaluator.stopEvaluation();
+                    mProfileSelector.selectPrimaryProfileForData();
+                    mProfileSelector.startProfileSelection();
+                }
+            };
+
+    /**
+     * create AlternativeNetworkAccessService instance
+     *
+     * @param c context
+     *
+     */
+    public static void initInstance(Context c) {
+        if (sInstance == null) {
+            sInstance = new AlternativeNetworkAccessService(c);
+        }
+        return;
+    }
+
+    /**
+     * get AlternativeNetworkAccessService instance
+     *
+     */
+    @VisibleForTesting
+    public static AlternativeNetworkAccessService getInstance() {
+        if (sInstance == null) {
+            Log.wtf(TAG, "getInstance null");
+        }
+        return sInstance;
+    }
+
+    /**
+     * Enable or disable Alternative Network Access service.
+     *
+     * This method should be called to enable or disable
+     * AlternativeNetworkAccess service on the device.
+     *
+     * <p>
+     * Requires Permission:
+     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
+     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
+     *
+     * @param enable enable(True) or disable(False)
+     * @param callingPackage caller's package name
+     * @return returns true if successfully set.
+     */
+    @Override
+    public boolean setEnable(boolean enable, String callingPackage) {
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mContext, mSubsriptionManager.getDefaultSubscriptionId(), "setEnable");
+        log("setEnable: " + enable);
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            enableAlternativeNetworkAccess(enable);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+
+        return true;
+    }
+
+    /**
+     * is Alternative Network Access service enabled
+     *
+     * This method should be called to determine if the Alternative Network Access service
+     * is enabled
+     *
+     * <p>
+     * Requires Permission:
+     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
+     *
+     * @param callingPackage caller's package name
+     */
+    @Override
+    public boolean isEnabled(String callingPackage) {
+        TelephonyPermissions.enforeceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege(
+                mContext, mSubsriptionManager.getDefaultSubscriptionId(), "isEnabled");
+        return mIsEnabled;
+    }
+
+    /**
+     * initialize ANAS and register as service.
+     * Read persistent state to update enable state
+     * Start sub components if already enabled.
+     * @param context context instance
+     */
+    private void initializeAndRegisterAsService(Context context) {
+        mContext = context;
+        mTelephonyManager = TelephonyManager.from(mContext);
+        mServiceStateEvaluator = new ANASServiceStateEvaluator(mContext, mServiceEvaluatorCallback);
+        mProfileSelector = new ANASProfileSelector(mContext, mProfileSelectionCallback);
+        mSharedPref = mContext.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
+        mSubsriptionManager = (SubscriptionManager) mContext.getSystemService(
+                Context.TELEPHONY_SUBSCRIPTION_SERVICE);
+
+        /* register the service */
+        if (ServiceManager.getService("ianas") == null) {
+            ServiceManager.addService("ianas", this);
+        }
+
+        enableAlternativeNetworkAccess(getPersistentEnableState());
+    }
+
+    private AlternativeNetworkAccessService(Context c) {
+        initializeAndRegisterAsService(c);
+        log("init completed");
+    }
+
+    private boolean getPersistentEnableState() {
+        return mSharedPref.getBoolean(PREF_ENABLED, true);
+    }
+
+    private void updateEnableState(boolean enable) {
+        mIsEnabled = enable;
+        mSharedPref.edit().putBoolean(PREF_ENABLED, mIsEnabled).apply();
+    }
+
+    /**
+     * update the enable state
+     * start profile selection if enabled.
+     * @param enable enable(true) or disable(false)
+     */
+    private void enableAlternativeNetworkAccess(boolean enable) {
+        synchronized (mLock) {
+            if (mIsEnabled != enable) {
+                updateEnableState(enable);
+                if (mIsEnabled) {
+                    mProfileSelector.startProfileSelection();
+                } else {
+                    mProfileSelector.stopProfileSelection();
+                }
+            }
+        }
+        logDebug("service is enable state " + mIsEnabled);
+    }
+
+    private void log(String msg) {
+        Rlog.d(TAG, msg);
+    }
+
+    private void logDebug(String msg) {
+        if (DBG) Rlog.d(TAG, msg);
+    }
+}
diff --git a/src/com/android/services/telephony/CdmaConferenceController.java b/src/com/android/services/telephony/CdmaConferenceController.java
index 24c3870..5d987f7 100644
--- a/src/com/android/services/telephony/CdmaConferenceController.java
+++ b/src/com/android/services/telephony/CdmaConferenceController.java
@@ -211,6 +211,7 @@
             // 4) Add the conference to the connection service if it is new.
             if (isNewlyCreated) {
                 Log.d(this, "Adding the conference call");
+                mConference.updateCallRadioTechAfterCreation();
                 mConnectionService.addConference(mConference);
             }
         } else if (conferenceConnections.isEmpty()) {
diff --git a/src/com/android/services/telephony/ImsConference.java b/src/com/android/services/telephony/ImsConference.java
index b196d57..5722834 100644
--- a/src/com/android/services/telephony/ImsConference.java
+++ b/src/com/android/services/telephony/ImsConference.java
@@ -640,6 +640,7 @@
 
         setState(mConferenceHost.getState());
         updateStatusHints();
+        putExtras(mConferenceHost.getExtras());
     }
 
     /**
diff --git a/src/com/android/services/telephony/TelephonyConferenceController.java b/src/com/android/services/telephony/TelephonyConferenceController.java
index e96815c..e9eef46 100644
--- a/src/com/android/services/telephony/TelephonyConferenceController.java
+++ b/src/com/android/services/telephony/TelephonyConferenceController.java
@@ -264,6 +264,7 @@
                                 mTelephonyConference, connection);
                         mTelephonyConference.addConnection(connection);
                     }
+                    mTelephonyConference.updateCallRadioTechAfterCreation();
                     mConnectionService.addConference(mTelephonyConference);
                 } else {
                     Log.d(this, "Trigger recalculate later");
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index 31fe68f..7d25767 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -36,6 +36,7 @@
 import android.telephony.CarrierConfigManager;
 import android.telephony.DisconnectCause;
 import android.telephony.PhoneNumberUtils;
+import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
 import android.telephony.ims.ImsCallProfile;
 import android.text.TextUtils;
@@ -96,6 +97,7 @@
     private static final int MSG_CDMA_VOICE_PRIVACY_ON = 15;
     private static final int MSG_CDMA_VOICE_PRIVACY_OFF = 16;
     private static final int MSG_HANGUP = 17;
+    private static final int MSG_SET_CALL_RADIO_TECH = 18;
 
     private final Handler mHandler = new Handler(Looper.getMainLooper()) {
         @Override
@@ -240,6 +242,31 @@
                     int cause = (int) msg.obj;
                     hangup(cause);
                     break;
+
+                case MSG_SET_CALL_RADIO_TECH:
+                    int vrat = (int) msg.obj;
+                    // Check whether Wi-Fi call tech is changed, it means call radio tech is:
+                    //  a) changed from IWLAN to other value, or
+                    //  b) changed from other value to IWLAN.
+                    //
+                    // In other word, below conditions are all met:
+                    // 1) {@link #getCallRadioTech} is different from new vrat
+                    // 2) Current call radio technology indicates Wi-Fi call, i.e. {@link #isWifi}
+                    //    is true, or new vrat indicates Wi-Fi call.
+                    boolean isWifiTechChange = getCallRadioTech() != vrat
+                            && (isWifi() || vrat == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN);
+
+                    // Step 1) Updates call radio tech firstly, so that afterwards Wi-Fi related
+                    // update actions are taken correctly.
+                    setCallRadioTech(vrat);
+
+                    // Step 2) Handles Wi-Fi call tech change.
+                    if (isWifiTechChange) {
+                        updateConnectionProperties();
+                        updateStatusHints();
+                        refreshDisableAddCall();
+                    }
+                    break;
             }
         }
     };
@@ -421,14 +448,14 @@
         }
 
         /**
-         * Used by {@link com.android.internal.telephony.Connection} to report a change in whether
-         * the call is being made over a wifi network.
+         * Used by {@link com.android.internal.telephony.Connection} to report a change for
+         * the call radio technology.
          *
-         * @param isWifi True if call is made over wifi.
+         * @param vrat the RIL Voice Radio Technology used for current connection.
          */
         @Override
-        public void onWifiChanged(boolean isWifi) {
-            setWifi(isWifi);
+        public void onCallRadioTechChanged(@ServiceState.RilRadioTechnology int vrat) {
+            mHandler.obtainMessage(MSG_SET_CALL_RADIO_TECH, vrat).sendToTarget();
         }
 
         /**
@@ -599,13 +626,6 @@
     private int mOriginalConnectionCapabilities;
 
     /**
-     * Determines if the {@link TelephonyConnection} is using wifi.
-     * This is used when {@link TelephonyConnection#updateConnectionProperties()} is called to
-     * indicate whether a call has the {@link Connection#PROPERTY_WIFI} property.
-     */
-    private boolean mIsWifi;
-
-    /**
      * Determines the audio quality is high for the {@link TelephonyConnection}.
      * This is used when {@link TelephonyConnection#updateConnectionProperties}} is called to
      * indicate whether a call has the {@link Connection#PROPERTY_HIGH_DEF_AUDIO} property.
@@ -1030,7 +1050,7 @@
 
         newProperties = changeBitmask(newProperties, PROPERTY_HIGH_DEF_AUDIO,
                 hasHighDefAudioProperty());
-        newProperties = changeBitmask(newProperties, PROPERTY_WIFI, mIsWifi);
+        newProperties = changeBitmask(newProperties, PROPERTY_WIFI, isWifi());
         newProperties = changeBitmask(newProperties, PROPERTY_IS_EXTERNAL_CALL,
                 isExternalConnection());
         newProperties = changeBitmask(newProperties, PROPERTY_HAS_CDMA_VOICE_PRIVACY,
@@ -1117,12 +1137,13 @@
         // Set video state and capabilities
         setVideoState(mOriginalConnection.getVideoState());
         setOriginalConnectionCapabilities(mOriginalConnection.getConnectionCapabilities());
-        setWifi(mOriginalConnection.isWifi());
         setAudioModeIsVoip(mOriginalConnection.getAudioModeIsVoip());
         setVideoProvider(mOriginalConnection.getVideoProvider());
         setAudioQuality(mOriginalConnection.getAudioQuality());
         setTechnologyTypeExtra();
 
+        setCallRadioTech(mOriginalConnection.getCallRadioTech());
+
         // Post update of extras to the handler; extras are updated via the handler to ensure thread
         // safety. The Extras Bundle is cloned in case the original extras are modified while they
         // are being added to mOriginalConnectionExtras in updateExtras.
@@ -1239,7 +1260,7 @@
 
         if (isCurrentVideoCall) {
             return true;
-        } else if (wasVideoCall && mIsWifi && !isVowifiEnabled) {
+        } else if (wasVideoCall && isWifi() && !isVowifiEnabled) {
             return true;
         }
         return false;
@@ -1274,7 +1295,7 @@
             return false;
         }
 
-        if (mIsWifi && !canWifiCallsBeHdAudio) {
+        if (isWifi() && !canWifiCallsBeHdAudio) {
             return false;
         }
 
@@ -1831,21 +1852,10 @@
     }
 
     /**
-     * Sets whether the call is using wifi. Used when rebuilding the capabilities to set or unset
-     * the {@link Connection#PROPERTY_WIFI} property.
-     */
-    public void setWifi(boolean isWifi) {
-        mIsWifi = isWifi;
-        updateConnectionProperties();
-        updateStatusHints();
-        refreshDisableAddCall();
-    }
-
-    /**
      * Whether the call is using wifi.
      */
     boolean isWifi() {
-        return mIsWifi;
+        return getCallRadioTech() == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN;
     }
 
     /**
@@ -2025,7 +2035,7 @@
     }
 
     private void updateStatusHints() {
-        if (mIsWifi && getPhone() != null) {
+        if (isWifi() && getPhone() != null) {
             int labelId = isValidRingingCall()
                     ? R.string.status_hint_label_incoming_wifi_call
                     : R.string.status_hint_label_wifi_call;
