Merge "Restructure Module code [ com.android.tethering ]"
diff --git a/StubLibraries.bp b/StubLibraries.bp
index e0c3022..3d28bf8 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -253,38 +253,11 @@
}
/////////////////////////////////////////////////////////////////////
-// Following droidstubs modules are for extra APIs for modules,
+// Following droidstub module for extra APIs for modules,
// namely @SystemApi(client=MODULE_LIBRARIES) APIs.
/////////////////////////////////////////////////////////////////////
droidstubs {
- name: "module-lib-api",
- defaults: ["metalava-full-api-stubs-default"],
- arg_files: ["core/res/AndroidManifest.xml"],
- args: metalava_framework_docs_args + module_libs,
-
- // Do not generate stubs as they are not needed
- generate_stubs: false,
-
- check_api: {
- current: {
- api_file: "api/module-lib-current.txt",
- removed_api_file: "api/module-lib-removed.txt",
- },
- last_released: {
- api_file: ":android.api.module-lib.latest",
- removed_api_file: ":removed.api.module-lib.latest",
- baseline_file: ":module-lib-api-incompatibilities-with-last-released"
- },
- api_lint: {
- enabled: true,
- new_since: ":android.api.module-lib.latest",
- baseline_file: "api/module-lib-lint-baseline.txt",
- },
- },
-}
-
-droidstubs {
name: "module-lib-api-stubs-docs-non-updatable",
defaults: ["metalava-non-updatable-api-stubs-default"],
arg_files: ["core/res/AndroidManifest.xml"],
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 97ef62b..d10e33f 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -131,6 +131,8 @@
import android.net.lowpan.LowpanManager;
import android.net.nsd.INsdManager;
import android.net.nsd.NsdManager;
+import android.net.vcn.IVcnManagementService;
+import android.net.vcn.VcnManager;
import android.net.wifi.WifiFrameworkInitializer;
import android.net.wifi.nl80211.WifiNl80211Manager;
import android.nfc.NfcManager;
@@ -371,6 +373,14 @@
ctx, () -> ServiceManager.getService(Context.TETHERING_SERVICE));
}});
+ registerService(Context.VCN_MANAGEMENT_SERVICE, VcnManager.class,
+ new CachedServiceFetcher<VcnManager>() {
+ @Override
+ public VcnManager createService(ContextImpl ctx) throws ServiceNotFoundException {
+ IBinder b = ServiceManager.getService(Context.VCN_MANAGEMENT_SERVICE);
+ IVcnManagementService service = IVcnManagementService.Stub.asInterface(b);
+ return new VcnManager(ctx, service);
+ }});
registerService(Context.IPSEC_SERVICE, IpSecManager.class,
new CachedServiceFetcher<IpSecManager>() {
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 872c377..7047f73 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -18,6 +18,7 @@
package android.bluetooth;
import android.Manifest;
+import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -686,6 +687,8 @@
private final Map<LeScanCallback, ScanCallback> mLeScanClients;
private static final Map<BluetoothDevice, List<Pair<OnMetadataChangedListener, Executor>>>
sMetadataListeners = new HashMap<>();
+ private final Map<BluetoothConnectionCallback, Executor>
+ mBluetoothConnectionCallbackExecutorMap = new HashMap<>();
/**
* Bluetooth metadata listener. Overrides the default BluetoothMetadataListener
@@ -3538,6 +3541,133 @@
@Nullable byte[] value);
}
+ private final IBluetoothConnectionCallback mConnectionCallback =
+ new IBluetoothConnectionCallback.Stub() {
+ @Override
+ public void onDeviceConnected(BluetoothDevice device) {
+ for (Map.Entry<BluetoothConnectionCallback, Executor> callbackExecutorEntry:
+ mBluetoothConnectionCallbackExecutorMap.entrySet()) {
+ BluetoothConnectionCallback callback = callbackExecutorEntry.getKey();
+ Executor executor = callbackExecutorEntry.getValue();
+ executor.execute(() -> callback.onDeviceConnected(device));
+ }
+ }
+
+ @Override
+ public void onDeviceDisconnected(BluetoothDevice device) {
+ for (Map.Entry<BluetoothConnectionCallback, Executor> callbackExecutorEntry:
+ mBluetoothConnectionCallbackExecutorMap.entrySet()) {
+ BluetoothConnectionCallback callback = callbackExecutorEntry.getKey();
+ Executor executor = callbackExecutorEntry.getValue();
+ executor.execute(() -> callback.onDeviceDisconnected(device));
+ }
+ }
+ };
+
+ /**
+ * Registers the BluetoothConnectionCallback to receive callback events when a bluetooth device
+ * (classic or low energy) is connected or disconnected.
+ *
+ * @param executor is the callback executor
+ * @param callback is the connection callback you wish to register
+ * @return true if the callback was registered successfully, false otherwise
+ * @throws IllegalArgumentException if the callback is already registered
+ * @hide
+ */
+ public boolean registerBluetoothConnectionCallback(@NonNull @CallbackExecutor Executor executor,
+ @NonNull BluetoothConnectionCallback callback) {
+ if (DBG) Log.d(TAG, "registerBluetoothConnectionCallback()");
+ if (callback == null) {
+ return false;
+ }
+
+ // If the callback map is empty, we register the service-to-app callback
+ if (mBluetoothConnectionCallbackExecutorMap.isEmpty()) {
+ try {
+ mServiceLock.readLock().lock();
+ if (mService != null) {
+ if (!mService.registerBluetoothConnectionCallback(mConnectionCallback)) {
+ return false;
+ }
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ mBluetoothConnectionCallbackExecutorMap.remove(callback);
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+ }
+
+ // Adds the passed in callback to our map of callbacks to executors
+ synchronized (mBluetoothConnectionCallbackExecutorMap) {
+ if (mBluetoothConnectionCallbackExecutorMap.containsKey(callback)) {
+ throw new IllegalArgumentException("This callback has already been registered");
+ }
+ mBluetoothConnectionCallbackExecutorMap.put(callback, executor);
+ }
+
+ return true;
+ }
+
+ /**
+ * Unregisters the BluetoothConnectionCallback that was previously registered by the application
+ *
+ * @param callback is the connection callback you wish to unregister
+ * @return true if the callback was unregistered successfully, false otherwise
+ * @hide
+ */
+ public boolean unregisterBluetoothConnectionCallback(
+ @NonNull BluetoothConnectionCallback callback) {
+ if (DBG) Log.d(TAG, "unregisterBluetoothConnectionCallback()");
+ if (callback == null) {
+ return false;
+ }
+
+ synchronized (mBluetoothConnectionCallbackExecutorMap) {
+ if (mBluetoothConnectionCallbackExecutorMap.remove(callback) != null) {
+ return false;
+ }
+ }
+
+ if (!mBluetoothConnectionCallbackExecutorMap.isEmpty()) {
+ return true;
+ }
+
+ // If the callback map is empty, we unregister the service-to-app callback
+ try {
+ mServiceLock.readLock().lock();
+ if (mService != null) {
+ return mService.unregisterBluetoothConnectionCallback(mConnectionCallback);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+
+ return false;
+ }
+
+ /**
+ * This abstract class is used to implement callbacks for when a bluetooth classic or Bluetooth
+ * Low Energy (BLE) device is either connected or disconnected.
+ *
+ * @hide
+ */
+ public abstract class BluetoothConnectionCallback {
+ /**
+ * Callback triggered when a bluetooth device (classic or BLE) is connected
+ * @param device is the connected bluetooth device
+ */
+ public void onDeviceConnected(BluetoothDevice device) {}
+
+ /**
+ * Callback triggered when a bluetooth device (classic or BLE) is disconnected
+ * @param device is the disconnected bluetooth device
+ */
+ public void onDeviceDisconnected(BluetoothDevice device) {}
+ }
+
/**
* Converts old constant of priority to the new for connection policy
*
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index e6609ca..392dd64 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3402,6 +3402,7 @@
VIBRATOR_SERVICE,
//@hide: STATUS_BAR_SERVICE,
CONNECTIVITY_SERVICE,
+ VCN_MANAGEMENT_SERVICE,
//@hide: IP_MEMORY_STORE_SERVICE,
IPSEC_SERVICE,
VPN_MANAGEMENT_SERVICE,
@@ -3966,6 +3967,16 @@
public static final String CONNECTIVITY_SERVICE = "connectivity";
/**
+ * Use with {@link #getSystemService(String)} to retrieve a {@link android.net.vcn.VcnManager}
+ * for managing Virtual Carrier Networks
+ *
+ * @see #getSystemService(String)
+ * @see android.net.vcn.VcnManager
+ * @hide
+ */
+ public static final String VCN_MANAGEMENT_SERVICE = "vcn_management";
+
+ /**
* Use with {@link #getSystemService(String)} to retrieve a
* {@link android.net.INetd} for communicating with the network stack
* @hide
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 72217a1..267057c 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -189,7 +189,7 @@
* Waits for the event to be delivered to the application and handled.
* @hide
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(trackingBug = 171972397)
public static final int INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH = 2; // see InputDispatcher.h
/** @hide */
diff --git a/core/java/android/net/vcn/IVcnManagementService.aidl b/core/java/android/net/vcn/IVcnManagementService.aidl
new file mode 100644
index 0000000..af06906
--- /dev/null
+++ b/core/java/android/net/vcn/IVcnManagementService.aidl
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2020, 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.vcn;
+
+/**
+ * @hide
+ */
+interface IVcnManagementService {
+}
diff --git a/core/java/android/net/vcn/VcnManager.java b/core/java/android/net/vcn/VcnManager.java
new file mode 100644
index 0000000..d563b03
--- /dev/null
+++ b/core/java/android/net/vcn/VcnManager.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2020 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.vcn;
+
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.NonNull;
+import android.annotation.SystemService;
+import android.content.Context;
+
+/**
+ * VcnManager publishes APIs for applications to configure and manage Virtual Carrier Networks
+ *
+ * @hide
+ */
+@SystemService(Context.VCN_MANAGEMENT_SERVICE)
+public final class VcnManager {
+ @NonNull private static final String TAG = VcnManager.class.getSimpleName();
+
+ @NonNull private final Context mContext;
+ @NonNull private final IVcnManagementService mService;
+
+ /**
+ * Construct an instance of VcnManager within an application context.
+ *
+ * @param ctx the application context for this manager
+ * @param service the VcnManagementService binder backing this manager
+ *
+ * @hide
+ */
+ public VcnManager(@NonNull Context ctx, @NonNull IVcnManagementService service) {
+ mContext = requireNonNull(ctx, "missing context");
+ mService = requireNonNull(service, "missing service");
+ }
+}
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 2aa5c13..7a48a2a 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -724,7 +724,7 @@
* Returns the identifier of this process' parent.
* @hide
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(trackingBug = 171962076)
public static final int myPpid() {
return Os.getppid();
}
diff --git a/core/java/android/os/SharedMemory.java b/core/java/android/os/SharedMemory.java
index 7512352..136e3de 100644
--- a/core/java/android/os/SharedMemory.java
+++ b/core/java/android/os/SharedMemory.java
@@ -158,7 +158,7 @@
*
* @hide Exposed for native ASharedMemory_dupFromJava()
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(trackingBug = 171971817)
public int getFd() {
return mFileDescriptor.getInt$();
}
diff --git a/packages/DynamicSystemInstallationService/res/values/strings.xml b/packages/DynamicSystemInstallationService/res/values/strings.xml
index 719fc73..bfeef0a 100644
--- a/packages/DynamicSystemInstallationService/res/values/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values/strings.xml
@@ -37,6 +37,9 @@
<string name="toast_dynsystem_discarded">Discarded dynamic system</string>
<!-- Toast when we fail to launch into Dynamic System [CHAR LIMIT=128] -->
<string name="toast_failed_to_reboot_to_dynsystem">Can\u2019t restart or load dynamic system</string>
+ <!-- Toast when we fail to disable Dynamic System [CHAR LIMIT=128] -->
+ <string name="toast_failed_to_disable_dynsystem">Failed to disable dynamic system</string>
+
<!-- URL of Dynamic System Key Revocation List [DO NOT TRANSLATE] -->
<string name="key_revocation_list_url" translatable="false">https://dl.google.com/developers/android/gsi/gsi-keyblacklist.json</string>
diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
index 12505bc..ac27580 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
@@ -375,8 +375,17 @@
return;
}
- // Per current design, we don't have disable() API. AOT is disabled on next reboot.
- // TODO: Use better status query when b/125079548 is done.
+ if (!mDynSystem.setEnable(/* enable = */ false, /* oneShot = */ false)) {
+ Log.e(TAG, "Failed to disable DynamicSystem.");
+
+ // Dismiss status bar and show a toast.
+ sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
+ Toast.makeText(this,
+ getString(R.string.toast_failed_to_disable_dynsystem),
+ Toast.LENGTH_LONG).show();
+ return;
+ }
+
PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
if (powerManager != null) {
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 21ad6de..da2a3de 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -1147,7 +1147,11 @@
mKeepaliveTracker = new KeepaliveTracker(mContext, mHandler);
mNotifier = new NetworkNotificationManager(mContext, mTelephonyManager,
- mContext.getSystemService(NotificationManager.class));
+ // Pass a NotificationManager obtained from a context with UserHandle.ALL, then
+ // NetworkNotificationManager can put up a notification to all users.
+ // TODO: Create NotificationManager in NetworkNotificationManager directly.
+ (NotificationManager) mContext.createContextAsUser(UserHandle.ALL, 0 /* flags */)
+ .getSystemService(Context.NOTIFICATION_SERVICE));
final int dailyLimit = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT,
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 8cc5fea..1cdc95a 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -1604,10 +1604,12 @@
if (!checkNotifyPermission("notifyDisplayInfoChanged()")) {
return;
}
+ String str = "notifyDisplayInfoChanged: PhoneId=" + phoneId + " subId=" + subId
+ + " telephonyDisplayInfo=" + telephonyDisplayInfo;
if (VDBG) {
- log("notifyDisplayInfoChanged: PhoneId=" + phoneId
- + " subId=" + subId + " telephonyDisplayInfo=" + telephonyDisplayInfo);
+ log(str);
}
+ mLocalLog.log(str);
synchronized (mRecords) {
if (validatePhoneId(phoneId)) {
mTelephonyDisplayInfos[phoneId] = telephonyDisplayInfo;
@@ -2295,10 +2297,10 @@
pw.println("mOutgoingCallEmergencyNumber=" + mOutgoingCallEmergencyNumber[i]);
pw.println("mOutgoingSmsEmergencyNumber=" + mOutgoingSmsEmergencyNumber[i]);
pw.println("mBarringInfo=" + mBarringInfo.get(i));
+ pw.println("mTelephonyDisplayInfo=" + mTelephonyDisplayInfos[i]);
pw.decreaseIndent();
}
pw.println("mCarrierNetworkChangeState=" + mCarrierNetworkChangeState);
-
pw.println("mPhoneCapability=" + mPhoneCapability);
pw.println("mActiveDataSubId=" + mActiveDataSubId);
pw.println("mRadioPowerState=" + mRadioPowerState);
diff --git a/services/core/java/com/android/server/VcnManagementService.java b/services/core/java/com/android/server/VcnManagementService.java
new file mode 100644
index 0000000..db7e16c
--- /dev/null
+++ b/services/core/java/com/android/server/VcnManagementService.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2020 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.server;
+
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.net.vcn.IVcnManagementService;
+
+/**
+ * VcnManagementService manages Virtual Carrier Network profiles and lifecycles.
+ *
+ * <pre>The internal structure of the VCN Management subsystem is as follows:
+ *
+ * +------------------------+ 1:1 +--------------------------------+
+ * | VcnManagementService | ------------ Creates -------------> | TelephonySubscriptionManager |
+ * | | | |
+ * | Manages configs and | | Tracks subscriptions, carrier |
+ * | VcnInstance lifecycles | <--- Notifies of subscription & --- | privilege changes, caches maps |
+ * +------------------------+ carrier privilege changes +--------------------------------+
+ * | 1:N ^
+ * | |
+ * | +-------------------------------+
+ * +---------------+ |
+ * | |
+ * Creates when config present, |
+ * subscription group active, and |
+ * providing app is carrier privileged Notifies of safe
+ * | mode state changes
+ * v |
+ * +-----------------------------------------------------------------------+
+ * | VcnInstance |
+ * | |
+ * | Manages tunnel lifecycles based on fulfillable NetworkRequest(s) |
+ * | and overall safe-mode |
+ * +-----------------------------------------------------------------------+
+ * | 1:N ^
+ * Creates to fulfill |
+ * NetworkRequest(s), tears Notifies of VcnTunnel
+ * down when no longer needed teardown (e.g. Network reaped)
+ * | and safe-mode timer changes
+ * v |
+ * +-----------------------------------------------------------------------+
+ * | VcnTunnel |
+ * | |
+ * | Manages a single (IKEv2) tunnel session and NetworkAgent, |
+ * | handles mobility events, (IPsec) Tunnel setup and safe-mode timers |
+ * +-----------------------------------------------------------------------+
+ * | 1:1 ^
+ * | |
+ * Creates upon instantiation Notifies of changes in
+ * | selected underlying network
+ * | or its properties
+ * v |
+ * +-----------------------------------------------------------------------+
+ * | UnderlyingNetworkTracker |
+ * | |
+ * | Manages lifecycle of underlying physical networks, filing requests to |
+ * | bring them up, and releasing them as they become no longer necessary |
+ * +-----------------------------------------------------------------------+
+ * </pre>
+ *
+ * @hide
+ */
+public class VcnManagementService extends IVcnManagementService.Stub {
+ @NonNull private static final String TAG = VcnManagementService.class.getSimpleName();
+
+ public static final boolean VDBG = false; // STOPSHIP: if true
+
+ /* Binder context for this service */
+ @NonNull private final Context mContext;
+ @NonNull private final Dependencies mDeps;
+
+ private VcnManagementService(@NonNull Context context, @NonNull Dependencies deps) {
+ mContext = requireNonNull(context, "Missing context");
+ mDeps = requireNonNull(deps, "Missing dependencies");
+ }
+
+ // Package-visibility for SystemServer to create instances.
+ static VcnManagementService create(@NonNull Context context) {
+ return new VcnManagementService(context, new Dependencies());
+ }
+
+ private static class Dependencies {}
+
+ /** Notifies the VcnManagementService that external dependencies can be set up */
+ public void systemReady() {}
+}
diff --git a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
index 26356b4..3d22d6d 100644
--- a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
+++ b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
@@ -30,7 +30,6 @@
import android.net.NetworkSpecifier;
import android.net.TelephonyNetworkSpecifier;
import android.net.wifi.WifiInfo;
-import android.os.UserHandle;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
@@ -75,8 +74,11 @@
private static final boolean DBG = true;
private static final boolean VDBG = false;
+ // The context is for the current user (system server)
private final Context mContext;
private final TelephonyManager mTelephonyManager;
+ // The notification manager is created from a context for User.ALL, so notifications
+ // will be sent to all users.
private final NotificationManager mNotificationManager;
// Tracks the types of notifications managed by this instance, from creation to cancellation.
private final SparseIntArray mNotificationTypeMap;
@@ -282,7 +284,7 @@
mNotificationTypeMap.put(id, eventId);
try {
- mNotificationManager.notifyAsUser(tag, eventId, notification, UserHandle.ALL);
+ mNotificationManager.notify(tag, eventId, notification);
} catch (NullPointerException npe) {
Slog.d(TAG, "setNotificationVisible: visible notificationManager error", npe);
}
@@ -311,7 +313,7 @@
nameOf(eventId)));
}
try {
- mNotificationManager.cancelAsUser(tag, eventId, UserHandle.ALL);
+ mNotificationManager.cancel(tag, eventId);
} catch (NullPointerException npe) {
Slog.d(TAG, String.format(
"failed to clear notification tag=%s event=%s", tag, nameOf(eventId)), npe);
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index a55df60..1a83272 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -199,6 +199,8 @@
// automated reconnection
private final Context mContext;
+ // The context is for specific user which is created from mUserId
+ private final Context mUserIdContext;
@VisibleForTesting final Dependencies mDeps;
private final NetworkInfo mNetworkInfo;
private int mLegacyState;
@@ -399,6 +401,7 @@
int userId, @NonNull KeyStore keyStore, SystemServices systemServices,
Ikev2SessionCreator ikev2SessionCreator) {
mContext = context;
+ mUserIdContext = context.createContextAsUser(UserHandle.of(userId), 0 /* flags */);
mDeps = deps;
mNetd = netService;
mUserId = userId;
@@ -1925,9 +1928,10 @@
final UserHandle user = UserHandle.of(mUserId);
final long token = Binder.clearCallingIdentity();
try {
- final NotificationManager notificationManager = NotificationManager.from(mContext);
+ final NotificationManager notificationManager =
+ mUserIdContext.getSystemService(NotificationManager.class);
if (!visible) {
- notificationManager.cancelAsUser(TAG, SystemMessage.NOTE_VPN_DISCONNECTED, user);
+ notificationManager.cancel(TAG, SystemMessage.NOTE_VPN_DISCONNECTED);
return;
}
final Intent intent = new Intent();
@@ -1947,8 +1951,7 @@
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setOngoing(true)
.setColor(mContext.getColor(R.color.system_notification_accent_color));
- notificationManager.notifyAsUser(TAG, SystemMessage.NOTE_VPN_DISCONNECTED,
- builder.build(), user);
+ notificationManager.notify(TAG, SystemMessage.NOTE_VPN_DISCONNECTED, builder.build());
} finally {
Binder.restoreCallingIdentity(token);
}
diff --git a/services/core/java/com/android/server/net/LockdownVpnTracker.java b/services/core/java/com/android/server/net/LockdownVpnTracker.java
index 3a262d6..06cebac 100644
--- a/services/core/java/com/android/server/net/LockdownVpnTracker.java
+++ b/services/core/java/com/android/server/net/LockdownVpnTracker.java
@@ -65,6 +65,7 @@
@NonNull private final Context mContext;
@NonNull private final ConnectivityService mConnService;
+ @NonNull private final NotificationManager mNotificationManager;
@NonNull private final Handler mHandler;
@NonNull private final Vpn mVpn;
@NonNull private final VpnProfile mProfile;
@@ -93,6 +94,7 @@
mHandler = Objects.requireNonNull(handler);
mVpn = Objects.requireNonNull(vpn);
mProfile = Objects.requireNonNull(profile);
+ mNotificationManager = mContext.getSystemService(NotificationManager.class);
final Intent configIntent = new Intent(ACTION_VPN_SETTINGS);
mConfigIntent = PendingIntent.getActivity(mContext, 0 /* requestCode */, configIntent,
@@ -266,11 +268,11 @@
.setColor(mContext.getColor(
com.android.internal.R.color.system_notification_accent_color));
- NotificationManager.from(mContext).notify(null, SystemMessage.NOTE_VPN_STATUS,
+ mNotificationManager.notify(null /* tag */, SystemMessage.NOTE_VPN_STATUS,
builder.build());
}
private void hideNotification() {
- NotificationManager.from(mContext).cancel(null, SystemMessage.NOTE_VPN_STATUS);
+ mNotificationManager.cancel(null, SystemMessage.NOTE_VPN_STATUS);
}
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index cc8c751..ae693c7 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1018,6 +1018,7 @@
IStorageManager storageManager = null;
NetworkManagementService networkManagement = null;
IpSecService ipSecService = null;
+ VcnManagementService vcnManagement = null;
NetworkStatsService networkStats = null;
NetworkPolicyManagerService networkPolicy = null;
IConnectivityManager connectivity = null;
@@ -1453,6 +1454,15 @@
}
t.traceEnd();
+ t.traceBegin("StartVcnManagementService");
+ try {
+ vcnManagement = VcnManagementService.create(context);
+ ServiceManager.addService(Context.VCN_MANAGEMENT_SERVICE, vcnManagement);
+ } catch (Throwable e) {
+ reportWtf("starting VCN Management Service", e);
+ }
+ t.traceEnd();
+
t.traceBegin("StartTextServicesManager");
mSystemServiceManager.startService(TextServicesManagerService.Lifecycle.class);
t.traceEnd();
@@ -2228,6 +2238,7 @@
final MediaRouterService mediaRouterF = mediaRouter;
final MmsServiceBroker mmsServiceF = mmsService;
final IpSecService ipSecServiceF = ipSecService;
+ final VcnManagementService vcnManagementF = vcnManagement;
final WindowManagerService windowManagerF = wm;
final ConnectivityManager connectivityF = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
@@ -2316,6 +2327,15 @@
reportWtf("making IpSec Service ready", e);
}
t.traceEnd();
+ t.traceBegin("MakeVcnManagementServiceReady");
+ try {
+ if (vcnManagementF != null) {
+ vcnManagementF.systemReady();
+ }
+ } catch (Throwable e) {
+ reportWtf("making VcnManagementService ready", e);
+ }
+ t.traceEnd();
t.traceBegin("MakeNetworkStatsServiceReady");
try {
if (networkStatsF != null) {
diff --git a/telephony/common/com/android/internal/telephony/CarrierAppUtils.java b/telephony/common/com/android/internal/telephony/CarrierAppUtils.java
index e57b030..7aecfdd 100644
--- a/telephony/common/com/android/internal/telephony/CarrierAppUtils.java
+++ b/telephony/common/com/android/internal/telephony/CarrierAppUtils.java
@@ -124,11 +124,7 @@
}
private static boolean isUpdatedSystemApp(ApplicationInfo ai) {
- if ((ai.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
- return true;
- }
-
- return false;
+ return (ai.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
}
/**
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 23d450b..56c2500 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -2802,7 +2802,11 @@
/** Current network is LTE_CA {@hide} */
@UnsupportedAppUsage
public static final int NETWORK_TYPE_LTE_CA = TelephonyProtoEnums.NETWORK_TYPE_LTE_CA; // = 19.
- /** Current network is NR(New Radio) 5G. */
+ /**
+ * Current network is NR (New Radio) 5G.
+ * This will only be returned for 5G SA.
+ * For 5G NSA, the network type will be {@link #NETWORK_TYPE_LTE}.
+ */
public static final int NETWORK_TYPE_NR = TelephonyProtoEnums.NETWORK_TYPE_NR; // 20.
private static final @NetworkType int[] NETWORK_TYPES = {
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 3705aaa..3a46291 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -251,6 +251,7 @@
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.AdditionalAnswers;
import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
import org.mockito.Mock;
@@ -452,6 +453,13 @@
}
@Override
+ public Context createContextAsUser(UserHandle user, int flags) {
+ final Context asUser = mock(Context.class, AdditionalAnswers.delegatesTo(this));
+ doReturn(user).when(asUser).getUser();
+ return asUser;
+ }
+
+ @Override
public ContentResolver getContentResolver() {
return mContentResolver;
}
@@ -4992,22 +5000,22 @@
// simulate that situation and check if ConnectivityService could filter that case.
mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid());
waitForIdle();
- verify(mNotificationManager, timeout(TIMEOUT_MS).times(1)).notifyAsUser(anyString(),
- eq(NotificationType.PRIVATE_DNS_BROKEN.eventId), any(), eq(UserHandle.ALL));
+ verify(mNotificationManager, timeout(TIMEOUT_MS).times(1)).notify(anyString(),
+ eq(NotificationType.PRIVATE_DNS_BROKEN.eventId), any());
// If private DNS resolution successful, the PRIVATE_DNS_BROKEN notification shouldn't be
// shown.
mWiFiNetworkAgent.setNetworkValid(true /* isStrictMode */);
mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid());
waitForIdle();
- verify(mNotificationManager, timeout(TIMEOUT_MS).times(1)).cancelAsUser(anyString(),
- eq(NotificationType.PRIVATE_DNS_BROKEN.eventId), eq(UserHandle.ALL));
+ verify(mNotificationManager, timeout(TIMEOUT_MS).times(1)).cancel(anyString(),
+ eq(NotificationType.PRIVATE_DNS_BROKEN.eventId));
// If private DNS resolution failed again, the PRIVATE_DNS_BROKEN notification should be
// shown again.
mWiFiNetworkAgent.setNetworkInvalid(true /* isStrictMode */);
mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid());
waitForIdle();
- verify(mNotificationManager, timeout(TIMEOUT_MS).times(2)).notifyAsUser(anyString(),
- eq(NotificationType.PRIVATE_DNS_BROKEN.eventId), any(), eq(UserHandle.ALL));
+ verify(mNotificationManager, timeout(TIMEOUT_MS).times(2)).notify(anyString(),
+ eq(NotificationType.PRIVATE_DNS_BROKEN.eventId), any());
}
@Test
diff --git a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
index 47db5d4..fa4df4e 100644
--- a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
+++ b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
@@ -114,7 +114,7 @@
final String tag = NetworkNotificationManager.tagFor(id);
mManager.showNotification(id, PRIVATE_DNS_BROKEN, nai, null, null, true);
verify(mNotificationManager, times(1))
- .notifyAsUser(eq(tag), eq(PRIVATE_DNS_BROKEN.eventId), any(), any());
+ .notify(eq(tag), eq(PRIVATE_DNS_BROKEN.eventId), any());
final int transportType = NetworkNotificationManager.approximateTransportType(nai);
if (transportType == NetworkCapabilities.TRANSPORT_WIFI) {
verify(mResources, times(1)).getString(title, eq(any()));
@@ -164,8 +164,8 @@
final int id = ids.get(i);
final int eventId = types.get(i).eventId;
final String tag = NetworkNotificationManager.tagFor(id);
- verify(mNotificationManager, times(1)).notifyAsUser(eq(tag), eq(eventId), any(), any());
- verify(mNotificationManager, times(1)).cancelAsUser(eq(tag), eq(eventId), any());
+ verify(mNotificationManager, times(1)).notify(eq(tag), eq(eventId), any());
+ verify(mNotificationManager, times(1)).cancel(eq(tag), eq(eventId));
}
}
@@ -174,13 +174,13 @@
mManager.showNotification(100, NO_INTERNET, mCellNai, mWifiNai, null, false);
mManager.showNotification(101, LOST_INTERNET, mCellNai, mWifiNai, null, false);
- verify(mNotificationManager, never()).notifyAsUser(any(), anyInt(), any(), any());
+ verify(mNotificationManager, never()).notify(any(), anyInt(), any());
mManager.showNotification(102, NO_INTERNET, mWifiNai, mCellNai, null, false);
final int eventId = NO_INTERNET.eventId;
final String tag = NetworkNotificationManager.tagFor(102);
- verify(mNotificationManager, times(1)).notifyAsUser(eq(tag), eq(eventId), any(), any());
+ verify(mNotificationManager, times(1)).notify(eq(tag), eq(eventId), any());
}
@Test
@@ -191,7 +191,7 @@
mManager.showNotification(103, LOST_INTERNET, mWifiNai, mCellNai, null, false);
mManager.showNotification(104, NETWORK_SWITCH, mWifiNai, mCellNai, null, false);
- verify(mNotificationManager, never()).notifyAsUser(any(), anyInt(), any(), any());
+ verify(mNotificationManager, never()).notify(any(), anyInt(), any());
}
@Test
@@ -201,19 +201,16 @@
// Show first NO_INTERNET
mManager.showNotification(id, NO_INTERNET, mWifiNai, mCellNai, null, false);
- verify(mNotificationManager, times(1))
- .notifyAsUser(eq(tag), eq(NO_INTERNET.eventId), any(), any());
+ verify(mNotificationManager, times(1)).notify(eq(tag), eq(NO_INTERNET.eventId), any());
// Captive portal detection triggers SIGN_IN a bit later, clearing the previous NO_INTERNET
mManager.showNotification(id, SIGN_IN, mWifiNai, mCellNai, null, false);
- verify(mNotificationManager, times(1))
- .cancelAsUser(eq(tag), eq(NO_INTERNET.eventId), any());
- verify(mNotificationManager, times(1))
- .notifyAsUser(eq(tag), eq(SIGN_IN.eventId), any(), any());
+ verify(mNotificationManager, times(1)).cancel(eq(tag), eq(NO_INTERNET.eventId));
+ verify(mNotificationManager, times(1)).notify(eq(tag), eq(SIGN_IN.eventId), any());
// Network disconnects
mManager.clearNotification(id);
- verify(mNotificationManager, times(1)).cancelAsUser(eq(tag), eq(SIGN_IN.eventId), any());
+ verify(mNotificationManager, times(1)).cancel(eq(tag), eq(SIGN_IN.eventId));
}
@Test
@@ -223,18 +220,17 @@
// Show first SIGN_IN
mManager.showNotification(id, SIGN_IN, mWifiNai, mCellNai, null, false);
- verify(mNotificationManager, times(1))
- .notifyAsUser(eq(tag), eq(SIGN_IN.eventId), any(), any());
+ verify(mNotificationManager, times(1)).notify(eq(tag), eq(SIGN_IN.eventId), any());
reset(mNotificationManager);
// NO_INTERNET arrives after, but is ignored.
mManager.showNotification(id, NO_INTERNET, mWifiNai, mCellNai, null, false);
- verify(mNotificationManager, never()).cancelAsUser(any(), anyInt(), any());
- verify(mNotificationManager, never()).notifyAsUser(any(), anyInt(), any(), any());
+ verify(mNotificationManager, never()).cancel(any(), anyInt());
+ verify(mNotificationManager, never()).notify(any(), anyInt(), any());
// Network disconnects
mManager.clearNotification(id);
- verify(mNotificationManager, times(1)).cancelAsUser(eq(tag), eq(SIGN_IN.eventId), any());
+ verify(mNotificationManager, times(1)).cancel(eq(tag), eq(SIGN_IN.eventId));
}
@Test
@@ -246,24 +242,20 @@
// to previous type or not. If they are equal then clear the notification; if they are not
// equal then return.
mManager.showNotification(id, NO_INTERNET, mWifiNai, mCellNai, null, false);
- verify(mNotificationManager, times(1))
- .notifyAsUser(eq(tag), eq(NO_INTERNET.eventId), any(), any());
+ verify(mNotificationManager, times(1)).notify(eq(tag), eq(NO_INTERNET.eventId), any());
// Previous notification is NO_INTERNET and given type is NO_INTERNET too. The notification
// should be cleared.
mManager.clearNotification(id, NO_INTERNET);
- verify(mNotificationManager, times(1))
- .cancelAsUser(eq(tag), eq(NO_INTERNET.eventId), any());
+ verify(mNotificationManager, times(1)).cancel(eq(tag), eq(NO_INTERNET.eventId));
// SIGN_IN is popped-up.
mManager.showNotification(id, SIGN_IN, mWifiNai, mCellNai, null, false);
- verify(mNotificationManager, times(1))
- .notifyAsUser(eq(tag), eq(SIGN_IN.eventId), any(), any());
+ verify(mNotificationManager, times(1)).notify(eq(tag), eq(SIGN_IN.eventId), any());
// The notification type is not matching previous one, PARTIAL_CONNECTIVITY won't be
// cleared.
mManager.clearNotification(id, PARTIAL_CONNECTIVITY);
- verify(mNotificationManager, never())
- .cancelAsUser(eq(tag), eq(PARTIAL_CONNECTIVITY.eventId), any());
+ verify(mNotificationManager, never()).cancel(eq(tag), eq(PARTIAL_CONNECTIVITY.eventId));
}
}
diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java
index daa2627..2fa0914 100644
--- a/tests/net/java/com/android/server/connectivity/VpnTest.java
+++ b/tests/net/java/com/android/server/connectivity/VpnTest.java
@@ -45,6 +45,7 @@
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -106,6 +107,7 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.AdditionalAnswers;
import org.mockito.Answers;
import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
@@ -215,6 +217,8 @@
when(mContext.getOpPackageName()).thenReturn(TEST_VPN_PKG);
when(mContext.getSystemService(eq(Context.USER_SERVICE))).thenReturn(mUserManager);
when(mContext.getSystemService(eq(Context.APP_OPS_SERVICE))).thenReturn(mAppOps);
+ when(mContext.getSystemServiceName(NotificationManager.class))
+ .thenReturn(Context.NOTIFICATION_SERVICE);
when(mContext.getSystemService(eq(Context.NOTIFICATION_SERVICE)))
.thenReturn(mNotificationManager);
when(mContext.getSystemService(eq(Context.CONNECTIVITY_SERVICE)))
@@ -594,26 +598,23 @@
// Don't show a notification for regular disconnected states.
vpn.updateState(DetailedState.DISCONNECTED, TAG);
- order.verify(mNotificationManager, atLeastOnce())
- .cancelAsUser(anyString(), anyInt(), eq(userHandle));
+ order.verify(mNotificationManager, atLeastOnce()).cancel(anyString(), anyInt());
// Start showing a notification for disconnected once always-on.
vpn.setAlwaysOnPackage(PKGS[0], false, null, mKeyStore);
- order.verify(mNotificationManager)
- .notifyAsUser(anyString(), anyInt(), any(), eq(userHandle));
+ order.verify(mNotificationManager).notify(anyString(), anyInt(), any());
// Stop showing the notification once connected.
vpn.updateState(DetailedState.CONNECTED, TAG);
- order.verify(mNotificationManager).cancelAsUser(anyString(), anyInt(), eq(userHandle));
+ order.verify(mNotificationManager).cancel(anyString(), anyInt());
// Show the notification if we disconnect again.
vpn.updateState(DetailedState.DISCONNECTED, TAG);
- order.verify(mNotificationManager)
- .notifyAsUser(anyString(), anyInt(), any(), eq(userHandle));
+ order.verify(mNotificationManager).notify(anyString(), anyInt(), any());
// Notification should be cleared after unsetting always-on package.
vpn.setAlwaysOnPackage(null, false, null, mKeyStore);
- order.verify(mNotificationManager).cancelAsUser(anyString(), anyInt(), eq(userHandle));
+ order.verify(mNotificationManager).cancel(anyString(), anyInt());
}
@Test
@@ -1272,6 +1273,10 @@
* Mock some methods of vpn object.
*/
private Vpn createVpn(@UserIdInt int userId) {
+ final Context asUserContext = mock(Context.class, AdditionalAnswers.delegatesTo(mContext));
+ doReturn(UserHandle.of(userId)).when(asUserContext).getUser();
+ when(mContext.createContextAsUser(eq(UserHandle.of(userId)), anyInt()))
+ .thenReturn(asUserContext);
return new Vpn(Looper.myLooper(), mContext, new TestDeps(), mNetService,
userId, mKeyStore, mSystemServices, mIkev2SessionCreator);
}