diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 3e0025043a074..2406cbaa28a87 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -1587,4 +1587,11 @@ public class ConnectivityManager { } catch (RemoteException e) { } } + + /** {@hide} */ + public void registerNetworkFactory(Messenger messenger) { + try { + mService.registerNetworkFactory(messenger); + } catch (RemoteException e) { } + } } diff --git a/core/java/android/net/ConnectivityServiceProtocol.java b/core/java/android/net/ConnectivityServiceProtocol.java new file mode 100644 index 0000000000000..34ba6455579a9 --- /dev/null +++ b/core/java/android/net/ConnectivityServiceProtocol.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net; + +import static com.android.internal.util.Protocol.BASE_CONNECTIVITY_SERVICE; + +/** + * Describes the Internal protocols used to communicate with ConnectivityService. + * @hide + */ +public class ConnectivityServiceProtocol { + private ConnectivityServiceProtocol() {} + + private static final int BASE = BASE_CONNECTIVITY_SERVICE; + + public static class NetworkFactoryProtocol { + private NetworkFactoryProtocol() {} + /** + * Pass a network request to the transport + * msg.obj = NetworkRequest + */ + public static final int CMD_REQUEST_NETWORK = BASE; + + /** + * Cancel a network request + * msg.obj = NetworkRequest + */ + public static final int CMD_CANCEL_REQUEST = BASE + 1; + } + + public static class NetworkAgentProtocol { + private NetworkAgentProtocol() {} + } +} diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index d53a856b48ea2..b69797e0b709b 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -150,4 +150,6 @@ interface IConnectivityManager void setProvisioningNotificationVisible(boolean visible, int networkType, in String extraInfo, in String url); void setAirplaneMode(boolean enable); + + void registerNetworkFactory(in Messenger messenger); } diff --git a/core/java/com/android/internal/util/Protocol.java b/core/java/com/android/internal/util/Protocol.java index bc92c4a740f4b..0937ec3a233c6 100644 --- a/core/java/com/android/internal/util/Protocol.java +++ b/core/java/com/android/internal/util/Protocol.java @@ -55,5 +55,6 @@ public class Protocol { public static final int BASE_DNS_PINGER = 0x00050000; public static final int BASE_NSD_MANAGER = 0x00060000; public static final int BASE_NETWORK_STATE_TRACKER = 0x00070000; + public static final int BASE_CONNECTIVITY_SERVICE = 0x00080000; //TODO: define all used protocols } diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index ce2aefb6b5acc..741bf958ff89c 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -29,6 +29,7 @@ import static android.net.ConnectivityManager.TYPE_WIMAX; import static android.net.ConnectivityManager.TYPE_PROXY; import static android.net.ConnectivityManager.getNetworkTypeName; import static android.net.ConnectivityManager.isNetworkTypeValid; +import static android.net.ConnectivityServiceProtocol.NetworkFactoryProtocol; import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL; import static android.net.NetworkPolicyManager.RULE_REJECT_METERED; @@ -66,10 +67,12 @@ import android.net.LinkProperties.CompareResult; import android.net.LinkQualityInfo; import android.net.MobileDataStateTracker; import android.net.Network; +import android.net.NetworkCapabilities; import android.net.NetworkConfig; import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; import android.net.NetworkQuotaInfo; +import android.net.NetworkRequest; import android.net.NetworkState; import android.net.NetworkStateTracker; import android.net.NetworkUtils; @@ -119,6 +122,7 @@ import com.android.internal.telephony.DctConstants; import com.android.internal.telephony.Phone; import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.TelephonyIntents; +import com.android.internal.util.AsyncChannel; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.XmlUtils; import com.android.server.am.BatteryStatsService; @@ -372,6 +376,12 @@ public class ConnectivityService extends IConnectivityManager.Stub { */ private static final int EVENT_PROXY_HAS_CHANGED = 16; + /** + * used internally when registering NetworkFactories + * obj = Messenger + */ + private static final int EVENT_REGISTER_NETWORK_FACTORY = 17; + /** Handler used for internal events. */ private InternalHandler mHandler; /** Handler used for incoming {@link NetworkStateTracker} events. */ @@ -461,6 +471,12 @@ public class ConnectivityService extends IConnectivityManager.Stub { NetworkFactory netFactory) { if (DBG) log("ConnectivityService starting up"); + NetworkCapabilities netCap = new NetworkCapabilities(); + netCap.addNetworkCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); + netCap.addNetworkCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED); + NetworkRequest netRequest = new NetworkRequest(netCap); + mNetworkRequests.append(netRequest.requestId, netRequest); + HandlerThread handlerThread = new HandlerThread("ConnectivityServiceThread"); handlerThread.start(); mHandler = new InternalHandler(handlerThread.getLooper()); @@ -3048,6 +3064,22 @@ public class ConnectivityService extends IConnectivityManager.Stub { public void handleMessage(Message msg) { NetworkInfo info; switch (msg.what) { + case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: { + AsyncChannel ac = (AsyncChannel) msg.obj; + if (mNetworkFactories.contains(ac)) { + if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { + if (VDBG) log("NetworkFactory connected"); + for (int i = 0; i < mNetworkRequests.size(); i++) { + ac.sendMessage(NetworkFactoryProtocol.CMD_REQUEST_NETWORK, + mNetworkRequests.valueAt(i)); + } + } else { + loge("Error connecting NetworkFactory"); + mNetworkFactories.remove((AsyncChannel) msg.obj); + } + } + break; + } case NetworkStateTracker.EVENT_STATE_CHANGED: { info = (NetworkInfo) msg.obj; NetworkInfo.State state = info.getState(); @@ -3241,6 +3273,10 @@ public class ConnectivityService extends IConnectivityManager.Stub { handleApplyDefaultProxy((ProxyInfo)msg.obj); break; } + case EVENT_REGISTER_NETWORK_FACTORY: { + handleRegisterNetworkFactory((Messenger)msg.obj); + break; + } } } } @@ -5081,4 +5117,21 @@ public class ConnectivityService extends IConnectivityManager.Stub { long wakeupTime = SystemClock.elapsedRealtime() + timeoutInMilliseconds; mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, wakeupTime, intent); } + + private final ArrayList mNetworkFactories = new ArrayList(); + + public void registerNetworkFactory(Messenger messenger) { + enforceConnectivityInternalPermission(); + + mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_FACTORY, messenger)); + } + + private void handleRegisterNetworkFactory(Messenger messenger) { + if (VDBG) log("Got NetworkFactory Messenger"); + AsyncChannel ac = new AsyncChannel(); + mNetworkFactories.add(ac); + ac.connect(mContext, mTrackerHandler, messenger); + } + + private final SparseArray mNetworkRequests = new SparseArray(); }