Skip to content

Commit fb11ffa

Browse files
jsharkeyAndroid (Google) Code Review
authored andcommitted
Merge "Isolate NetworkStateTracker creation, test." into jb-mr1-dev
2 parents 82f479d + fb878b6 commit fb11ffa

File tree

3 files changed

+328
-71
lines changed

3 files changed

+328
-71
lines changed

services/java/com/android/server/ConnectivityService.java

Lines changed: 102 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@
2020
import static android.Manifest.permission.RECEIVE_DATA_ACTIVITY_CHANGE;
2121
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
2222
import 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;
2330
import static android.net.ConnectivityManager.isNetworkTypeValid;
2431
import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
2532
import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
@@ -86,14 +93,13 @@
8693
import com.android.server.net.BaseNetworkObserver;
8794
import com.google.android.collect.Lists;
8895
import com.google.android.collect.Sets;
96+
8997
import dalvik.system.DexClassLoader;
98+
9099
import java.io.FileDescriptor;
91100
import java.io.IOException;
92101
import java.io.PrintWriter;
93102
import java.lang.reflect.Constructor;
94-
import java.lang.reflect.Method;
95-
import java.lang.reflect.Modifier;
96-
import java.lang.reflect.InvocationTargetException;
97103
import java.net.Inet4Address;
98104
import java.net.Inet6Address;
99105
import 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

services/tests/servicestests/Android.mk

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src)
99

1010
LOCAL_STATIC_JAVA_LIBRARIES := \
1111
easymocklib \
12-
guava
12+
guava \
13+
littlemock
1314

1415
LOCAL_JAVA_LIBRARIES := android.test.runner services
1516

0 commit comments

Comments
 (0)