diff --git a/tests/cts/hostside/aidl/Android.mk b/tests/cts/hostside/aidl/Android.mk index 85f71c3726..20dabc15b2 100644 --- a/tests/cts/hostside/aidl/Android.mk +++ b/tests/cts/hostside/aidl/Android.mk @@ -19,6 +19,7 @@ LOCAL_MODULE_TAGS := tests LOCAL_SDK_VERSION := current LOCAL_SRC_FILES := \ com/android/cts/net/hostside/IMyService.aidl \ + com/android/cts/net/hostside/INetworkCallback.aidl \ com/android/cts/net/hostside/INetworkStateObserver.aidl \ com/android/cts/net/hostside/IRemoteSocketFactory.aidl LOCAL_MODULE := CtsHostsideNetworkTestsAidl diff --git a/tests/cts/hostside/aidl/com/android/cts/net/hostside/IMyService.aidl b/tests/cts/hostside/aidl/com/android/cts/net/hostside/IMyService.aidl index 72d105990e..a820ae581f 100644 --- a/tests/cts/hostside/aidl/com/android/cts/net/hostside/IMyService.aidl +++ b/tests/cts/hostside/aidl/com/android/cts/net/hostside/IMyService.aidl @@ -16,10 +16,13 @@ package com.android.cts.net.hostside; +import com.android.cts.net.hostside.INetworkCallback; + interface IMyService { void registerBroadcastReceiver(); int getCounters(String receiverName, String action); String checkNetworkStatus(); String getRestrictBackgroundStatus(); void sendNotification(int notificationId, String notificationType); + void registerNetworkCallback(in INetworkCallback cb); } diff --git a/tests/cts/hostside/aidl/com/android/cts/net/hostside/INetworkCallback.aidl b/tests/cts/hostside/aidl/com/android/cts/net/hostside/INetworkCallback.aidl new file mode 100644 index 0000000000..740ec26ee2 --- /dev/null +++ b/tests/cts/hostside/aidl/com/android/cts/net/hostside/INetworkCallback.aidl @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2019 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 com.android.cts.net.hostside; + +import android.net.Network; + +interface INetworkCallback { + void onBlockedStatusChanged(in Network network, boolean blocked); + void onAvailable(in Network network); + void onLost(in Network network); +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 5232372047..d15913d85c 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -962,6 +962,10 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation fail("app2 receiver is not ready"); } + protected void registerNetworkCallback(INetworkCallback cb) throws Exception { + mServiceClient.registerNetworkCallback(cb); + } + /** * Registers a {@link NotificationListenerService} implementation that will execute the * notification actions right after the notification is sent. diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyServiceClient.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyServiceClient.java index e2976c2150..3ee7b99c35 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyServiceClient.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyServiceClient.java @@ -26,8 +26,6 @@ import android.os.RemoteException; import com.android.cts.net.hostside.IMyService; -import java.io.FileDescriptor; - public class MyServiceClient { private static final int TIMEOUT_MS = 5000; private static final String PACKAGE = MyServiceClient.class.getPackage().getName(); @@ -98,4 +96,8 @@ public class MyServiceClient { public void sendNotification(int notificationId, String notificationType) throws RemoteException { mService.sendNotification(notificationId, notificationType); } + + public void registerNetworkCallback(INetworkCallback cb) throws RemoteException { + mService.registerNetworkCallback(cb); + } } diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java index 2496c4ac7d..ec536aff68 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java @@ -16,6 +16,7 @@ package com.android.cts.net.hostside.app2; import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; + import static com.android.cts.net.hostside.app2.Common.ACTION_RECEIVER_READY; import static com.android.cts.net.hostside.app2.Common.DYNAMIC_RECEIVER; import static com.android.cts.net.hostside.app2.Common.TAG; @@ -26,13 +27,16 @@ import android.app.Service; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.SharedPreferences; +import android.net.ConnectivityManager; +import android.net.Network; +import android.net.NetworkCapabilities; +import android.net.NetworkRequest; import android.os.IBinder; -import android.os.Looper; +import android.os.RemoteException; import android.util.Log; -import android.widget.Toast; import com.android.cts.net.hostside.IMyService; +import com.android.cts.net.hostside.INetworkCallback; /** * Service used to dynamically register a broadcast receiver. @@ -40,7 +44,10 @@ import com.android.cts.net.hostside.IMyService; public class MyService extends Service { private static final String NOTIFICATION_CHANNEL_ID = "MyService"; + ConnectivityManager mCm; + private MyBroadcastReceiver mReceiver; + private ConnectivityManager.NetworkCallback mNetworkCallback; // TODO: move MyBroadcast static functions here - they were kept there to make git diff easier. @@ -81,8 +88,67 @@ public class MyService extends Service { MyBroadcastReceiver .sendNotification(getApplicationContext(), NOTIFICATION_CHANNEL_ID, notificationId, notificationType); } + + @Override + public void registerNetworkCallback(INetworkCallback cb) { + if (mNetworkCallback != null) { + Log.d(TAG, "unregister previous network callback: " + mNetworkCallback); + unregisterNetworkCallback(); + } + Log.d(TAG, "registering network callback"); + + mNetworkCallback = new ConnectivityManager.NetworkCallback() { + @Override + public void onBlockedStatusChanged(Network network, boolean blocked) { + try { + cb.onBlockedStatusChanged(network, blocked); + } catch (RemoteException e) { + Log.d(TAG, "Cannot send onBlockedStatusChanged: " + e); + unregisterNetworkCallback(); + } + } + + @Override + public void onAvailable(Network network) { + try { + cb.onAvailable(network); + } catch (RemoteException e) { + Log.d(TAG, "Cannot send onAvailable: " + e); + unregisterNetworkCallback(); + } + } + + @Override + public void onLost(Network network) { + try { + cb.onLost(network); + } catch (RemoteException e) { + Log.d(TAG, "Cannot send onLost: " + e); + unregisterNetworkCallback(); + } + } + }; + mCm.registerNetworkCallback(makeWifiNetworkRequest(), mNetworkCallback); + try { + cb.asBinder().linkToDeath(() -> unregisterNetworkCallback(), 0); + } catch (RemoteException e) { + unregisterNetworkCallback(); + } + } }; + private void unregisterNetworkCallback() { + Log.d(TAG, "unregistering network callback"); + mCm.unregisterNetworkCallback(mNetworkCallback); + mNetworkCallback = null; + } + + private NetworkRequest makeWifiNetworkRequest() { + return new NetworkRequest.Builder() + .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) + .build(); + } + @Override public IBinder onBind(Intent intent) { return mBinder; @@ -94,6 +160,8 @@ public class MyService extends Service { ((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE)) .createNotificationChannel(new NotificationChannel(NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_ID, NotificationManager.IMPORTANCE_DEFAULT)); + mCm = (ConnectivityManager) getApplicationContext() + .getSystemService(Context.CONNECTIVITY_SERVICE); } @Override