Merge "Prepare CaptivePortalLogin for system_current"
am: 74b1c8626e
Change-Id: I94b2c465290c36a601de89f6c9e8ebd138b2efe7
This commit is contained in:
27
packages/CaptivePortalLogin/Android.bp
Normal file
27
packages/CaptivePortalLogin/Android.bp
Normal file
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
android_app {
|
||||
name: "CaptivePortalLogin",
|
||||
srcs: ["src/**/*.java"],
|
||||
platform_apis: true,
|
||||
certificate: "platform",
|
||||
static_libs: [
|
||||
"android-support-v4",
|
||||
"metrics-constants-protos",
|
||||
],
|
||||
manifest: "AndroidManifest.xml",
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4
|
||||
|
||||
LOCAL_SRC_FILES := $(call all-java-files-under, src)
|
||||
|
||||
LOCAL_PACKAGE_NAME := CaptivePortalLogin
|
||||
LOCAL_PRIVATE_PLATFORM_APIS := true
|
||||
LOCAL_CERTIFICATE := platform
|
||||
|
||||
include $(BUILD_PACKAGE)
|
||||
@@ -21,7 +21,8 @@
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.NETWORK_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.NETWORK_BYPASS_PRIVATE_DNS" />
|
||||
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
<?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="@+id/ssl_error_msg"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:layout_marginStart="20dip"
|
||||
android:layout_marginEnd="20dip"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginBottom="4dip"
|
||||
android:layout_marginTop="4dip" />
|
||||
|
||||
@@ -78,7 +78,18 @@
|
||||
android:id="@+id/certificate_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginBottom="16dip" >
|
||||
<TextView
|
||||
android:id="@+id/ssl_error_msg"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:layout_marginStart="20dip"
|
||||
android:layout_marginEnd="20dip"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginBottom="4dip"
|
||||
android:layout_marginTop="16dip" />
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
@@ -20,7 +20,7 @@ import static android.net.ConnectivityManager.EXTRA_CAPTIVE_PORTAL_PROBE_SPEC;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.LoadedApk;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
@@ -37,8 +37,9 @@ import android.net.captiveportal.CaptivePortalProbeSpec;
|
||||
import android.net.http.SslCertificate;
|
||||
import android.net.http.SslError;
|
||||
import android.net.wifi.WifiInfo;
|
||||
import android.os.Build;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.SystemProperties;
|
||||
import android.support.v4.widget.SwipeRefreshLayout;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArrayMap;
|
||||
@@ -95,6 +96,7 @@ public class CaptivePortalLoginActivity extends Activity {
|
||||
private CaptivePortal mCaptivePortal;
|
||||
private NetworkCallback mNetworkCallback;
|
||||
private ConnectivityManager mCm;
|
||||
private WifiManager mWifiManager;
|
||||
private boolean mLaunchBrowser = false;
|
||||
private MyWebViewClient mWebViewClient;
|
||||
private SwipeRefreshLayout mSwipeRefreshLayout;
|
||||
@@ -108,7 +110,8 @@ public class CaptivePortalLoginActivity extends Activity {
|
||||
mCaptivePortal = getIntent().getParcelableExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL);
|
||||
logMetricsEvent(MetricsEvent.ACTION_CAPTIVE_PORTAL_LOGIN_ACTIVITY);
|
||||
|
||||
mCm = ConnectivityManager.from(this);
|
||||
mCm = getSystemService(ConnectivityManager.class);
|
||||
mWifiManager = getSystemService(WifiManager.class);
|
||||
mNetwork = getIntent().getParcelableExtra(ConnectivityManager.EXTRA_NETWORK);
|
||||
mUserAgent =
|
||||
getIntent().getStringExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL_USER_AGENT);
|
||||
@@ -150,7 +153,6 @@ public class CaptivePortalLoginActivity extends Activity {
|
||||
// Also initializes proxy system properties.
|
||||
mNetwork = mNetwork.getPrivateDnsBypassingCopy();
|
||||
mCm.bindProcessToNetwork(mNetwork);
|
||||
mCm.setProcessDefaultNetworkForHostResolution(mNetwork);
|
||||
|
||||
// Proxy system properties must be initialized before setContentView is called because
|
||||
// setContentView initializes the WebView logic which in turn reads the system properties.
|
||||
@@ -189,9 +191,12 @@ public class CaptivePortalLoginActivity extends Activity {
|
||||
|
||||
// Find WebView's proxy BroadcastReceiver and prompt it to read proxy system properties.
|
||||
private void setWebViewProxy() {
|
||||
LoadedApk loadedApk = getApplication().mLoadedApk;
|
||||
// TODO: migrate to androidx WebView proxy setting API as soon as it is finalized
|
||||
try {
|
||||
Field receiversField = LoadedApk.class.getDeclaredField("mReceivers");
|
||||
final Field loadedApkField = Application.class.getDeclaredField("mLoadedApk");
|
||||
final Class<?> loadedApkClass = loadedApkField.getType();
|
||||
final Object loadedApk = loadedApkField.get(getApplication());
|
||||
Field receiversField = loadedApkClass.getDeclaredField("mReceivers");
|
||||
receiversField.setAccessible(true);
|
||||
ArrayMap receivers = (ArrayMap) receiversField.get(loadedApk);
|
||||
for (Object receiverMap : receivers.values()) {
|
||||
@@ -332,7 +337,11 @@ public class CaptivePortalLoginActivity extends Activity {
|
||||
|
||||
private static String sanitizeURL(URL url) {
|
||||
// In non-Debug build, only show host to avoid leaking private info.
|
||||
return Build.IS_DEBUGGABLE ? Objects.toString(url) : host(url);
|
||||
return isDebuggable() ? Objects.toString(url) : host(url);
|
||||
}
|
||||
|
||||
private static boolean isDebuggable() {
|
||||
return SystemProperties.getInt("ro.debuggable", 0) == 1;
|
||||
}
|
||||
|
||||
private void testForCaptivePortal() {
|
||||
@@ -585,19 +594,18 @@ public class CaptivePortalLoginActivity extends Activity {
|
||||
}
|
||||
|
||||
private void setViewSecurityCertificate(LinearLayout certificateLayout, SslError error) {
|
||||
((TextView) certificateLayout.findViewById(R.id.ssl_error_msg))
|
||||
.setText(sslErrorMessage(error));
|
||||
SslCertificate cert = error.getCertificate();
|
||||
|
||||
View certificateView = cert.inflateCertificateView(CaptivePortalLoginActivity.this);
|
||||
final LinearLayout placeholder = (LinearLayout) certificateView
|
||||
.findViewById(com.android.internal.R.id.placeholder);
|
||||
LayoutInflater factory = LayoutInflater.from(CaptivePortalLoginActivity.this);
|
||||
|
||||
TextView textView = (TextView) factory.inflate(
|
||||
R.layout.ssl_error_msg, placeholder, false);
|
||||
textView.setText(sslErrorMessage(error));
|
||||
placeholder.addView(textView);
|
||||
|
||||
certificateLayout.addView(certificateView);
|
||||
// TODO: call the method directly once inflateCertificateView is @SystemApi
|
||||
try {
|
||||
final View certificateView = (View) SslCertificate.class.getMethod(
|
||||
"inflateCertificateView", Context.class)
|
||||
.invoke(cert, CaptivePortalLoginActivity.this);
|
||||
certificateLayout.addView(certificateView);
|
||||
} catch (ReflectiveOperationException | SecurityException e) {
|
||||
Log.e(TAG, "Could not create certificate view", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -618,11 +626,30 @@ public class CaptivePortalLoginActivity extends Activity {
|
||||
|
||||
private String getHeaderTitle() {
|
||||
NetworkCapabilities nc = mCm.getNetworkCapabilities(mNetwork);
|
||||
if (nc == null || TextUtils.isEmpty(nc.getSSID())
|
||||
|| !nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
|
||||
final String ssid = getSsid();
|
||||
if (TextUtils.isEmpty(ssid)
|
||||
|| nc == null || !nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
|
||||
return getString(R.string.action_bar_label);
|
||||
}
|
||||
return getString(R.string.action_bar_title, WifiInfo.removeDoubleQuotes(nc.getSSID()));
|
||||
return getString(R.string.action_bar_title, ssid);
|
||||
}
|
||||
|
||||
// TODO: remove once SSID is obtained from NetworkCapabilities
|
||||
private String getSsid() {
|
||||
if (mWifiManager == null) {
|
||||
return null;
|
||||
}
|
||||
final WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
|
||||
return removeDoubleQuotes(wifiInfo.getSSID());
|
||||
}
|
||||
|
||||
private static String removeDoubleQuotes(String string) {
|
||||
if (string == null) return null;
|
||||
final int length = string.length();
|
||||
if ((length > 1) && (string.charAt(0) == '"') && (string.charAt(length - 1) == '"')) {
|
||||
return string.substring(1, length - 1);
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
private String getHeaderSubtitle(URL url) {
|
||||
|
||||
@@ -109,6 +109,8 @@ public class NetworkMonitor extends StateMachine {
|
||||
private static final boolean DBG = true;
|
||||
private static final boolean VDBG = false;
|
||||
private static final boolean VDBG_STALL = Log.isLoggable(TAG, Log.DEBUG);
|
||||
// TODO: use another permission for CaptivePortalLoginActivity once it has its own certificate
|
||||
private static final String PERMISSION_NETWORK_SETTINGS = "android.permission.NETWORK_SETTINGS";
|
||||
// Default configuration values for captive portal detection probes.
|
||||
// TODO: append a random length parameter to the default HTTPS url.
|
||||
// TODO: randomize browser version ids in the default User-Agent String.
|
||||
@@ -682,7 +684,7 @@ public class NetworkMonitor extends StateMachine {
|
||||
public void appResponse(int response) {
|
||||
if (response == APP_RETURN_WANTED_AS_IS) {
|
||||
mContext.enforceCallingPermission(
|
||||
android.Manifest.permission.CONNECTIVITY_INTERNAL,
|
||||
PERMISSION_NETWORK_SETTINGS,
|
||||
"CaptivePortal");
|
||||
}
|
||||
sendMessage(CMD_CAPTIVE_PORTAL_APP_FINISHED, response);
|
||||
@@ -692,7 +694,7 @@ public class NetworkMonitor extends StateMachine {
|
||||
public void logEvent(int eventId, String packageName)
|
||||
throws RemoteException {
|
||||
mContext.enforceCallingPermission(
|
||||
android.Manifest.permission.CONNECTIVITY_INTERNAL,
|
||||
PERMISSION_NETWORK_SETTINGS,
|
||||
"CaptivePortal");
|
||||
mCallback.logCaptivePortalLoginEvent(eventId, packageName);
|
||||
}
|
||||
|
||||
@@ -17,3 +17,24 @@ java_library_static {
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
java_library_static {
|
||||
name: "metrics-constants-protos",
|
||||
host_supported: true,
|
||||
proto: {
|
||||
type: "nano",
|
||||
},
|
||||
srcs: ["src/metrics_constants.proto"],
|
||||
no_framework_libs: true,
|
||||
sdk_version: "system_current",
|
||||
// Pin java_version until jarjar is certified to support later versions. http://b/72703434
|
||||
java_version: "1.8",
|
||||
target: {
|
||||
android: {
|
||||
jarjar_rules: "jarjar-rules.txt",
|
||||
},
|
||||
host: {
|
||||
static_libs: ["libprotobuf-java-nano"],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user