diff options
author | TreeHugger Robot <treehugger-gerrit@google.com> | 2018-07-10 01:30:42 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2018-07-10 01:30:42 +0000 |
commit | bdbf66ece04700137cf989faba7abcb7adf5bd8e (patch) | |
tree | fae62ecfa5496d0e4b91d76eb0ad9a95cafdc077 | |
parent | f7482de1ce502e824828aeb1bf465bd4f7e165f7 (diff) | |
parent | 9b783b02980bfabdfa618045defb9033f901a8ae (diff) | |
download | Car-bdbf66ece04700137cf989faba7abcb7adf5bd8e.tar.gz |
Merge "Add connectivity test fragment to KitchenSink" into pi-dev
5 files changed, 235 insertions, 0 deletions
diff --git a/tests/EmbeddedKitchenSinkApp/AndroidManifest.xml b/tests/EmbeddedKitchenSinkApp/AndroidManifest.xml index bc89ad4311..6e8e80f73a 100644 --- a/tests/EmbeddedKitchenSinkApp/AndroidManifest.xml +++ b/tests/EmbeddedKitchenSinkApp/AndroidManifest.xml @@ -42,6 +42,8 @@ <uses-permission android:name="android.permission.READ_SMS"/> <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> + <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> + <uses-permission android:name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS" /> <uses-permission android:name="android.permission.INJECT_EVENTS" /> <application android:label="@string/app_title" diff --git a/tests/EmbeddedKitchenSinkApp/res/layout/connectivity_fragment.xml b/tests/EmbeddedKitchenSinkApp/res/layout/connectivity_fragment.xml new file mode 100644 index 0000000000..15422b1116 --- /dev/null +++ b/tests/EmbeddedKitchenSinkApp/res/layout/connectivity_fragment.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2018 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. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <LinearLayout + android:orientation="horizontal" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + <ListView + android:id="@+id/networks" + android:layout_width="wrap_content" + android:layout_height="wrap_content"> + </ListView> + </LinearLayout> + <LinearLayout + android:orientation="horizontal" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_margin="4dp"> + <Button android:id="@+id/networksRefresh" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Refresh"/> + <Button android:id="@+id/networkRequestOemPaid" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Request OEM-paid"/> + <Button android:id="@+id/networkRequestEth1" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Request eth1"/> + <Button android:id="@+id/networkReleaseNetwork" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Release Request"/> + </LinearLayout> + +</LinearLayout>
\ No newline at end of file diff --git a/tests/EmbeddedKitchenSinkApp/res/layout/list_item.xml b/tests/EmbeddedKitchenSinkApp/res/layout/list_item.xml new file mode 100644 index 0000000000..f517913acb --- /dev/null +++ b/tests/EmbeddedKitchenSinkApp/res/layout/list_item.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2018 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. +--> +<TextView xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@android:id/text1" + android:paddingTop="2dip" + android:paddingBottom="3dip" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:textSize="24sp" />
\ No newline at end of file diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/KitchenSinkActivity.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/KitchenSinkActivity.java index 8f6d92ac55..caca03af01 100644 --- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/KitchenSinkActivity.java +++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/KitchenSinkActivity.java @@ -44,6 +44,7 @@ import com.google.android.car.kitchensink.audio.AudioTestFragment; import com.google.android.car.kitchensink.bluetooth.BluetoothHeadsetFragment; import com.google.android.car.kitchensink.bluetooth.MapMceTestFragment; import com.google.android.car.kitchensink.cluster.InstrumentClusterFragment; +import com.google.android.car.kitchensink.connectivity.ConnectivityFragment; import com.google.android.car.kitchensink.cube.CubesTestFragment; import com.google.android.car.kitchensink.diagnostic.DiagnosticTestFragment; import com.google.android.car.kitchensink.displayinfo.DisplayInfoFragment; @@ -169,6 +170,7 @@ public class KitchenSinkActivity extends CarDrawerActivity { startActivity(intent); }); add("activity view", ActivityViewTestFragment.class); + add("connectivity", ConnectivityFragment.class); add("quit", KitchenSinkActivity.this::finish); } diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/connectivity/ConnectivityFragment.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/connectivity/ConnectivityFragment.java new file mode 100644 index 0000000000..0ffa6bf37e --- /dev/null +++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/connectivity/ConnectivityFragment.java @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2018 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.google.android.car.kitchensink.connectivity; + +import android.annotation.Nullable; +import android.annotation.SuppressLint; +import android.net.ConnectivityManager; +import android.net.ConnectivityManager.NetworkCallback; +import android.net.Network; +import android.net.NetworkCapabilities; +import android.net.NetworkInfo; +import android.net.NetworkRequest; +import android.os.Bundle; +import android.os.Handler; +import android.support.v4.app.Fragment; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.ListView; +import android.widget.Toast; + +import com.google.android.car.kitchensink.R; + +import java.util.ArrayList; + +@SuppressLint("SetTextI18n") +public class ConnectivityFragment extends Fragment { + private static final String TAG = ConnectivityFragment.class.getSimpleName(); + + private final Handler mHandler = new Handler(); + private final ArrayList<String> mNetworks = new ArrayList<>(); + + private ConnectivityManager mConnectivityManager; + private ArrayAdapter<String> mNetworksAdapter; + + private final NetworkCallback mNetworkCallback = new NetworkCallback() { + @Override + public void onAvailable(Network network) { + showToast("onAvailable, netId: " + network); + refreshNetworks(); + } + + @Override + public void onLost(Network network) { + showToast("onLost, netId: " + network); + refreshNetworks(); + } + }; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mConnectivityManager = getActivity().getSystemService(ConnectivityManager.class); + + mConnectivityManager.addDefaultNetworkActiveListener(() -> refreshNetworks()); + } + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.connectivity_fragment, container, false); + + ListView networksView = view.findViewById(R.id.networks); + mNetworksAdapter = new ArrayAdapter<>(getActivity(), R.layout.list_item, mNetworks); + networksView.setAdapter(mNetworksAdapter); + + setClickAction(view, R.id.networksRefresh, this::refreshNetworks); + setClickAction(view, R.id.networkRequestOemPaid, this::requestOemPaid); + setClickAction(view, R.id.networkRequestEth1, this::requestEth1); + setClickAction(view, R.id.networkReleaseNetwork, this::releaseNetworkRequest); + + return view; + } + + private void releaseNetworkRequest() { + mConnectivityManager.unregisterNetworkCallback(mNetworkCallback); + showToast("Release request sent"); + } + + private void requestEth1() { + NetworkRequest request = new NetworkRequest.Builder() + .clearCapabilities() + .addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET) + .setNetworkSpecifier("eth1") + .build(); + mConnectivityManager.requestNetwork(request, mNetworkCallback, mHandler); + } + + private void requestOemPaid() { + NetworkRequest request = new NetworkRequest.Builder() + .addCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID) + .build(); + + mConnectivityManager.requestNetwork(request, mNetworkCallback, mHandler); + } + + @Override + public void onResume() { + super.onResume(); + refreshNetworks(); + } + + private void setClickAction(View view, int id, Runnable action) { + view.findViewById(id).setOnClickListener(v -> action.run()); + } + + private void refreshNetworks() { + mNetworks.clear(); + + for (Network network : mConnectivityManager.getAllNetworks()) { + boolean isDefault = sameNetworkId(network, mConnectivityManager.getActiveNetwork()); + NetworkCapabilities nc = mConnectivityManager.getNetworkCapabilities(network); + boolean isOemPaid = nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID); + boolean isInternet = nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); + + NetworkInfo networkInfo = mConnectivityManager.getNetworkInfo(network); + + mNetworks.add("netId: " + network.netId + + (isInternet ? " [INTERNET]" : "") + + (isDefault ? " [DEFAULT]" : "") + + (isOemPaid ? " [OEM-paid]" : "") + nc + " " + networkInfo); + } + + mNetworksAdapter.notifyDataSetChanged(); + } + + private void showToast(String text) { + Log.d(TAG, "showToast: " + text); + Toast.makeText(getContext(), text, Toast.LENGTH_LONG).show(); + } + + private static boolean sameNetworkId(Network net1, Network net2) { + return net1 != null && net2 != null && net1.netId == net2.netId; + + } +} |