2020import static android .Manifest .permission .RECEIVE_DATA_ACTIVITY_CHANGE ;
2121import static android .net .ConnectivityManager .CONNECTIVITY_ACTION ;
2222import static android .net .ConnectivityManager .CONNECTIVITY_ACTION_IMMEDIATE ;
23+ import static android .net .ConnectivityManager .TYPE_BLUETOOTH ;
24+ import static android .net .ConnectivityManager .TYPE_DUMMY ;
25+ import static android .net .ConnectivityManager .TYPE_ETHERNET ;
26+ import static android .net .ConnectivityManager .TYPE_MOBILE ;
27+ import static android .net .ConnectivityManager .TYPE_WIFI ;
28+ import static android .net .ConnectivityManager .TYPE_WIMAX ;
29+ import static android .net .ConnectivityManager .getNetworkTypeName ;
2330import static android .net .ConnectivityManager .isNetworkTypeValid ;
2431import static android .net .NetworkPolicyManager .RULE_ALLOW_ALL ;
2532import static android .net .NetworkPolicyManager .RULE_REJECT_METERED ;
8693import com .android .server .net .BaseNetworkObserver ;
8794import com .google .android .collect .Lists ;
8895import com .google .android .collect .Sets ;
96+
8997import dalvik .system .DexClassLoader ;
98+
9099import java .io .FileDescriptor ;
91100import java .io .IOException ;
92101import java .io .PrintWriter ;
93102import java .lang .reflect .Constructor ;
94- import java .lang .reflect .Method ;
95- import java .lang .reflect .Modifier ;
96- import java .lang .reflect .InvocationTargetException ;
97103import java .net .Inet4Address ;
98104import java .net .Inet6Address ;
99105import java .net .InetAddress ;
@@ -317,13 +323,25 @@ public RadioAttributes(String init) {
317323
318324 public ConnectivityService (Context context , INetworkManagementService netd ,
319325 INetworkStatsService statsService , INetworkPolicyManager policyManager ) {
326+ // Currently, omitting a NetworkFactory will create one internally
327+ // TODO: create here when we have cleaner WiMAX support
328+ this (context , netd , statsService , policyManager , null );
329+ }
330+
331+ public ConnectivityService (Context context , INetworkManagementService netd ,
332+ INetworkStatsService statsService , INetworkPolicyManager policyManager ,
333+ NetworkFactory netFactory ) {
320334 if (DBG ) log ("ConnectivityService starting up" );
321335
322336 HandlerThread handlerThread = new HandlerThread ("ConnectivityServiceThread" );
323337 handlerThread .start ();
324338 mHandler = new InternalHandler (handlerThread .getLooper ());
325339 mTrackerHandler = new NetworkStateTrackerHandler (handlerThread .getLooper ());
326340
341+ if (netFactory == null ) {
342+ netFactory = new DefaultNetworkFactory (context , mTrackerHandler );
343+ }
344+
327345 // setup our unique device name
328346 if (TextUtils .isEmpty (SystemProperties .get ("net.hostname" ))) {
329347 String id = Settings .Secure .getString (context .getContentResolver (),
@@ -462,59 +480,27 @@ public ConnectivityService(Context context, INetworkManagementService netd,
462480
463481 mTestMode = SystemProperties .get ("cm.test.mode" ).equals ("true" )
464482 && SystemProperties .get ("ro.build.type" ).equals ("eng" );
465- /*
466- * Create the network state trackers for Wi-Fi and mobile
467- * data. Maybe this could be done with a factory class,
468- * but it's not clear that it's worth it, given that
469- * the number of different network types is not going
470- * to change very often.
471- */
472- for (int netType : mPriorityList ) {
473- switch (mNetConfigs [netType ].radio ) {
474- case ConnectivityManager .TYPE_WIFI :
475- mNetTrackers [netType ] = new WifiStateTracker (
476- netType , mNetConfigs [netType ].name );
477- mNetTrackers [netType ].startMonitoring (context , mTrackerHandler );
478- break ;
479- case ConnectivityManager .TYPE_MOBILE :
480- mNetTrackers [netType ] = new MobileDataStateTracker (netType ,
481- mNetConfigs [netType ].name );
482- mNetTrackers [netType ].startMonitoring (context , mTrackerHandler );
483- break ;
484- case ConnectivityManager .TYPE_DUMMY :
485- mNetTrackers [netType ] = new DummyDataStateTracker (netType ,
486- mNetConfigs [netType ].name );
487- mNetTrackers [netType ].startMonitoring (context , mTrackerHandler );
488- break ;
489- case ConnectivityManager .TYPE_BLUETOOTH :
490- mNetTrackers [netType ] = BluetoothTetheringDataTracker .getInstance ();
491- mNetTrackers [netType ].startMonitoring (context , mTrackerHandler );
492- break ;
493- case ConnectivityManager .TYPE_WIMAX :
494- mNetTrackers [netType ] = makeWimaxStateTracker ();
495- if (mNetTrackers [netType ]!= null ) {
496- mNetTrackers [netType ].startMonitoring (context , mTrackerHandler );
497- }
498- break ;
499- case ConnectivityManager .TYPE_ETHERNET :
500- mNetTrackers [netType ] = EthernetDataTracker .getInstance ();
501- mNetTrackers [netType ].startMonitoring (context , mTrackerHandler );
502- break ;
503- default :
504- loge ("Trying to create a DataStateTracker for an unknown radio type " +
505- mNetConfigs [netType ].radio );
483+
484+ // Create and start trackers for hard-coded networks
485+ for (int targetNetworkType : mPriorityList ) {
486+ final NetworkConfig config = mNetConfigs [targetNetworkType ];
487+ final NetworkStateTracker tracker ;
488+ try {
489+ tracker = netFactory .createTracker (targetNetworkType , config );
490+ mNetTrackers [targetNetworkType ] = tracker ;
491+ } catch (IllegalArgumentException e ) {
492+ Slog .e (TAG , "Problem creating " + getNetworkTypeName (targetNetworkType )
493+ + " tracker: " + e );
506494 continue ;
507495 }
508- mCurrentLinkProperties [netType ] = null ;
509- if (mNetTrackers [netType ] != null && mNetConfigs [netType ].isDefault ()) {
510- mNetTrackers [netType ].reconnect ();
496+
497+ tracker .startMonitoring (context , mTrackerHandler );
498+ if (config .isDefault ()) {
499+ tracker .reconnect ();
511500 }
512501 }
513502
514- IBinder b = ServiceManager .getService (Context .NETWORKMANAGEMENT_SERVICE );
515- INetworkManagementService nmService = INetworkManagementService .Stub .asInterface (b );
516-
517- mTethering = new Tethering (mContext , nmService , statsService , this , mHandler .getLooper ());
503+ mTethering = new Tethering (mContext , mNetd , statsService , this , mHandler .getLooper ());
518504 mTetheringConfigValid = ((mTethering .getTetherableUsbRegexs ().length != 0 ||
519505 mTethering .getTetherableWifiRegexs ().length != 0 ||
520506 mTethering .getTetherableBluetoothRegexs ().length != 0 ) &&
@@ -523,9 +509,9 @@ public ConnectivityService(Context context, INetworkManagementService netd,
523509 mVpn = new Vpn (mContext , new VpnCallback ());
524510
525511 try {
526- nmService .registerObserver (mTethering );
527- nmService .registerObserver (mVpn );
528- nmService .registerObserver (mDataActivityObserver );
512+ mNetd .registerObserver (mTethering );
513+ mNetd .registerObserver (mVpn );
514+ mNetd .registerObserver (mDataActivityObserver );
529515 } catch (RemoteException e ) {
530516 loge ("Error registering observer :" + e );
531517 }
@@ -540,7 +526,53 @@ public ConnectivityService(Context context, INetworkManagementService netd,
540526 loadGlobalProxy ();
541527 }
542528
543- private NetworkStateTracker makeWimaxStateTracker () {
529+ /**
530+ * Factory that creates {@link NetworkStateTracker} instances using given
531+ * {@link NetworkConfig}.
532+ */
533+ public interface NetworkFactory {
534+ public NetworkStateTracker createTracker (int targetNetworkType , NetworkConfig config );
535+ }
536+
537+ private static class DefaultNetworkFactory implements NetworkFactory {
538+ private final Context mContext ;
539+ private final Handler mTrackerHandler ;
540+
541+ public DefaultNetworkFactory (Context context , Handler trackerHandler ) {
542+ mContext = context ;
543+ mTrackerHandler = trackerHandler ;
544+ }
545+
546+ @ Override
547+ public NetworkStateTracker createTracker (int targetNetworkType , NetworkConfig config ) {
548+ switch (config .radio ) {
549+ case TYPE_WIFI :
550+ return new WifiStateTracker (targetNetworkType , config .name );
551+ case TYPE_MOBILE :
552+ return new MobileDataStateTracker (targetNetworkType , config .name );
553+ case TYPE_DUMMY :
554+ return new DummyDataStateTracker (targetNetworkType , config .name );
555+ case TYPE_BLUETOOTH :
556+ return BluetoothTetheringDataTracker .getInstance ();
557+ case TYPE_WIMAX :
558+ return makeWimaxStateTracker (mContext , mTrackerHandler );
559+ case TYPE_ETHERNET :
560+ return EthernetDataTracker .getInstance ();
561+ default :
562+ throw new IllegalArgumentException (
563+ "Trying to create a NetworkStateTracker for an unknown radio type: "
564+ + config .radio );
565+ }
566+ }
567+ }
568+
569+ /**
570+ * Loads external WiMAX library and registers as system service, returning a
571+ * {@link NetworkStateTracker} for WiMAX. Caller is still responsible for
572+ * invoking {@link NetworkStateTracker#startMonitoring(Context, Handler)}.
573+ */
574+ private static NetworkStateTracker makeWimaxStateTracker (
575+ Context context , Handler trackerHandler ) {
544576 // Initialize Wimax
545577 DexClassLoader wimaxClassLoader ;
546578 Class wimaxStateTrackerClass = null ;
@@ -554,25 +586,25 @@ private NetworkStateTracker makeWimaxStateTracker() {
554586
555587 NetworkStateTracker wimaxStateTracker = null ;
556588
557- boolean isWimaxEnabled = mContext .getResources ().getBoolean (
589+ boolean isWimaxEnabled = context .getResources ().getBoolean (
558590 com .android .internal .R .bool .config_wimaxEnabled );
559591
560592 if (isWimaxEnabled ) {
561593 try {
562- wimaxJarLocation = mContext .getResources ().getString (
594+ wimaxJarLocation = context .getResources ().getString (
563595 com .android .internal .R .string .config_wimaxServiceJarLocation );
564- wimaxLibLocation = mContext .getResources ().getString (
596+ wimaxLibLocation = context .getResources ().getString (
565597 com .android .internal .R .string .config_wimaxNativeLibLocation );
566- wimaxManagerClassName = mContext .getResources ().getString (
598+ wimaxManagerClassName = context .getResources ().getString (
567599 com .android .internal .R .string .config_wimaxManagerClassname );
568- wimaxServiceClassName = mContext .getResources ().getString (
600+ wimaxServiceClassName = context .getResources ().getString (
569601 com .android .internal .R .string .config_wimaxServiceClassname );
570- wimaxStateTrackerClassName = mContext .getResources ().getString (
602+ wimaxStateTrackerClassName = context .getResources ().getString (
571603 com .android .internal .R .string .config_wimaxStateTrackerClassname );
572604
573605 log ("wimaxJarLocation: " + wimaxJarLocation );
574606 wimaxClassLoader = new DexClassLoader (wimaxJarLocation ,
575- new ContextWrapper (mContext ).getCacheDir ().getAbsolutePath (),
607+ new ContextWrapper (context ).getCacheDir ().getAbsolutePath (),
576608 wimaxLibLocation , ClassLoader .getSystemClassLoader ());
577609
578610 try {
@@ -593,13 +625,13 @@ private NetworkStateTracker makeWimaxStateTracker() {
593625
594626 Constructor wmxStTrkrConst = wimaxStateTrackerClass .getConstructor
595627 (new Class [] {Context .class , Handler .class });
596- wimaxStateTracker = (NetworkStateTracker )wmxStTrkrConst .newInstance (mContext ,
597- mTrackerHandler );
628+ wimaxStateTracker = (NetworkStateTracker ) wmxStTrkrConst .newInstance (
629+ context , trackerHandler );
598630
599631 Constructor wmxSrvConst = wimaxServiceClass .getDeclaredConstructor
600632 (new Class [] {Context .class , wimaxStateTrackerClass });
601633 wmxSrvConst .setAccessible (true );
602- IBinder svcInvoker = (IBinder )wmxSrvConst .newInstance (mContext , wimaxStateTracker );
634+ IBinder svcInvoker = (IBinder )wmxSrvConst .newInstance (context , wimaxStateTracker );
603635 wmxSrvConst .setAccessible (false );
604636
605637 ServiceManager .addService (WimaxManagerConstants .WIMAX_SERVICE , svcInvoker );
@@ -1876,6 +1908,7 @@ private void handleConnect(NetworkInfo info) {
18761908 // snapshot isFailover, because sendConnectedBroadcast() resets it
18771909 boolean isFailover = info .isFailover ();
18781910 final NetworkStateTracker thisNet = mNetTrackers [type ];
1911+ final String thisIface = thisNet .getLinkProperties ().getInterfaceName ();
18791912
18801913 // if this is a default net and other default is running
18811914 // kill the one not preferred
@@ -1934,10 +1967,9 @@ private void handleConnect(NetworkInfo info) {
19341967 sendConnectedBroadcastDelayed (info , getConnectivityChangeDelay ());
19351968
19361969 // notify battery stats service about this network
1937- final String iface = thisNet .getLinkProperties ().getInterfaceName ();
1938- if (iface != null ) {
1970+ if (thisIface != null ) {
19391971 try {
1940- BatteryStatsService .getService ().noteNetworkInterfaceType (iface , type );
1972+ BatteryStatsService .getService ().noteNetworkInterfaceType (thisIface , type );
19411973 } catch (RemoteException e ) {
19421974 // ignored; service lives in system_server
19431975 }
@@ -2927,11 +2959,11 @@ public void onChange(boolean selfChange) {
29272959 }
29282960 }
29292961
2930- private void log (String s ) {
2962+ private static void log (String s ) {
29312963 Slog .d (TAG , s );
29322964 }
29332965
2934- private void loge (String s ) {
2966+ private static void loge (String s ) {
29352967 Slog .e (TAG , s );
29362968 }
29372969
0 commit comments