From d05db41eb7a413339d25f8bd37f44b229980a1a5 Mon Sep 17 00:00:00 2001 From: junyulai Date: Tue, 19 Mar 2019 21:34:38 +0800 Subject: [PATCH] Export API of listening for network change events in app2 Currently, due to foreground app will never get blocked by NetworkPolicyManagerService, so onBlockedStatusChanged cannot be tested under cts net app. Thus, listen for network change events in app2 allows subsequent tests on NetworkCallbacks. Bug: 118862340 Test: m -j cts Change-Id: I26ca370fc6ae4dd3f32ce6cf448bae83f3fbfbcc --- tests/cts/hostside/aidl/Android.mk | 1 + .../android/cts/net/hostside/IMyService.aidl | 3 + .../cts/net/hostside/INetworkCallback.aidl | 25 +++++++ ...ractRestrictBackgroundNetworkTestCase.java | 4 + .../cts/net/hostside/MyServiceClient.java | 6 +- .../cts/net/hostside/app2/MyService.java | 74 ++++++++++++++++++- 6 files changed, 108 insertions(+), 5 deletions(-) create mode 100644 tests/cts/hostside/aidl/com/android/cts/net/hostside/INetworkCallback.aidl 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