16bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt/*
26bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt* Copyright (C) 2015 The Android Open Source Project
36bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt*
46bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt* Licensed under the Apache License, Version 2.0 (the "License");
56bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt* you may not use this file except in compliance with the License.
66bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt* You may obtain a copy of the License at
76bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt*
86bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt*      http://www.apache.org/licenses/LICENSE-2.0
96bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt*
106bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt* Unless required by applicable law or agreed to in writing, software
116bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt* distributed under the License is distributed on an "AS IS" BASIS,
126bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt* See the License for the specific language governing permissions and
146bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt* limitations under the License.
156bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt*/
166bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
176bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwaltpackage com.android.internal.telephony;
186bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
196bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwaltimport static android.telephony.SubscriptionManager.INVALID_PHONE_INDEX;
206bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwaltimport static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
216bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
226bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwaltimport android.content.BroadcastReceiver;
236bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwaltimport android.content.Context;
246bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwaltimport android.content.Intent;
256bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwaltimport android.content.IntentFilter;
26b24093047930443f067628be575f3da743294ff3Lorenzo Colittiimport android.net.MatchAllNetworkSpecifier;
276bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwaltimport android.net.NetworkCapabilities;
286bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwaltimport android.net.NetworkFactory;
296bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwaltimport android.net.NetworkRequest;
30b24093047930443f067628be575f3da743294ff3Lorenzo Colittiimport android.net.NetworkSpecifier;
31b24093047930443f067628be575f3da743294ff3Lorenzo Colittiimport android.net.StringNetworkSpecifier;
326bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwaltimport android.os.Handler;
336bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwaltimport android.os.Looper;
346bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwaltimport android.os.Message;
356bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwaltimport android.os.Registrant;
366bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwaltimport android.os.RegistrantList;
376bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwaltimport android.os.RemoteException;
386bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwaltimport android.telephony.Rlog;
396bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwaltimport android.util.LocalLog;
406bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
41e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwaltimport com.android.internal.annotations.VisibleForTesting;
426bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwaltimport com.android.internal.telephony.dataconnection.DcRequest;
436bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwaltimport com.android.internal.util.IndentingPrintWriter;
446bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
456bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwaltimport java.io.FileDescriptor;
466bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwaltimport java.io.PrintWriter;
476bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwaltimport java.util.ArrayList;
486bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwaltimport java.util.Calendar;
496bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwaltimport java.util.Collections;
506bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwaltimport java.util.List;
516bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
526bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt/**
536bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt * Utility singleton to monitor subscription changes and incoming NetworkRequests
546bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt * and determine which phone/phones are active.
556bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt *
566bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt * Manages the ALLOW_DATA calls to modems and notifies phones about changes to
576bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt * the active phones.  Note we don't wait for data attach (which may not happen anyway).
586bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt */
596bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwaltpublic class PhoneSwitcher extends Handler {
606bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private final static String LOG_TAG = "PhoneSwitcher";
616bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private final static boolean VDBG = false;
626bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
636bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private final int mMaxActivePhones;
646bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private final List<DcRequest> mPrioritizedDcRequests = new ArrayList<DcRequest>();
656bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private final RegistrantList[] mActivePhoneRegistrants;
666bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private final SubscriptionController mSubscriptionController;
676bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private final int[] mPhoneSubscriptions;
686bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private final CommandsInterface[] mCommandsInterfaces;
696bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private final Context mContext;
706bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private final PhoneState[] mPhoneStates;
716bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private final int mNumPhones;
726bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private final Phone[] mPhones;
736bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private final LocalLog mLocalLog;
746bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
756bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private int mDefaultDataSubscription;
766bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
776bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private final static int EVENT_DEFAULT_SUBSCRIPTION_CHANGED = 101;
786bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private final static int EVENT_SUBSCRIPTION_CHANGED         = 102;
796bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private final static int EVENT_REQUEST_NETWORK              = 103;
806bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private final static int EVENT_RELEASE_NETWORK              = 104;
816bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private final static int EVENT_EMERGENCY_TOGGLE             = 105;
82e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwalt    private final static int EVENT_RESEND_DATA_ALLOWED          = 106;
836bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
846bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private final static int MAX_LOCAL_LOG_LINES = 30;
856bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
86e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwalt    @VisibleForTesting
87e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwalt    public PhoneSwitcher(Looper looper) {
88e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwalt        super(looper);
89e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwalt        mMaxActivePhones = 0;
90e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwalt        mSubscriptionController = null;
91e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwalt        mPhoneSubscriptions = null;
92e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwalt        mCommandsInterfaces = null;
93e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwalt        mContext = null;
94e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwalt        mPhoneStates = null;
95e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwalt        mPhones = null;
96e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwalt        mLocalLog = null;
97e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwalt        mActivePhoneRegistrants = null;
98e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwalt        mNumPhones = 0;
99e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwalt    }
100e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwalt
1016bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    public PhoneSwitcher(int maxActivePhones, int numPhones, Context context,
1026bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            SubscriptionController subscriptionController, Looper looper, ITelephonyRegistry tr,
1036bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            CommandsInterface[] cis, Phone[] phones) {
1046bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        super(looper);
1056bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        mContext = context;
1066bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        mNumPhones = numPhones;
1076bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        mPhones = phones;
1086bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        mPhoneSubscriptions = new int[numPhones];
1096bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        mMaxActivePhones = maxActivePhones;
1106bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        mLocalLog = new LocalLog(MAX_LOCAL_LOG_LINES);
1116bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
1126bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        mSubscriptionController = subscriptionController;
1136bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
1146bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        mActivePhoneRegistrants = new RegistrantList[numPhones];
1156bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        mPhoneStates = new PhoneState[numPhones];
1166bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        for (int i = 0; i < numPhones; i++) {
1176bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            mActivePhoneRegistrants[i] = new RegistrantList();
1186bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            mPhoneStates[i] = new PhoneState();
1196bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            if (mPhones[i] != null) {
1206bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                mPhones[i].registerForEmergencyCallToggle(this, EVENT_EMERGENCY_TOGGLE, null);
1216bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            }
1226bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        }
1236bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
1246bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        mCommandsInterfaces = cis;
1256bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
1266bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        try {
127dfe03ae02975c71aba045b826b36f5d2815ba6d5Hall Liu            tr.addOnSubscriptionsChangedListener(context.getOpPackageName(),
128dfe03ae02975c71aba045b826b36f5d2815ba6d5Hall Liu                    mSubscriptionsChangedListener);
1296bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        } catch (RemoteException e) {
1306bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        }
1316bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
1326bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        mContext.registerReceiver(mDefaultDataChangedReceiver,
1336bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                new IntentFilter(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED));
1346bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
1356bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        NetworkCapabilities netCap = new NetworkCapabilities();
1366bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        netCap.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
1376bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS);
1386bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL);
1396bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_DUN);
1406bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_FOTA);
1416bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
1426bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_CBS);
1436bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_IA);
1446bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_RCS);
1456bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_XCAP);
1466bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS);
1476bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
1486bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
149b24093047930443f067628be575f3da743294ff3Lorenzo Colitti        netCap.setNetworkSpecifier(new MatchAllNetworkSpecifier());
1506bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
1516bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        NetworkFactory networkFactory = new PhoneSwitcherNetworkRequestListener(looper, context,
1526bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                netCap, this);
1533baedf2ead743a2c67dcac03733cec52bcef5636Robert Greenwalt        // we want to see all requests
1543baedf2ead743a2c67dcac03733cec52bcef5636Robert Greenwalt        networkFactory.setScoreFilter(101);
1556bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        networkFactory.register();
1566bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
1576bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        log("PhoneSwitcher started");
1586bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    }
1596bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
1606bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private final BroadcastReceiver mDefaultDataChangedReceiver = new BroadcastReceiver() {
1616bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        @Override
1626bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        public void onReceive(Context context, Intent intent) {
1636bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            Message msg = PhoneSwitcher.this.obtainMessage(EVENT_DEFAULT_SUBSCRIPTION_CHANGED);
1646bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            msg.sendToTarget();
1656bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        }
1666bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    };
1676bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
1686bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private final IOnSubscriptionsChangedListener mSubscriptionsChangedListener =
1696bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            new IOnSubscriptionsChangedListener.Stub() {
1706bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        @Override
1716bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        public void onSubscriptionsChanged() {
1726bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            Message msg = PhoneSwitcher.this.obtainMessage(EVENT_SUBSCRIPTION_CHANGED);
1736bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            msg.sendToTarget();
1746bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        }
1756bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    };
1766bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
1776bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    @Override
1786bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    public void handleMessage(Message msg) {
1796bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        switch (msg.what) {
1806bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            case EVENT_SUBSCRIPTION_CHANGED: {
1816bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                onEvaluate(REQUESTS_UNCHANGED, "subChanged");
1826bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                break;
1836bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            }
1846bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            case EVENT_DEFAULT_SUBSCRIPTION_CHANGED: {
1856bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                onEvaluate(REQUESTS_UNCHANGED, "defaultChanged");
1866bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                break;
1876bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            }
1886bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            case EVENT_REQUEST_NETWORK: {
1896bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                onRequestNetwork((NetworkRequest)msg.obj);
1906bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                break;
1916bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            }
1926bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            case EVENT_RELEASE_NETWORK: {
1936bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                onReleaseNetwork((NetworkRequest)msg.obj);
1946bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                break;
1956bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            }
1966bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            case EVENT_EMERGENCY_TOGGLE: {
1976bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                onEvaluate(REQUESTS_CHANGED, "emergencyToggle");
1986bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                break;
1996bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            }
200e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwalt            case EVENT_RESEND_DATA_ALLOWED: {
201e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwalt                onResendDataAllowed(msg);
202e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwalt                break;
203e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwalt            }
2046bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        }
2056bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    }
2066bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
2076bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private boolean isEmergency() {
2086bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        for (Phone p : mPhones) {
2096bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            if (p == null) continue;
2106bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            if (p.isInEcm() || p.isInEmergencyCall()) return true;
2116bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        }
2126bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        return false;
2136bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    }
2146bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
2156bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private static class PhoneSwitcherNetworkRequestListener extends NetworkFactory {
2166bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        private final PhoneSwitcher mPhoneSwitcher;
2176bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        public PhoneSwitcherNetworkRequestListener (Looper l, Context c,
2186bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                NetworkCapabilities nc, PhoneSwitcher ps) {
2196bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            super(l, c, "PhoneSwitcherNetworkRequstListener", nc);
2206bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            mPhoneSwitcher = ps;
2216bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        }
2226bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
2236bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        @Override
2246bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        protected void needNetworkFor(NetworkRequest networkRequest, int score) {
2253baedf2ead743a2c67dcac03733cec52bcef5636Robert Greenwalt            if (VDBG) log("needNetworkFor " + networkRequest + ", " + score);
2266bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            Message msg = mPhoneSwitcher.obtainMessage(EVENT_REQUEST_NETWORK);
2276bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            msg.obj = networkRequest;
2286bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            msg.sendToTarget();
2296bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        }
2306bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
2316bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        @Override
2326bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        protected void releaseNetworkFor(NetworkRequest networkRequest) {
2333baedf2ead743a2c67dcac03733cec52bcef5636Robert Greenwalt            if (VDBG) log("releaseNetworkFor " + networkRequest);
2346bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            Message msg = mPhoneSwitcher.obtainMessage(EVENT_RELEASE_NETWORK);
2356bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            msg.obj = networkRequest;
2366bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            msg.sendToTarget();
2376bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        }
2386bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    }
2396bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
2406bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private void onRequestNetwork(NetworkRequest networkRequest) {
2416bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        final DcRequest dcRequest = new DcRequest(networkRequest, mContext);
2426bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        if (mPrioritizedDcRequests.contains(dcRequest) == false) {
2436bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            mPrioritizedDcRequests.add(dcRequest);
2446bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            Collections.sort(mPrioritizedDcRequests);
2456bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            onEvaluate(REQUESTS_CHANGED, "netRequest");
2466bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        }
2476bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    }
2486bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
2496bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private void onReleaseNetwork(NetworkRequest networkRequest) {
2506bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        final DcRequest dcRequest = new DcRequest(networkRequest, mContext);
2516bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
2526bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        if (mPrioritizedDcRequests.remove(dcRequest)) {
2536bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            onEvaluate(REQUESTS_CHANGED, "netReleased");
2546bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        }
2556bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    }
2566bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
2576bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private static final boolean REQUESTS_CHANGED   = true;
2586bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private static final boolean REQUESTS_UNCHANGED = false;
2596bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    /**
2606bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt     * Re-evaluate things.
2616bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt     * Do nothing if nothing's changed.
2626bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt     *
2636bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt     * Otherwise, go through the requests in priority order adding their phone
2646bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt     * until we've added up to the max allowed.  Then go through shutting down
2656bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt     * phones that aren't in the active phone list.  Finally, activate all
2666bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt     * phones in the active phone list.
2676bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt     */
26887c2958ce9e74b35ca6ef36f0b5caaaac8d5b008Robert Greenwalt    private void onEvaluate(boolean requestsChanged, String reason) {
26987c2958ce9e74b35ca6ef36f0b5caaaac8d5b008Robert Greenwalt        StringBuilder sb = new StringBuilder(reason);
2706bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        if (isEmergency()) {
2716bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            log("onEvalute aborted due to Emergency");
2726bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            return;
2736bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        }
2746bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
2756bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        boolean diffDetected = requestsChanged;
2766bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        final int dataSub = mSubscriptionController.getDefaultDataSubId();
2776bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        if (dataSub != mDefaultDataSubscription) {
27887c2958ce9e74b35ca6ef36f0b5caaaac8d5b008Robert Greenwalt            sb.append(" default ").append(mDefaultDataSubscription).append("->").append(dataSub);
2796bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            mDefaultDataSubscription = dataSub;
2806bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            diffDetected = true;
28187c2958ce9e74b35ca6ef36f0b5caaaac8d5b008Robert Greenwalt
2826bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        }
2836bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
2846bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        for (int i = 0; i < mNumPhones; i++) {
2856bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            int sub = mSubscriptionController.getSubIdUsingPhoneId(i);
2866bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            if (sub != mPhoneSubscriptions[i]) {
28787c2958ce9e74b35ca6ef36f0b5caaaac8d5b008Robert Greenwalt                sb.append(" phone[").append(i).append("] ").append(mPhoneSubscriptions[i]);
28887c2958ce9e74b35ca6ef36f0b5caaaac8d5b008Robert Greenwalt                sb.append("->").append(sub);
2896bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                mPhoneSubscriptions[i] = sub;
2906bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                diffDetected = true;
2916bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            }
2926bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        }
2936bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
2946bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        if (diffDetected) {
29587c2958ce9e74b35ca6ef36f0b5caaaac8d5b008Robert Greenwalt            log("evaluating due to " + sb.toString());
2966bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
2976bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            List<Integer> newActivePhones = new ArrayList<Integer>();
2986bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
2996bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            for (DcRequest dcRequest : mPrioritizedDcRequests) {
3006bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                int phoneIdForRequest = phoneIdForRequest(dcRequest.networkRequest);
3016bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                if (phoneIdForRequest == INVALID_PHONE_INDEX) continue;
3026bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                if (newActivePhones.contains(phoneIdForRequest)) continue;
3036bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                newActivePhones.add(phoneIdForRequest);
3046bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                if (newActivePhones.size() >= mMaxActivePhones) break;
3056bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            }
3066bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
3076bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            if (VDBG) {
3086bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                log("default subId = " + mDefaultDataSubscription);
3096bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                for (int i = 0; i < mNumPhones; i++) {
3106bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                    log(" phone[" + i + "] using sub[" + mPhoneSubscriptions[i] + "]");
3116bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                }
3126bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                log(" newActivePhones:");
3136bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                for (Integer i : newActivePhones) log("  " + i);
3146bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            }
3156bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
3166bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            for (int phoneId = 0; phoneId < mNumPhones; phoneId++) {
3176bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                if (newActivePhones.contains(phoneId) == false) {
3186bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                    deactivate(phoneId);
3196bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                }
3206bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            }
3216bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
3226bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            // only activate phones up to the limit
3236bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            for (int phoneId : newActivePhones) {
3246bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                activate(phoneId);
3256bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            }
3266bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        }
3276bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    }
3286bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
3296bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private static class PhoneState {
3306bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        public volatile boolean active = false;
3316bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        public long lastRequested = 0;
3326bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    }
3336bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
3346bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private void deactivate(int phoneId) {
3356bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        PhoneState state = mPhoneStates[phoneId];
3366bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        if (state.active == false) return;
3376bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        state.active = false;
3386bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        log("deactivate " + phoneId);
3396bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        state.lastRequested = System.currentTimeMillis();
340c3a015d2b1b1d89606d77ee09cd0f96744967968Jayachandran C        // Skip ALLOW_DATA for single SIM device
341c3a015d2b1b1d89606d77ee09cd0f96744967968Jayachandran C        if (mNumPhones > 1) {
342c3a015d2b1b1d89606d77ee09cd0f96744967968Jayachandran C            mCommandsInterfaces[phoneId].setDataAllowed(false, null);
343c3a015d2b1b1d89606d77ee09cd0f96744967968Jayachandran C        }
3446bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        mActivePhoneRegistrants[phoneId].notifyRegistrants();
3456bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    }
3466bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
3476bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private void activate(int phoneId) {
3486bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        PhoneState state = mPhoneStates[phoneId];
3496bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        if (state.active == true) return;
3506bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        state.active = true;
3516bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        log("activate " + phoneId);
3526bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        state.lastRequested = System.currentTimeMillis();
353c3a015d2b1b1d89606d77ee09cd0f96744967968Jayachandran C        // Skip ALLOW_DATA for single SIM device
354c3a015d2b1b1d89606d77ee09cd0f96744967968Jayachandran C        if (mNumPhones > 1) {
355c3a015d2b1b1d89606d77ee09cd0f96744967968Jayachandran C            mCommandsInterfaces[phoneId].setDataAllowed(true, null);
356c3a015d2b1b1d89606d77ee09cd0f96744967968Jayachandran C        }
3576bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        mActivePhoneRegistrants[phoneId].notifyRegistrants();
3586bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    }
3596bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
360e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwalt    // used when the modem may have been rebooted and we want to resend
361e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwalt    // setDataAllowed
362e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwalt    public void resendDataAllowed(int phoneId) {
363e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwalt        validatePhoneId(phoneId);
364e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwalt        Message msg = obtainMessage(EVENT_RESEND_DATA_ALLOWED);
365e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwalt        msg.arg1 = phoneId;
366e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwalt        msg.sendToTarget();
367e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwalt    }
368e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwalt
369e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwalt    private void onResendDataAllowed(Message msg) {
370e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwalt        final int phoneId = msg.arg1;
371c3a015d2b1b1d89606d77ee09cd0f96744967968Jayachandran C        // Skip ALLOW_DATA for single SIM device
372c3a015d2b1b1d89606d77ee09cd0f96744967968Jayachandran C        if (mNumPhones > 1) {
373c3a015d2b1b1d89606d77ee09cd0f96744967968Jayachandran C            mCommandsInterfaces[phoneId].setDataAllowed(mPhoneStates[phoneId].active, null);
374c3a015d2b1b1d89606d77ee09cd0f96744967968Jayachandran C        }
375e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwalt    }
376e9bf1f44cc6a888fff8419c8f35612d503ba3216Robert Greenwalt
3776bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private int phoneIdForRequest(NetworkRequest netRequest) {
378b24093047930443f067628be575f3da743294ff3Lorenzo Colitti        NetworkSpecifier specifier = netRequest.networkCapabilities.getNetworkSpecifier();
3796bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        int subId;
3806bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
381b24093047930443f067628be575f3da743294ff3Lorenzo Colitti        if (specifier == null) {
3826bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            subId = mDefaultDataSubscription;
383b24093047930443f067628be575f3da743294ff3Lorenzo Colitti        } else if (specifier instanceof StringNetworkSpecifier) {
384b24093047930443f067628be575f3da743294ff3Lorenzo Colitti            try {
385b24093047930443f067628be575f3da743294ff3Lorenzo Colitti                subId = Integer.parseInt(((StringNetworkSpecifier) specifier).specifier);
386b24093047930443f067628be575f3da743294ff3Lorenzo Colitti            } catch (NumberFormatException e) {
387b24093047930443f067628be575f3da743294ff3Lorenzo Colitti                Rlog.e(LOG_TAG, "NumberFormatException on "
388b24093047930443f067628be575f3da743294ff3Lorenzo Colitti                        + ((StringNetworkSpecifier) specifier).specifier);
389b24093047930443f067628be575f3da743294ff3Lorenzo Colitti                subId = INVALID_SUBSCRIPTION_ID;
390b24093047930443f067628be575f3da743294ff3Lorenzo Colitti            }
3916bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        } else {
392b24093047930443f067628be575f3da743294ff3Lorenzo Colitti            subId = INVALID_SUBSCRIPTION_ID;
3936bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        }
394b24093047930443f067628be575f3da743294ff3Lorenzo Colitti
3956bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        int phoneId = INVALID_PHONE_INDEX;
3966bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        if (subId == INVALID_SUBSCRIPTION_ID) return phoneId;
3976bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
3986bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        for (int i = 0 ; i < mNumPhones; i++) {
3996bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            if (mPhoneSubscriptions[i] == subId) {
4006bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                phoneId = i;
4016bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                break;
4026bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            }
4036bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        }
4046bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        return phoneId;
4056bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    }
4066bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
4076bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    public boolean isPhoneActive(int phoneId) {
4086bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        validatePhoneId(phoneId);
4096bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        return mPhoneStates[phoneId].active;
4106bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    }
4116bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
4126bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    public void registerForActivePhoneSwitch(int phoneId, Handler h, int what, Object o) {
4136bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        validatePhoneId(phoneId);
4146bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        Registrant r = new Registrant(h, what, o);
4156bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        mActivePhoneRegistrants[phoneId].add(r);
4166bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        r.notifyRegistrant();
4176bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    }
4186bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
4196bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    public void unregisterForActivePhoneSwitch(int phoneId, Handler h) {
4206bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        validatePhoneId(phoneId);
4216bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        mActivePhoneRegistrants[phoneId].remove(h);
4226bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    }
4236bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
4246bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private void validatePhoneId(int phoneId) {
4256bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        if (phoneId < 0 || phoneId >= mNumPhones) {
4266bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            throw new IllegalArgumentException("Invalid PhoneId");
4276bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        }
4286bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    }
4296bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
4306bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    private void log(String l) {
4316bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        Rlog.d(LOG_TAG, l);
4326bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        mLocalLog.log(l);
4336bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    }
4346bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt
4356bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
4366bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
4376bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        pw.println("PhoneSwitcher:");
4386bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        Calendar c = Calendar.getInstance();
4396bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        for (int i = 0; i < mNumPhones; i++) {
4406bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            PhoneState ps = mPhoneStates[i];
4416bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            c.setTimeInMillis(ps.lastRequested);
4426bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt            pw.println("PhoneId(" + i + ") active=" + ps.active + ", lastRequest=" +
4436bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                    (ps.lastRequested == 0 ? "never" :
4446bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt                     String.format("%tm-%td %tH:%tM:%tS.%tL", c, c, c, c, c, c)));
4456bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        }
4466bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        pw.increaseIndent();
4476bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        mLocalLog.dump(fd, pw, args);
4486bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt        pw.decreaseIndent();
4496bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt    }
4506bfc71d2b5340f6274b3e63926a7068e364fc9ffRobert Greenwalt}
451