ConnectivityService.java revision b928535902b204ac3ec25f161352786842248767
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.server; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.Notification; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.NotificationManager; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ContentResolver; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.ConnectivityManager; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.IConnectivityManager; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.MobileDataStateTracker; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.NetworkInfo; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.NetworkStateTracker; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.wifi.WifiStateTracker; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Binder; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 3342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwaltimport android.os.IBinder; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Looper; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message; 3642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwaltimport android.os.RemoteException; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ServiceManager; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemProperties; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.provider.Settings; 4042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwaltimport android.text.TextUtils; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.EventLog; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwaltimport com.android.internal.telephony.Phone; 4542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileDescriptor; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.PrintWriter; 4842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwaltimport java.util.ArrayList; 4942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwaltimport java.util.List; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class ConnectivityService extends IConnectivityManager.Stub { 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 56d8df149cfb82cf02cef7e04c05f229d7caf7fe90Robert Greenwalt private static final boolean DBG = true; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "ConnectivityService"; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt // how long to wait before switching back to a radio's default network 6042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt private static final int RESTORE_DEFAULT_NETWORK_DELAY = 1 * 60 * 1000; 6142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt // system property that can override the above value 6242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt private static final String NETWORK_RESTORE_DELAY_PROP_NAME = 6342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt "android.telephony.apn-restore"; 6442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sometimes we want to refer to the individual network state 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * trackers separately, and sometimes we just want to treat them 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * abstractly. 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private NetworkStateTracker mNetTrackers[]; 7142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 7242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt /** 7342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt * A per Net list of the PID's that requested access to the net 7442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt * used both as a refcount and for per-PID DNS selection 7542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt */ 7642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt private List mNetRequestersPids[]; 7742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private WifiWatchdogService mWifiWatchdogService; 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt // priority order of the nettrackers 8142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt // (excluding dynamically set mNetworkPreference) 8242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt // TODO - move mNetworkTypePreference into this 8342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt private int[] mPriorityList; 8442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Context mContext; 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mNetworkPreference; 8742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt private int mActiveDefaultNetwork = -1; 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mNumDnsEntries; 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mTestMode; 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static ConnectivityService sServiceInstance; 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt private Handler mHandler; 9542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 9642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt // list of DeathRecipients used to make sure features are turned off when 9742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt // a process dies 9842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt private List mFeatureUsers; 9942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 1000f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood private boolean mSystemReady; 1011c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn private Intent mInitialBroadcast; 1020f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood 103511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt private static class NetworkAttributes { 10442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt /** 10542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt * Class for holding settings read from resources. 10642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt */ 10742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt public String mName; 10842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt public int mType; 10942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt public int mRadio; 11042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt public int mPriority; 111511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt public NetworkInfo.State mLastState; 11242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt public NetworkAttributes(String init) { 11342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt String fragments[] = init.split(","); 11442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt mName = fragments[0].toLowerCase(); 1155154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt mType = Integer.parseInt(fragments[1]); 1165154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt mRadio = Integer.parseInt(fragments[2]); 1175154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt mPriority = Integer.parseInt(fragments[3]); 118511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt mLastState = NetworkInfo.State.UNKNOWN; 11942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 12042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt public boolean isDefault() { 12142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt return (mType == mRadio); 12242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 12342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 12442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt NetworkAttributes[] mNetAttributes; 1255154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt int mNetworksDefined; 12642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 127511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt private static class RadioAttributes { 12842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt public int mSimultaneity; 12942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt public int mType; 13042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt public RadioAttributes(String init) { 13142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt String fragments[] = init.split(","); 1325154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt mType = Integer.parseInt(fragments[0]); 1335154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt mSimultaneity = Integer.parseInt(fragments[1]); 13442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 13542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 13642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt RadioAttributes[] mRadioAttributes; 13742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static class ConnectivityThread extends Thread { 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Context mContext; 14086e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ConnectivityThread(Context context) { 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super("ConnectivityThread"); 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void run() { 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Looper.prepare(); 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sServiceInstance = new ConnectivityService(mContext); 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notifyAll(); 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Looper.loop(); 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15586e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static ConnectivityService getServiceInstance(Context context) { 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ConnectivityThread thread = new ConnectivityThread(context); 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project thread.start(); 15986e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (thread) { 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (sServiceInstance == null) { 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Wait until sServiceInstance has been initialized. 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project thread.wait(); 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (InterruptedException ignore) { 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, 16786e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt "Unexpected InterruptedException while waiting"+ 16886e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt " for ConnectivityService thread"); 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17286e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return sServiceInstance; 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17686e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static ConnectivityService getInstance(Context context) { 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ConnectivityThread.getServiceInstance(context); 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18086e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ConnectivityService(Context context) { 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DBG) Log.v(TAG, "ConnectivityService starting up"); 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 18442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt mNetTrackers = new NetworkStateTracker[ 18542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt ConnectivityManager.MAX_NETWORK_TYPE+1]; 18642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt mHandler = new MyHandler(); 18786e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkPreference = getPersistedNetworkPreference(); 18986e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt 1905154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt mRadioAttributes = new RadioAttributes[ConnectivityManager.MAX_RADIO_TYPE+1]; 1915154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt mNetAttributes = new NetworkAttributes[ConnectivityManager.MAX_NETWORK_TYPE+1]; 1925154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt 19342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt // Load device network attributes from resources 19442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt String[] raStrings = context.getResources().getStringArray( 19542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt com.android.internal.R.array.radioAttributes); 1965154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt for (String raString : raStrings) { 1975154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt RadioAttributes r = new RadioAttributes(raString); 1985154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt if (r.mType > ConnectivityManager.MAX_RADIO_TYPE) { 1995154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt Log.e(TAG, "Error in radioAttributes - ignoring attempt to define type " + r.mType); 2005154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt continue; 2015154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt } 2025154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt if (mRadioAttributes[r.mType] != null) { 2035154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt Log.e(TAG, "Error in radioAttributes - ignoring attempt to redefine type " + 2045154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt r.mType); 2055154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt continue; 2065154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt } 20742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt mRadioAttributes[r.mType] = r; 20842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 20942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 2105154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt String[] naStrings = context.getResources().getStringArray( 2115154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt com.android.internal.R.array.networkAttributes); 2125154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt for (String naString : naStrings) { 2135154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt try { 2145154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt NetworkAttributes n = new NetworkAttributes(naString); 2155154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt if (n.mType > ConnectivityManager.MAX_NETWORK_TYPE) { 2165154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt Log.e(TAG, "Error in networkAttributes - ignoring attempt to define type " + 2175154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt n.mType); 2185154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt continue; 2195154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt } 2205154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt if (mNetAttributes[n.mType] != null) { 2215154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt Log.e(TAG, "Error in networkAttributes - ignoring attempt to redefine type " + 2225154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt n.mType); 2235154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt continue; 2245154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt } 2255154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt if (mRadioAttributes[n.mRadio] == null) { 2265154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt Log.e(TAG, "Error in networkAttributes - ignoring attempt to use undefined " + 2275154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt "radio " + n.mRadio + " in network type " + n.mType); 2285154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt continue; 2295154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt } 2305154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt mNetAttributes[n.mType] = n; 2315154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt mNetworksDefined++; 2325154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt } catch(Exception e) { 2335154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt // ignore it - leave the entry null 2345154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt } 2355154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt } 2365154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt 23742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt // high priority first 2385154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt mPriorityList = new int[mNetworksDefined]; 23942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt { 2405154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt int insertionPoint = mNetworksDefined-1; 2415154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt int currentLowest = 0; 2425154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt int nextLowest = 0; 2435154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt while (insertionPoint > -1) { 2445154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt for (NetworkAttributes na : mNetAttributes) { 2455154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt if (na == null) continue; 2465154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt if (na.mPriority < currentLowest) continue; 2475154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt if (na.mPriority > currentLowest) { 2485154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt if (na.mPriority < nextLowest || nextLowest == 0) { 2495154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt nextLowest = na.mPriority; 2505154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt } 2515154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt continue; 25242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 2535154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt mPriorityList[insertionPoint--] = na.mType; 25442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 2555154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt currentLowest = nextLowest; 2565154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt nextLowest = 0; 25742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 25842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 25942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 2605154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt mNetRequestersPids = new ArrayList[ConnectivityManager.MAX_NETWORK_TYPE+1]; 2615154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt for (int i : mPriorityList) { 26242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt mNetRequestersPids[i] = new ArrayList(); 26342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 26442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 26542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt mFeatureUsers = new ArrayList(); 26642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 2675154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt mNumDnsEntries = 0; 2685154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt 2695154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt mTestMode = SystemProperties.get("cm.test.mode").equals("true") 2705154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt && SystemProperties.get("ro.build.type").equals("eng"); 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create the network state trackers for Wi-Fi and mobile 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * data. Maybe this could be done with a factory class, 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * but it's not clear that it's worth it, given that 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the number of different network types is not going 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to change very often. 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2785154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt for (int netType : mPriorityList) { 2795154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt switch (mNetAttributes[netType].mRadio) { 2805154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt case ConnectivityManager.TYPE_WIFI: 2815154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt if (DBG) Log.v(TAG, "Starting Wifi Service."); 2825154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt WifiStateTracker wst = new WifiStateTracker(context, mHandler); 2835154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt WifiService wifiService = new WifiService(context, wst); 2845154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt ServiceManager.addService(Context.WIFI_SERVICE, wifiService); 2855154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt mNetTrackers[ConnectivityManager.TYPE_WIFI] = wst; 2865154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt wst.startMonitoring(); 2875154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt 2885154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt // Constructing this starts it too 2895154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt mWifiWatchdogService = new WifiWatchdogService(context, wst); 2905154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt break; 2915154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt case ConnectivityManager.TYPE_MOBILE: 2925154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt mNetTrackers[netType] = new MobileDataStateTracker(context, mHandler, 2935154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt netType, mNetAttributes[netType].mName); 2945154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt mNetTrackers[netType].startMonitoring(); 2955154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt break; 2965154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt default: 2975154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt Log.e(TAG, "Trying to create a DataStateTracker for an unknown radio type " + 2985154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt mNetAttributes[netType].mRadio); 2995154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt continue; 3005154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt } 3015154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt } 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3045154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 30686e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt * Sets the preferred network. 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param preference the new preference 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public synchronized void setNetworkPreference(int preference) { 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforceChangePermission(); 31142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (ConnectivityManager.isNetworkTypeValid(preference) && 3125154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt mNetAttributes[preference] != null && 31342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt mNetAttributes[preference].isDefault()) { 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNetworkPreference != preference) { 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project persistNetworkPreference(preference); 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkPreference = preference; 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforcePreference(); 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getNetworkPreference() { 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforceAccessPermission(); 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mNetworkPreference; 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void persistNetworkPreference(int networkPreference) { 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ContentResolver cr = mContext.getContentResolver(); 32986e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt Settings.Secure.putInt(cr, Settings.Secure.NETWORK_PREFERENCE, 33086e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt networkPreference); 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 33286e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int getPersistedNetworkPreference() { 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ContentResolver cr = mContext.getContentResolver(); 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int networkPrefSetting = Settings.Secure 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project .getInt(cr, Settings.Secure.NETWORK_PREFERENCE, -1); 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (networkPrefSetting != -1) { 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return networkPrefSetting; 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ConnectivityManager.DEFAULT_NETWORK_PREFERENCE; 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 34486e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 34686e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt * Make the state of network connectivity conform to the preference settings 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * In this method, we only tear down a non-preferred network. Establishing 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a connection to the preferred network is taken care of when we handle 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the disconnect event from the non-preferred network 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * (see {@link #handleDisconnect(NetworkInfo)}). 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void enforcePreference() { 35342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (mNetTrackers[mNetworkPreference].getNetworkInfo().isConnected()) 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 35642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (!mNetTrackers[mNetworkPreference].isAvailable()) 35742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt return; 35842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 35942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt for (int t=0; t <= ConnectivityManager.MAX_RADIO_TYPE; t++) { 3605154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt if (t != mNetworkPreference && mNetTrackers[t] != null && 36142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt mNetTrackers[t].getNetworkInfo().isConnected()) { 362ec9fe4672a46eb928ab710d8e3caf2ce046100d4Robert Greenwalt if (DBG) { 363ec9fe4672a46eb928ab710d8e3caf2ce046100d4Robert Greenwalt Log.d(TAG, "tearing down " + 364ec9fe4672a46eb928ab710d8e3caf2ce046100d4Robert Greenwalt mNetTrackers[t].getNetworkInfo() + 365ec9fe4672a46eb928ab710d8e3caf2ce046100d4Robert Greenwalt " in enforcePreference"); 366ec9fe4672a46eb928ab710d8e3caf2ce046100d4Robert Greenwalt } 36742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt teardown(mNetTrackers[t]); 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean teardown(NetworkStateTracker netTracker) { 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (netTracker.teardown()) { 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project netTracker.setTeardownRequested(true); 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return NetworkInfo for the active (i.e., connected) network interface. 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * It is assumed that at most one network is active at a time. If more 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * than one is active, it is indeterminate which will be returned. 38586e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt * @return the info for the active network, or {@code null} if none is 38686e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt * active 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public NetworkInfo getActiveNetworkInfo() { 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforceAccessPermission(); 39042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt for (int type=0; type <= ConnectivityManager.MAX_NETWORK_TYPE; type++) { 3915154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt if (mNetAttributes[type] == null || !mNetAttributes[type].isDefault()) { 39242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt continue; 39342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 39442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt NetworkStateTracker t = mNetTrackers[type]; 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NetworkInfo info = t.getNetworkInfo(); 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (info.isConnected()) { 39742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (DBG && type != mActiveDefaultNetwork) Log.e(TAG, 39842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt "connected default network is not " + 39942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt "mActiveDefaultNetwork!"); 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return info; 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public NetworkInfo getNetworkInfo(int networkType) { 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforceAccessPermission(); 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ConnectivityManager.isNetworkTypeValid(networkType)) { 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NetworkStateTracker t = mNetTrackers[networkType]; 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t != null) 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return t.getNetworkInfo(); 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public NetworkInfo[] getAllNetworkInfo() { 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforceAccessPermission(); 4185154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt NetworkInfo[] result = new NetworkInfo[mNetworksDefined]; 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i = 0; 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (NetworkStateTracker t : mNetTrackers) { 4215154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt if(t != null) result[i++] = t.getNetworkInfo(); 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean setRadios(boolean turnOn) { 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean result = true; 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforceChangePermission(); 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (NetworkStateTracker t : mNetTrackers) { 4305154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt if (t != null) result = t.setRadio(turnOn) && result; 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean setRadio(int netType, boolean turnOn) { 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforceChangePermission(); 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!ConnectivityManager.isNetworkTypeValid(netType)) { 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NetworkStateTracker tracker = mNetTrackers[netType]; 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return tracker != null && tracker.setRadio(turnOn); 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4449c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt /** 4459c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt * Used to notice when the calling process dies so we can self-expire 4469c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt * 4479c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt * Also used to know if the process has cleaned up after itself when 4489c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt * our auto-expire timer goes off. The timer has a link to an object. 4499c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt * 4509c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt */ 45142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt private class FeatureUser implements IBinder.DeathRecipient { 45242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt int mNetworkType; 45342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt String mFeature; 45442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt IBinder mBinder; 45542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt int mPid; 45642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt int mUid; 457b928535902b204ac3ec25f161352786842248767Robert Greenwalt long mCreateTime; 45842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 45942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt FeatureUser(int type, String feature, IBinder binder) { 46042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt super(); 46142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt mNetworkType = type; 46242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt mFeature = feature; 46342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt mBinder = binder; 46442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt mPid = getCallingPid(); 46542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt mUid = getCallingUid(); 466b928535902b204ac3ec25f161352786842248767Robert Greenwalt mCreateTime = System.currentTimeMillis(); 4679c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt 46842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt try { 46942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt mBinder.linkToDeath(this, 0); 47042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } catch (RemoteException e) { 47142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt binderDied(); 47242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 47342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 47442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 47542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt void unlinkDeathRecipient() { 47642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt mBinder.unlinkToDeath(this, 0); 47742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 47842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 47942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt public void binderDied() { 48042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt Log.d(TAG, "ConnectivityService FeatureUser binderDied(" + 481b928535902b204ac3ec25f161352786842248767Robert Greenwalt mNetworkType + ", " + mFeature + ", " + mBinder + "), created " + 482b928535902b204ac3ec25f161352786842248767Robert Greenwalt (System.currentTimeMillis() - mCreateTime) + " mSec ago"); 4839c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt stopUsingNetworkFeature(this, false); 48442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 48542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 4869c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt public void expire() { 4879c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt Log.d(TAG, "ConnectivityService FeatureUser expire(" + 488b928535902b204ac3ec25f161352786842248767Robert Greenwalt mNetworkType + ", " + mFeature + ", " + mBinder +"), created " + 489b928535902b204ac3ec25f161352786842248767Robert Greenwalt (System.currentTimeMillis() - mCreateTime) + " mSec ago"); 4909c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt stopUsingNetworkFeature(this, false); 4919c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt } 492b928535902b204ac3ec25f161352786842248767Robert Greenwalt 493b928535902b204ac3ec25f161352786842248767Robert Greenwalt public String toString() { 494b928535902b204ac3ec25f161352786842248767Robert Greenwalt return "FeatureUser("+mNetworkType+","+mFeature+","+mPid+","+mUid+"), created " + 495b928535902b204ac3ec25f161352786842248767Robert Greenwalt (System.currentTimeMillis() - mCreateTime) + " mSec ago"; 496b928535902b204ac3ec25f161352786842248767Robert Greenwalt } 49742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 49842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 4999c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt // javadoc from interface 50042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt public int startUsingNetworkFeature(int networkType, String feature, 50142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt IBinder binder) { 50242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (DBG) { 50342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt Log.d(TAG, "startUsingNetworkFeature for net " + networkType + 50442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt ": " + feature); 50542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforceChangePermission(); 5075154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt if (!ConnectivityManager.isNetworkTypeValid(networkType) || 5085154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt mNetAttributes[networkType] == null) { 50942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt return Phone.APN_REQUEST_FAILED; 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 51142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 5129c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt FeatureUser f = new FeatureUser(networkType, feature, binder); 51342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 51442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt // TODO - move this into the MobileDataStateTracker 51542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt int usedNetworkType = networkType; 51642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if(networkType == ConnectivityManager.TYPE_MOBILE) { 51742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_MMS)) { 51842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt usedNetworkType = ConnectivityManager.TYPE_MOBILE_MMS; 51942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_SUPL)) { 52042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt usedNetworkType = ConnectivityManager.TYPE_MOBILE_SUPL; 52142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_DUN)) { 52242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt usedNetworkType = ConnectivityManager.TYPE_MOBILE_DUN; 52342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_HIPRI)) { 52442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt usedNetworkType = ConnectivityManager.TYPE_MOBILE_HIPRI; 52542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 52642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 52742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt NetworkStateTracker network = mNetTrackers[usedNetworkType]; 52842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (network != null) { 52942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (usedNetworkType != networkType) { 53042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt Integer currentPid = new Integer(getCallingPid()); 53142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 53242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt NetworkStateTracker radio = mNetTrackers[networkType]; 53342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt NetworkInfo ni = network.getNetworkInfo(); 53442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 53542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (ni.isAvailable() == false) { 53642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (DBG) Log.d(TAG, "special network not available"); 53742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt return Phone.APN_TYPE_NOT_AVAILABLE; 53842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 53942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 5409c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt synchronized(this) { 5419c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt mFeatureUsers.add(f); 5429c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt if (!mNetRequestersPids[usedNetworkType].contains(currentPid)) { 5439c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt // this gets used for per-pid dns when connected 5449c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt mNetRequestersPids[usedNetworkType].add(currentPid); 5459c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt } 54642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 5479c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt mHandler.sendMessageDelayed(mHandler.obtainMessage( 5489c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt NetworkStateTracker.EVENT_RESTORE_DEFAULT_NETWORK, 5499c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt f), getRestoreDefaultNetworkDelay()); 5509c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt 55142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 552a64bf834ffa677405af1c87c9f53eed0cd3853ceRobert Greenwalt if ((ni.isConnectedOrConnecting() == true) && 553a64bf834ffa677405af1c87c9f53eed0cd3853ceRobert Greenwalt !network.isTeardownRequested()) { 55442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (ni.isConnected() == true) { 55542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt // add the pid-specific dns 55642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt handleDnsConfigurationChange(); 55742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (DBG) Log.d(TAG, "special network already active"); 55842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt return Phone.APN_ALREADY_ACTIVE; 55942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 56042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (DBG) Log.d(TAG, "special network already connecting"); 56142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt return Phone.APN_REQUEST_STARTED; 56242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 56342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 56442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt // check if the radio in play can make another contact 56542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt // assume if cannot for now 56642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 56742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (DBG) Log.d(TAG, "reconnecting to special network"); 56842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt network.reconnect(); 56942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt return Phone.APN_REQUEST_STARTED; 57042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } else { 5719c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt synchronized(this) { 5729c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt mFeatureUsers.add(f); 5739c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt } 5749c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt mHandler.sendMessageDelayed(mHandler.obtainMessage( 5759c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt NetworkStateTracker.EVENT_RESTORE_DEFAULT_NETWORK, 5769c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt f), getRestoreDefaultNetworkDelay()); 5779c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt 57842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt return network.startUsingNetworkFeature(feature, 57942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt getCallingPid(), getCallingUid()); 58042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 58242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt return Phone.APN_TYPE_NOT_AVAILABLE; 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5859c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt // javadoc from interface 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int stopUsingNetworkFeature(int networkType, String feature) { 587b8f16340b531809aa08cb73c55ddadd5f94de080Robert Greenwalt enforceChangePermission(); 588b8f16340b531809aa08cb73c55ddadd5f94de080Robert Greenwalt 5899c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt int pid = getCallingPid(); 5909c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt int uid = getCallingUid(); 5919c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt 5929c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt FeatureUser u = null; 5939c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt boolean found = false; 5949c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt 5959c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt synchronized(this) { 5969c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt for (int i = 0; i < mFeatureUsers.size() ; i++) { 5979c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt u = (FeatureUser)mFeatureUsers.get(i); 5989c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt if (uid == u.mUid && pid == u.mPid && 5999c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt networkType == u.mNetworkType && 6009c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt TextUtils.equals(feature, u.mFeature)) { 6019c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt found = true; 6029c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt break; 6039c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt } 6049c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt } 6059c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt } 6069c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt if (found && u != null) { 6079c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt // stop regardless of how many other time this proc had called start 6089c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt return stopUsingNetworkFeature(u, true); 6099c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt } else { 6109c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt // none found! 611b928535902b204ac3ec25f161352786842248767Robert Greenwalt if (DBG) Log.d(TAG, "ignoring stopUsingNetworkFeature - not a live request"); 6129c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt return 1; 6139c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt } 61442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 61542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 6169c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt private int stopUsingNetworkFeature(FeatureUser u, boolean ignoreDups) { 6179c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt int networkType = u.mNetworkType; 6189c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt String feature = u.mFeature; 6199c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt int pid = u.mPid; 6209c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt int uid = u.mUid; 6219c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt 6229c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt NetworkStateTracker tracker = null; 6239c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt boolean callTeardown = false; // used to carry our decision outside of sync block 6249c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt 62542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (DBG) { 62642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt Log.d(TAG, "stopUsingNetworkFeature for net " + networkType + 62742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt ": " + feature); 62842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 629b8f16340b531809aa08cb73c55ddadd5f94de080Robert Greenwalt 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!ConnectivityManager.isNetworkTypeValid(networkType)) { 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 63342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 6349c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt // need to link the mFeatureUsers list with the mNetRequestersPids state in this 6359c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt // sync block 6369c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt synchronized(this) { 6379c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt // check if this process still has an outstanding start request 6389c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt if (!mFeatureUsers.contains(u)) { 6399c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt return 1; 6409c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt } 6419c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt u.unlinkDeathRecipient(); 6429c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt mFeatureUsers.remove(mFeatureUsers.indexOf(u)); 6439c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt // If we care about duplicate requests, check for that here. 6449c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt // 6459c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt // This is done to support the extension of a request - the app 6469c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt // can request we start the network feature again and renew the 6479c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt // auto-shutoff delay. Normal "stop" calls from the app though 6489c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt // do not pay attention to duplicate requests - in effect the 6499c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt // API does not refcount and a single stop will counter multiple starts. 6509c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt if (ignoreDups == false) { 6519c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt for (int i = 0; i < mFeatureUsers.size() ; i++) { 6529c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt FeatureUser x = (FeatureUser)mFeatureUsers.get(i); 6539c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt if (x.mUid == u.mUid && x.mPid == u.mPid && 6549c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt x.mNetworkType == u.mNetworkType && 6559c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt TextUtils.equals(x.mFeature, u.mFeature)) { 656b928535902b204ac3ec25f161352786842248767Robert Greenwalt if (DBG) Log.d(TAG, "ignoring stopUsingNetworkFeature as dup is found"); 6579c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt return 1; 6589c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt } 65942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 66042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 66142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 6629c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt // TODO - move to MobileDataStateTracker 6639c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt int usedNetworkType = networkType; 6649c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt if (networkType == ConnectivityManager.TYPE_MOBILE) { 6659c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_MMS)) { 6669c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt usedNetworkType = ConnectivityManager.TYPE_MOBILE_MMS; 6679c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_SUPL)) { 6689c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt usedNetworkType = ConnectivityManager.TYPE_MOBILE_SUPL; 6699c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_DUN)) { 6709c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt usedNetworkType = ConnectivityManager.TYPE_MOBILE_DUN; 6719c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_HIPRI)) { 6729c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt usedNetworkType = ConnectivityManager.TYPE_MOBILE_HIPRI; 6739c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt } 67442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 6759c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt tracker = mNetTrackers[usedNetworkType]; 6765154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt if (tracker == null) { 6775154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt return -1; 6785154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt } 6795154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt if (usedNetworkType != networkType) { 6809c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt Integer currentPid = new Integer(pid); 6819c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt mNetRequestersPids[usedNetworkType].remove(currentPid); 682421c72b6773582dd1473ace44c42d4e0ee1287e3Robert Greenwalt reassessPidDns(pid, true); 6839c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt if (mNetRequestersPids[usedNetworkType].size() != 0) { 6849c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt if (DBG) Log.d(TAG, "not tearing down special network - " + 6859c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt "others still using it"); 6869c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt return 1; 6879c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt } 6889c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt callTeardown = true; 68942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 6909c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt } 69142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 6929c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt if (callTeardown) { 69342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt tracker.teardown(); 69442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt return 1; 69542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } else { 6969c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt // do it the old fashioned way 69742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt return tracker.stopUsingNetworkFeature(feature, pid, uid); 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Ensure that a network route exists to deliver traffic to the specified 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * host via the specified network interface. 70486e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt * @param networkType the type of the network over which traffic to the 70586e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt * specified host is to be routed 70686e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt * @param hostAddress the IP address of the host to which the route is 70786e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt * desired 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return {@code true} on success, {@code false} on failure 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean requestRouteToHost(int networkType, int hostAddress) { 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enforceChangePermission(); 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!ConnectivityManager.isNetworkTypeValid(networkType)) { 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NetworkStateTracker tracker = mNetTrackers[networkType]; 7168206ff30c23c76851bebc8d72a65e65b0f7f9a29Robert Greenwalt 7175154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt if (tracker == null || !tracker.getNetworkInfo().isConnected() || 7185154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt tracker.isTeardownRequested()) { 7198206ff30c23c76851bebc8d72a65e65b0f7f9a29Robert Greenwalt if (DBG) { 7205154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt Log.d(TAG, "requestRouteToHost on down network (" + networkType + ") - dropped"); 7218206ff30c23c76851bebc8d72a65e65b0f7f9a29Robert Greenwalt } 7228206ff30c23c76851bebc8d72a65e65b0f7f9a29Robert Greenwalt return false; 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7248206ff30c23c76851bebc8d72a65e65b0f7f9a29Robert Greenwalt return tracker.requestRouteToHost(hostAddress); 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see ConnectivityManager#getBackgroundDataSetting() 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean getBackgroundDataSetting() { 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Settings.Secure.getInt(mContext.getContentResolver(), 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Settings.Secure.BACKGROUND_DATA, 1) == 1; 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 73486e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see ConnectivityManager#setBackgroundDataSetting(boolean) 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setBackgroundDataSetting(boolean allowBackgroundDataUsage) { 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.enforceCallingOrSelfPermission( 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.Manifest.permission.CHANGE_BACKGROUND_DATA_SETTING, 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "ConnectivityService"); 74286e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (getBackgroundDataSetting() == allowBackgroundDataUsage) return; 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Settings.Secure.putInt(mContext.getContentResolver(), 74686e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt Settings.Secure.BACKGROUND_DATA, 74786e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt allowBackgroundDataUsage ? 1 : 0); 74886e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent broadcast = new Intent( 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED); 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(broadcast); 75286e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt } 75386e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int getNumConnectedNetworks() { 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int numConnectedNets = 0; 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (NetworkStateTracker nt : mNetTrackers) { 7585154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt if (nt != null && nt.getNetworkInfo().isConnected() && 75986e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt !nt.isTeardownRequested()) { 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ++numConnectedNets; 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return numConnectedNets; 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void enforceAccessPermission() { 76786e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt mContext.enforceCallingOrSelfPermission( 76886e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt android.Manifest.permission.ACCESS_NETWORK_STATE, 76986e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt "ConnectivityService"); 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void enforceChangePermission() { 77386e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt mContext.enforceCallingOrSelfPermission( 77486e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt android.Manifest.permission.CHANGE_NETWORK_STATE, 77586e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt "ConnectivityService"); 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 77986e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt * Handle a {@code DISCONNECTED} event. If this pertains to the non-active 78086e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt * network, we ignore it. If it is for the active network, we send out a 78186e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt * broadcast. But first, we check whether it might be possible to connect 78286e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt * to a different network. 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param info the {@code NetworkInfo} for the network 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void handleDisconnect(NetworkInfo info) { 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 78742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt int prevNetType = info.getType(); 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 78942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt mNetTrackers[prevNetType].setTeardownRequested(false); 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the disconnected network is not the active one, then don't report 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this as a loss of connectivity. What probably happened is that we're 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * getting the disconnect for a network that we explicitly disabled 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in accordance with network preference policies. 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 79642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (!mNetAttributes[prevNetType].isDefault()) { 79742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt List pids = mNetRequestersPids[prevNetType]; 79842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt for (int i = 0; i<pids.size(); i++) { 79942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt Integer pid = (Integer)pids.get(i); 80042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt // will remove them because the net's no longer connected 80142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt // need to do this now as only now do we know the pids and 80242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt // can properly null things that are no longer referenced. 80342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt reassessPidDns(pid.intValue(), false); 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION); 8081c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info); 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (info.isFailover()) { 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true); 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project info.setFailover(false); 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (info.getReason() != null) { 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason()); 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (info.getExtraInfo() != null) { 81886e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, 81986e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt info.getExtraInfo()); 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 82142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 82242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt /* 82342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt * If this is a default network, check if other defaults are available 82442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt * or active 82542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt */ 82642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt NetworkStateTracker newNet = null; 82742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (mNetAttributes[prevNetType].isDefault()) { 82842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (mActiveDefaultNetwork == prevNetType) { 82942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt mActiveDefaultNetwork = -1; 83042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 83142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 83242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt int newType = -1; 83342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt int newPriority = -1; 83442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt for (int checkType=0; checkType <= 83542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt ConnectivityManager.MAX_NETWORK_TYPE; checkType++) { 8365154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt if (checkType == prevNetType) continue; 8375154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt if (mNetAttributes[checkType] == null) continue; 83842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (mNetAttributes[checkType].isDefault()) { 83942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt /* TODO - if we have multiple nets we could use 84042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt * we may want to put more thought into which we choose 84142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt */ 84242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (checkType == mNetworkPreference) { 84342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt newType = checkType; 84442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt break; 84542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 8465154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt if (mNetAttributes[checkType].mPriority > newPriority) { 84742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt newType = checkType; 8485154ae7665743b114c71f90dcc577dc50c63b398Robert Greenwalt newPriority = mNetAttributes[newType].mPriority; 84942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 85042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 85142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 85242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 85342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (newType != -1) { 85442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt newNet = mNetTrackers[newType]; 85542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt /** 85642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt * See if the other network is available to fail over to. 85742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt * If is not available, we enable it anyway, so that it 85842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt * will be able to connect when it does become available, 85942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt * but we report a total loss of connectivity rather than 86042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt * report that we are attempting to fail over. 86142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt */ 86242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (newNet.isAvailable()) { 86342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt NetworkInfo switchTo = newNet.getNetworkInfo(); 86442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt switchTo.setFailover(true); 865a64bf834ffa677405af1c87c9f53eed0cd3853ceRobert Greenwalt if (!switchTo.isConnectedOrConnecting() || 866a64bf834ffa677405af1c87c9f53eed0cd3853ceRobert Greenwalt newNet.isTeardownRequested()) { 86742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt newNet.reconnect(); 86842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 86942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (DBG) { 87042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (switchTo.isConnected()) { 87142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt Log.v(TAG, "Switching to already connected " + 87242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt switchTo.getTypeName()); 87342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } else { 87442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt Log.v(TAG, "Attempting to switch to " + 87542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt switchTo.getTypeName()); 87642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 87742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 87842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt intent.putExtra(ConnectivityManager. 87942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt EXTRA_OTHER_NETWORK_INFO, switchTo); 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 881c7d2530d52e9c188392b118caea64673dbbad45cRobert Greenwalt intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, 882c7d2530d52e9c188392b118caea64673dbbad45cRobert Greenwalt true); 88342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt newNet.reconnect(); 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 88542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } else { 88642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, 88742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt true); 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 89042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 89142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt // do this before we broadcast the change 89242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt handleConnectivityChange(); 89342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 8940f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood sendStickyBroadcast(intent); 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 89686e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt * If the failover network is already connected, then immediately send 89786e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt * out a followup broadcast indicating successful failover 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 89942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (newNet != null && newNet.getNetworkInfo().isConnected()) 90042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt sendConnectedBroadcast(newNet.getNetworkInfo()); 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void sendConnectedBroadcast(NetworkInfo info) { 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION); 9051c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info); 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (info.isFailover()) { 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true); 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project info.setFailover(false); 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (info.getReason() != null) { 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason()); 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (info.getExtraInfo() != null) { 91586e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, 91686e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt info.getExtraInfo()); 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9180f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood sendStickyBroadcast(intent); 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Called when an attempt to fail over to another network has failed. 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param info the {@link NetworkInfo} for the failed network 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void handleConnectionFailure(NetworkInfo info) { 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetTrackers[info.getType()].setTeardownRequested(false); 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 92842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt String reason = info.getReason(); 92942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt String extraInfo = info.getExtraInfo(); 93042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 93142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (DBG) { 93242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt String reasonText; 93342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (reason == null) { 93442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt reasonText = "."; 93542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } else { 93642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt reasonText = " (" + reason + ")."; 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 93842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt Log.v(TAG, "Attempt to connect to " + info.getTypeName() + 93942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt " failed" + reasonText); 94042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 94186e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt 94242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION); 9431c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 94442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info); 94542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (getActiveNetworkInfo() == null) { 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true); 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 94842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (reason != null) { 94942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt intent.putExtra(ConnectivityManager.EXTRA_REASON, reason); 95042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 95142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (extraInfo != null) { 95242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, extraInfo); 95342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 95442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (info.isFailover()) { 95542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true); 95642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt info.setFailover(false); 95742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 9580f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood sendStickyBroadcast(intent); 9590f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood } 9600f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood 9610f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood private void sendStickyBroadcast(Intent intent) { 9620f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood synchronized(this) { 9631c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn if (!mSystemReady) { 9641c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn mInitialBroadcast = new Intent(intent); 9650f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood } 9661c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 9671c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn mContext.sendStickyBroadcast(intent); 9680f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood } 9690f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood } 9700f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood 9710f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood void systemReady() { 9720f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood synchronized(this) { 9730f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood mSystemReady = true; 9741c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn if (mInitialBroadcast != null) { 9751c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn mContext.sendStickyBroadcast(mInitialBroadcast); 9761c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn mInitialBroadcast = null; 9770f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood } 9780f79b54c3a0b4141b1da38fa301571a89e165632Mike Lockwood } 9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void handleConnect(NetworkInfo info) { 98242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt int type = info.getType(); 9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // snapshot isFailover, because sendConnectedBroadcast() resets it 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isFailover = info.isFailover(); 98642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt NetworkStateTracker thisNet = mNetTrackers[type]; 98742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 98842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt // if this is a default net and other default is running 98942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt // kill the one not preferred 99042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (mNetAttributes[type].isDefault()) { 99142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (mActiveDefaultNetwork != -1 && mActiveDefaultNetwork != type) { 99242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if ((type != mNetworkPreference && 99342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt mNetAttributes[mActiveDefaultNetwork].mPriority > 99442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt mNetAttributes[type].mPriority) || 99542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt mNetworkPreference == mActiveDefaultNetwork) { 99642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt // don't accept this one 99742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (DBG) Log.v(TAG, "Not broadcasting CONNECT_ACTION " + 99842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt "to torn down network " + info.getTypeName()); 99942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt teardown(thisNet); 100042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt return; 100142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } else { 100242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt // tear down the other 100342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt NetworkStateTracker otherNet = 100442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt mNetTrackers[mActiveDefaultNetwork]; 100542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (DBG) Log.v(TAG, "Policy requires " + 100642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt otherNet.getNetworkInfo().getTypeName() + 100742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt " teardown"); 100842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (!teardown(otherNet)) { 100942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt Log.e(TAG, "Network declined teardown request"); 101042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt return; 101142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 101242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (isFailover) { 101342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt otherNet.releaseWakeLock(); 101442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 101542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 101742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt mActiveDefaultNetwork = type; 10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 101942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt thisNet.setTeardownRequested(false); 102042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt thisNet.updateNetworkSettings(); 102142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt handleConnectivityChange(); 102242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt sendConnectedBroadcast(info); 10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void handleScanResultsAvailable(NetworkInfo info) { 10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int networkType = info.getType(); 10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (networkType != ConnectivityManager.TYPE_WIFI) { 102886e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt if (DBG) Log.v(TAG, "Got ScanResultsAvailable for " + 102986e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt info.getTypeName() + " network. Don't know how to handle."); 10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 103186e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt 10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetTrackers[networkType].interpretScanResultsAvailable(); 10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 103586e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt private void handleNotificationChange(boolean visible, int id, 103686e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt Notification notification) { 10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NotificationManager notificationManager = (NotificationManager) mContext 10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project .getSystemService(Context.NOTIFICATION_SERVICE); 103986e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt 10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (visible) { 10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notificationManager.notify(id, notification); 10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notificationManager.cancel(id); 10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * After any kind of change in the connectivity state of any network, 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * make sure that anything that depends on the connectivity state of 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * more than one network is set up correctly. We're mainly concerned 10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * with making sure that the list of DNS servers is set up according 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to which networks are connected, and ensuring that the right routing 10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * table entries exist. 10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void handleConnectivityChange() { 10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 105742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt * If a non-default network is enabled, add the host routes that 10581ef95f9eed610897b46a00f51a7cd7944ef26e62Robert Greenwalt * will allow it's DNS servers to be accessed. Only 10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If both mobile and wifi are enabled, add the host routes that 10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will allow MMS traffic to pass on the mobile network. But 10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * remove the default route for the mobile network, so that there 10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will be only one default route, to ensure that all traffic 10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * except MMS will travel via Wi-Fi. 10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 106542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt handleDnsConfigurationChange(); 106642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 106742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt for (int netType : mPriorityList) { 106842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (mNetTrackers[netType].getNetworkInfo().isConnected()) { 106942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (mNetAttributes[netType].isDefault()) { 107042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt mNetTrackers[netType].addDefaultRoute(); 107142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } else { 107242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt mNetTrackers[netType].addPrivateDnsRoutes(); 107342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 107442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } else { 107542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (mNetAttributes[netType].isDefault()) { 107642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt mNetTrackers[netType].removeDefaultRoute(); 107742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } else { 107842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt mNetTrackers[netType].removePrivateDnsRoutes(); 107942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 108042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 108442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt /** 108542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt * Adjust the per-process dns entries (net.dns<x>.<pid>) based 108642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt * on the highest priority active net which this process requested. 108742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt * If there aren't any, clear it out 108842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt */ 108942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt private void reassessPidDns(int myPid, boolean doBump) 109042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt { 109142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (DBG) Log.d(TAG, "reassessPidDns for pid " + myPid); 109242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt for(int i : mPriorityList) { 109342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (mNetAttributes[i].isDefault()) { 109442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt continue; 109542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 109642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt NetworkStateTracker nt = mNetTrackers[i]; 109742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (nt.getNetworkInfo().isConnected() && 109842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt !nt.isTeardownRequested()) { 109942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt List pids = mNetRequestersPids[i]; 110042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt for (int j=0; j<pids.size(); j++) { 110142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt Integer pid = (Integer)pids.get(j); 110242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (pid.intValue() == myPid) { 110342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt String[] dnsList = nt.getNameServers(); 110442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt writePidDns(dnsList, myPid); 110542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (doBump) { 110642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt bumpDns(); 110742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 110842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt return; 110942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 111042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 111142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 111242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 111342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt // nothing found - delete 111442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt for (int i = 1; ; i++) { 111542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt String prop = "net.dns" + i + "." + myPid; 111642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (SystemProperties.get(prop).length() == 0) { 111742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (doBump) { 111842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt bumpDns(); 111942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 112042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt return; 112142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 112242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt SystemProperties.set(prop, ""); 112342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 112442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 112542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 112642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt private void writePidDns(String[] dnsList, int pid) { 112742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt int j = 1; 112842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt for (String dns : dnsList) { 112942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (dns != null && !TextUtils.equals(dns, "0.0.0.0")) { 113042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt SystemProperties.set("net.dns" + j++ + "." + pid, dns); 113142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 113242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 113342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 113442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 113542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt private void bumpDns() { 11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 113742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt * Bump the property that tells the name resolver library to reread 113842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt * the DNS server list from the properties. 11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 114042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt String propVal = SystemProperties.get("net.dnschange"); 114142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt int n = 0; 114242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (propVal.length() != 0) { 114342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt try { 114442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt n = Integer.parseInt(propVal); 114542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } catch (NumberFormatException e) {} 114642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 114742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt SystemProperties.set("net.dnschange", "" + (n+1)); 114842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 115042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt private void handleDnsConfigurationChange() { 115142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt // add default net's dns entries 115242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt for (int x = mPriorityList.length-1; x>= 0; x--) { 115342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt int netType = mPriorityList[x]; 11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NetworkStateTracker nt = mNetTrackers[netType]; 115542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (nt != null && nt.getNetworkInfo().isConnected() && 115686e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt !nt.isTeardownRequested()) { 11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String[] dnsList = nt.getNameServers(); 115842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (mNetAttributes[netType].isDefault()) { 115942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt int j = 1; 116042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt for (String dns : dnsList) { 116142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (dns != null && !TextUtils.equals(dns, "0.0.0.0")) { 11621ef95f9eed610897b46a00f51a7cd7944ef26e62Robert Greenwalt if (DBG) { 11631ef95f9eed610897b46a00f51a7cd7944ef26e62Robert Greenwalt Log.d(TAG, "adding dns " + dns + " for " + 11641ef95f9eed610897b46a00f51a7cd7944ef26e62Robert Greenwalt nt.getNetworkInfo().getTypeName()); 11651ef95f9eed610897b46a00f51a7cd7944ef26e62Robert Greenwalt } 116642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt SystemProperties.set("net.dns" + j++, dns); 116742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 116842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 116942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt for (int k=j ; k<mNumDnsEntries; k++) { 1170b06324a5c1af11b0fef76bdafa569a60498a93d2Robert Greenwalt if (DBG) Log.d(TAG, "erasing net.dns" + k); 1171b06324a5c1af11b0fef76bdafa569a60498a93d2Robert Greenwalt SystemProperties.set("net.dns" + k, ""); 117242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 117342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt mNumDnsEntries = j; 117442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } else { 117542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt // set per-pid dns for attached secondary nets 117642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt List pids = mNetRequestersPids[netType]; 117742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt for (int y=0; y< pids.size(); y++) { 117842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt Integer pid = (Integer)pids.get(y); 117942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt writePidDns(dnsList, pid.intValue()); 11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 118442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 118542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt bumpDns(); 118642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 118742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt 118842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt private int getRestoreDefaultNetworkDelay() { 118942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt String restoreDefaultNetworkDelayStr = SystemProperties.get( 119042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt NETWORK_RESTORE_DELAY_PROP_NAME); 119142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if(restoreDefaultNetworkDelayStr != null && 119242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt restoreDefaultNetworkDelayStr.length() != 0) { 119342acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt try { 119442acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt return Integer.valueOf(restoreDefaultNetworkDelayStr); 119542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } catch (NumberFormatException e) { 119642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 119842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt return RESTORE_DEFAULT_NETWORK_DELAY; 11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 120386e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt if (mContext.checkCallingOrSelfPermission( 120486e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt android.Manifest.permission.DUMP) 12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED) { 120686e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt pw.println("Permission Denial: can't dump ConnectivityService " + 120786e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt "from from pid=" + Binder.getCallingPid() + ", uid=" + 120886e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt Binder.getCallingUid()); 12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(); 12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (NetworkStateTracker nst : mNetTrackers) { 1213b928535902b204ac3ec25f161352786842248767Robert Greenwalt if (nst != null) { 1214b928535902b204ac3ec25f161352786842248767Robert Greenwalt if (nst.getNetworkInfo().isConnected()) { 1215b928535902b204ac3ec25f161352786842248767Robert Greenwalt pw.println("Active network: " + nst.getNetworkInfo(). 1216b928535902b204ac3ec25f161352786842248767Robert Greenwalt getTypeName()); 1217b928535902b204ac3ec25f161352786842248767Robert Greenwalt } 1218b928535902b204ac3ec25f161352786842248767Robert Greenwalt pw.println(nst.getNetworkInfo()); 1219b928535902b204ac3ec25f161352786842248767Robert Greenwalt pw.println(nst); 1220b928535902b204ac3ec25f161352786842248767Robert Greenwalt pw.println(); 1221b928535902b204ac3ec25f161352786842248767Robert Greenwalt } 1222b928535902b204ac3ec25f161352786842248767Robert Greenwalt } 1223b928535902b204ac3ec25f161352786842248767Robert Greenwalt 1224b928535902b204ac3ec25f161352786842248767Robert Greenwalt pw.println("Network Requester Pids:"); 1225b928535902b204ac3ec25f161352786842248767Robert Greenwalt for (int net : mPriorityList) { 1226b928535902b204ac3ec25f161352786842248767Robert Greenwalt String pidString = net + ": "; 1227b928535902b204ac3ec25f161352786842248767Robert Greenwalt for (Object pid : mNetRequestersPids[net]) { 1228b928535902b204ac3ec25f161352786842248767Robert Greenwalt pidString = pidString + pid.toString() + ", "; 122942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt } 1230b928535902b204ac3ec25f161352786842248767Robert Greenwalt pw.println(pidString); 12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1232b928535902b204ac3ec25f161352786842248767Robert Greenwalt pw.println(); 1233b928535902b204ac3ec25f161352786842248767Robert Greenwalt 1234b928535902b204ac3ec25f161352786842248767Robert Greenwalt pw.println("FeatureUsers:"); 1235b928535902b204ac3ec25f161352786842248767Robert Greenwalt for (Object requester : mFeatureUsers) { 1236b928535902b204ac3ec25f161352786842248767Robert Greenwalt pw.println(requester.toString()); 1237b928535902b204ac3ec25f161352786842248767Robert Greenwalt } 1238b928535902b204ac3ec25f161352786842248767Robert Greenwalt pw.println(); 12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 124142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt // must be stateless - things change under us. 12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class MyHandler extends Handler { 12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void handleMessage(Message msg) { 12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NetworkInfo info; 12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (msg.what) { 12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case NetworkStateTracker.EVENT_STATE_CHANGED: 12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project info = (NetworkInfo) msg.obj; 1249511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt int type = info.getType(); 1250511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt NetworkInfo.State state = info.getState(); 1251511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt if(mNetAttributes[type].mLastState == state) { 1252511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt if (DBG) { 1253511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt // TODO - remove this after we validate the dropping doesn't break anything 1254511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt Log.d(TAG, "Dropping ConnectivityChange for " + 1255511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt info.getTypeName() +": " + 1256511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt state + "/" + info.getDetailedState()); 1257511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt } 1258511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt return; 1259511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt } 1260511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt mNetAttributes[type].mLastState = state; 1261511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt 126242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt if (DBG) Log.d(TAG, "ConnectivityChange for " + 126386e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt info.getTypeName() + ": " + 1264511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt state + "/" + info.getDetailedState()); 12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Connectivity state changed: 12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // [31-13] Reserved for future use 126886e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt // [12-9] Network subtype (for mobile network, as defined 126986e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt // by TelephonyManager) 127086e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt // [8-3] Detailed state ordinal (as defined by 127186e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt // NetworkInfo.DetailedState) 12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // [2-0] Network type (as defined by ConnectivityManager) 12739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int eventLogParam = (info.getType() & 0x7) | 12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((info.getDetailedState().ordinal() & 0x3f) << 3) | 12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (info.getSubtype() << 9); 1276ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker EventLog.writeEvent(EventLogTags.CONNECTIVITY_STATE_CHANGED, 127786e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt eventLogParam); 127886e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt 127986e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt if (info.getDetailedState() == 128086e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt NetworkInfo.DetailedState.FAILED) { 12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handleConnectionFailure(info); 1282511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt } else if (state == NetworkInfo.State.DISCONNECTED) { 12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handleDisconnect(info); 1284511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt } else if (state == NetworkInfo.State.SUSPENDED) { 12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: need to think this over. 128686e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt // the logic here is, handle SUSPENDED the same as 128786e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt // DISCONNECTED. The only difference being we are 128886e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt // broadcasting an intent with NetworkInfo that's 128986e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt // suspended. This allows the applications an 129086e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt // opportunity to handle DISCONNECTED and SUSPENDED 129186e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt // differently, or not. 12929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handleDisconnect(info); 1293511288a04639859a6d9bbfedfa2f2b4d7d2c3e88Robert Greenwalt } else if (state == NetworkInfo.State.CONNECTED) { 12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handleConnect(info); 12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 12979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case NetworkStateTracker.EVENT_SCAN_RESULTS_AVAILABLE: 12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project info = (NetworkInfo) msg.obj; 13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handleScanResultsAvailable(info); 13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 130286e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt 13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case NetworkStateTracker.EVENT_NOTIFICATION_CHANGED: 130486e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt handleNotificationChange(msg.arg1 == 1, msg.arg2, 130586e9e55c54a3e07f6c9476d107db99131cefc5d7Robert Greenwalt (Notification) msg.obj); 13069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case NetworkStateTracker.EVENT_CONFIGURATION_CHANGED: 130842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt handleDnsConfigurationChange(); 13099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 13109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case NetworkStateTracker.EVENT_ROAMING_CHANGED: 13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // fill me in 13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case NetworkStateTracker.EVENT_NETWORK_SUBTYPE_CHANGED: 13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // fill me in 13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 131842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt case NetworkStateTracker.EVENT_RESTORE_DEFAULT_NETWORK: 13199c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt FeatureUser u = (FeatureUser)msg.obj; 13209c75d4af63f92806943a9fa9d942644bd601310eRobert Greenwalt u.expire(); 132142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt break; 13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1326