summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorAaron Huang <huangaaron@google.com>2021-01-18 15:28:01 +0800
committerAaron Huang <huangaaron@google.com>2021-03-15 14:40:58 +0800
commit5d31a15d84de61d7059b5a1211b5c7dda4d5b612 (patch)
treee694c6bcbe8635006f26375ea0f049608271e356 /core
parentb4cbcf01aa9cde6ab6fb0403cca7b02268b4cff9 (diff)
Make PacProxyService be a system service
PacProxyInstaller class is running a thread all the time and is listening to intent ACTION_PAC_REFRESH so it would be better to make it be a system service with a manager class PacProxyManager which is obtained with getSystemService(PacProxyManager.class). Besides, rename PacProxyInstaller to PacProxyService will be easier to know it's the service for PacProxyManager. ConnectivityService is going to be a mainline module and it needs constructor of PacProxyService to be SystemApi. However, in current design, it needs to pass a handler and an int arguments to the constructor which would be difficult to maintain if just expose the constructor directly. So, define a listener for the event that the current PAC proxy has been installed so that the handler and the int arguments can be removed from the constructor. Bug: 177035719 Test: FrameworksNetTests Change-Id: I2abff75ec59a17628ef006aad348c53fadbed076
Diffstat (limited to 'core')
-rw-r--r--core/api/module-lib-current.txt10
-rw-r--r--core/java/android/app/SystemServiceRegistry.java11
-rw-r--r--core/java/android/content/Context.java12
-rw-r--r--core/java/android/net/IPacProxyInstalledListener.aidl25
-rw-r--r--core/java/android/net/IPacProxyManager.aidl28
-rw-r--r--core/java/android/net/PacProxyManager.java150
-rw-r--r--core/java/android/net/PacProxySelector.java2
7 files changed, 237 insertions, 1 deletions
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 4d9b4aafcae1..cdbd671bbb10 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -42,6 +42,16 @@ package android.net {
method @Nullable public byte[] getWatchlistConfigHash();
}
+ public class PacProxyManager {
+ method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void addPacProxyInstalledListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.PacProxyManager.PacProxyInstalledListener);
+ method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void removePacProxyInstalledListener(@NonNull android.net.PacProxyManager.PacProxyInstalledListener);
+ method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void setCurrentProxyScriptUrl(@Nullable android.net.ProxyInfo);
+ }
+
+ public static interface PacProxyManager.PacProxyInstalledListener {
+ method public void onPacProxyInstalled(@Nullable android.net.Network, @NonNull android.net.ProxyInfo);
+ }
+
public final class Proxy {
method public static void setHttpProxyConfiguration(@Nullable android.net.ProxyInfo);
}
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 331a0b125ee2..267d029d53fe 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -117,11 +117,13 @@ import android.net.EthernetManager;
import android.net.IEthernetManager;
import android.net.IIpSecService;
import android.net.INetworkPolicyManager;
+import android.net.IPacProxyManager;
import android.net.IVpnManager;
import android.net.IpSecManager;
import android.net.NetworkPolicyManager;
import android.net.NetworkScoreManager;
import android.net.NetworkWatchlistManager;
+import android.net.PacProxyManager;
import android.net.TetheringManager;
import android.net.VpnManager;
import android.net.lowpan.ILowpanManager;
@@ -346,6 +348,15 @@ public final class SystemServiceRegistry {
// (which extends it).
SYSTEM_SERVICE_NAMES.put(android.text.ClipboardManager.class, Context.CLIPBOARD_SERVICE);
+ registerService(Context.PAC_PROXY_SERVICE, PacProxyManager.class,
+ new CachedServiceFetcher<PacProxyManager>() {
+ @Override
+ public PacProxyManager createService(ContextImpl ctx) throws ServiceNotFoundException {
+ IBinder b = ServiceManager.getServiceOrThrow(Context.PAC_PROXY_SERVICE);
+ IPacProxyManager service = IPacProxyManager.Stub.asInterface(b);
+ return new PacProxyManager(ctx.getOuterContext(), service);
+ }});
+
registerService(Context.NETD_SERVICE, IBinder.class, new StaticServiceFetcher<IBinder>() {
@Override
public IBinder createService() throws ServiceNotFoundException {
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 9c8856650ae0..aa6127904400 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3451,6 +3451,7 @@ public abstract class Context {
VIBRATOR_SERVICE,
//@hide: STATUS_BAR_SERVICE,
CONNECTIVITY_SERVICE,
+ PAC_PROXY_SERVICE,
VCN_MANAGEMENT_SERVICE,
//@hide: IP_MEMORY_STORE_SERVICE,
IPSEC_SERVICE,
@@ -4017,6 +4018,17 @@ public abstract class Context {
public static final String CONNECTIVITY_SERVICE = "connectivity";
/**
+ * Use with {@link #getSystemService(String)} to retrieve a {@link
+ * android.net.PacProxyManager} for handling management of
+ * pac proxy information.
+ *
+ * @see #getSystemService(String)
+ * @see android.net.PacProxyManager
+ * @hide
+ */
+ public static final String PAC_PROXY_SERVICE = "pac_proxy";
+
+ /**
* Use with {@link #getSystemService(String)} to retrieve a {@link android.net.vcn.VcnManager}
* for managing Virtual Carrier Networks
*
diff --git a/core/java/android/net/IPacProxyInstalledListener.aidl b/core/java/android/net/IPacProxyInstalledListener.aidl
new file mode 100644
index 000000000000..b1f946e02215
--- /dev/null
+++ b/core/java/android/net/IPacProxyInstalledListener.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2021 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 android.net.Network;
+import android.net.ProxyInfo;
+
+/** {@hide} */
+oneway interface IPacProxyInstalledListener {
+ void onPacProxyInstalled(in Network network, in ProxyInfo proxy);
+}
diff --git a/core/java/android/net/IPacProxyManager.aidl b/core/java/android/net/IPacProxyManager.aidl
new file mode 100644
index 000000000000..8f65c56662ef
--- /dev/null
+++ b/core/java/android/net/IPacProxyManager.aidl
@@ -0,0 +1,28 @@
+/**
+ * Copyright (c) 2021, 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 perNmissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import android.net.IPacProxyInstalledListener;
+import android.net.ProxyInfo;
+
+/** {@hide} */
+interface IPacProxyManager
+{
+ void addListener(IPacProxyInstalledListener listener);
+ void removeListener(IPacProxyInstalledListener listener);
+ void setCurrentProxyScriptUrl(in ProxyInfo proxyInfo);
+}
diff --git a/core/java/android/net/PacProxyManager.java b/core/java/android/net/PacProxyManager.java
new file mode 100644
index 000000000000..8f7ad8c335ca
--- /dev/null
+++ b/core/java/android/net/PacProxyManager.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2021 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 android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.annotation.SystemService;
+import android.content.Context;
+import android.os.Binder;
+import android.os.RemoteException;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.HashMap;
+import java.util.Objects;
+import java.util.concurrent.Executor;
+
+/**
+ * @hide
+ */
+@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+@SystemService(Context.PAC_PROXY_SERVICE)
+public class PacProxyManager {
+ private final Context mContext;
+ private final IPacProxyManager mService;
+ @GuardedBy("mListenerMap")
+ private final HashMap<PacProxyInstalledListener, PacProxyInstalledListenerProxy>
+ mListenerMap = new HashMap<>();
+
+ /** @hide */
+ public PacProxyManager(Context context, IPacProxyManager service) {
+ Objects.requireNonNull(service, "missing IPacProxyManager");
+ mContext = context;
+ mService = service;
+ }
+
+ /**
+ * Add a listener to start monitoring events reported by PacProxyService.
+ */
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.NETWORK_STACK,
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+ android.Manifest.permission.NETWORK_SETTINGS})
+ public void addPacProxyInstalledListener(@NonNull Executor executor,
+ @NonNull PacProxyInstalledListener listener) {
+ try {
+ synchronized (mListenerMap) {
+ final PacProxyInstalledListenerProxy listenerProxy =
+ new PacProxyInstalledListenerProxy(executor, listener);
+
+ if (null != mListenerMap.putIfAbsent(listener, listenerProxy)) {
+ throw new IllegalStateException("Listener is already added.");
+ }
+ mService.addListener(listenerProxy);
+ }
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Remove the listener to stop monitoring the event of PacProxyInstalledListener.
+ */
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.NETWORK_STACK,
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+ android.Manifest.permission.NETWORK_SETTINGS})
+ public void removePacProxyInstalledListener(@NonNull PacProxyInstalledListener listener) {
+ try {
+ synchronized (mListenerMap) {
+ final PacProxyInstalledListenerProxy listenerProxy = mListenerMap.remove(listener);
+ if (listenerProxy == null) return;
+ mService.removeListener(listenerProxy);
+ }
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Updates the PAC Proxy Installer with current Proxy information.
+ */
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.NETWORK_STACK,
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+ android.Manifest.permission.NETWORK_SETTINGS})
+ public void setCurrentProxyScriptUrl(@Nullable ProxyInfo proxy) {
+ try {
+ mService.setCurrentProxyScriptUrl(proxy);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * A callback interface for monitoring changes of PAC proxy information.
+ */
+ public interface PacProxyInstalledListener {
+ /**
+ * Notify that the PAC proxy has been installed. Note that this method will be called with
+ * a ProxyInfo with an empty PAC URL when the PAC proxy is removed.
+ *
+ * This method supports different PAC proxies per-network but not all devices might support
+ * per-network proxies. In that case it will be applied globally.
+ *
+ * @param network the network for which this proxy installed.
+ * @param proxy the installed proxy.
+ */
+ void onPacProxyInstalled(@Nullable Network network, @NonNull ProxyInfo proxy);
+ }
+
+ /**
+ * PacProxyInstalledListener proxy for PacProxyInstalledListener object.
+ * @hide
+ */
+ public class PacProxyInstalledListenerProxy extends IPacProxyInstalledListener.Stub {
+ private final Executor mExecutor;
+ private final PacProxyInstalledListener mListener;
+
+ PacProxyInstalledListenerProxy(Executor executor, PacProxyInstalledListener listener) {
+ mExecutor = executor;
+ mListener = listener;
+ }
+
+ @Override
+ public void onPacProxyInstalled(Network network, ProxyInfo proxy) {
+ Binder.withCleanCallingIdentity(() -> {
+ mExecutor.execute(() -> {
+ mListener.onPacProxyInstalled(network, proxy);
+ });
+ });
+ }
+ }
+}
diff --git a/core/java/android/net/PacProxySelector.java b/core/java/android/net/PacProxySelector.java
index 326943a27d4e..84b7eecd2027 100644
--- a/core/java/android/net/PacProxySelector.java
+++ b/core/java/android/net/PacProxySelector.java
@@ -51,7 +51,7 @@ public class PacProxySelector extends ProxySelector {
ServiceManager.getService(PROXY_SERVICE));
if (mProxyService == null) {
// Added because of b10267814 where mako is restarting.
- Log.e(TAG, "PacProxyInstaller: no proxy service");
+ Log.e(TAG, "PacProxyService: no proxy service");
}
mDefaultList = Lists.newArrayList(java.net.Proxy.NO_PROXY);
}