Merge "Remove NetdService usage from IpSecService"
diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
index 84d05c8..0f2ce01 100644
--- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
+++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
@@ -3302,7 +3302,7 @@
if (DEBUG) Slog.d(TAG, "Moved from LIGHT_STATE_ACTIVE to LIGHT_STATE_INACTIVE");
resetLightIdleManagementLocked();
scheduleLightAlarmLocked(mConstants.LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT,
- mConstants.FLEX_TIME_SHORT);
+ mConstants.FLEX_TIME_SHORT, true);
EventLogTags.writeDeviceIdleLight(mLightState, "no activity");
}
}
@@ -3377,7 +3377,7 @@
mLightState = LIGHT_STATE_PRE_IDLE;
EventLogTags.writeDeviceIdleLight(mLightState, reason);
scheduleLightAlarmLocked(mConstants.LIGHT_PRE_IDLE_TIMEOUT,
- mConstants.FLEX_TIME_SHORT);
+ mConstants.FLEX_TIME_SHORT, true);
break;
}
// Nothing active, fall through to immediately idle.
@@ -3396,7 +3396,7 @@
}
}
mMaintenanceStartTime = 0;
- scheduleLightAlarmLocked(mNextLightIdleDelay, mNextLightIdleDelayFlex);
+ scheduleLightAlarmLocked(mNextLightIdleDelay, mNextLightIdleDelayFlex, false);
mNextLightIdleDelay = Math.min(mConstants.LIGHT_MAX_IDLE_TIMEOUT,
(long) (mNextLightIdleDelay * mConstants.LIGHT_IDLE_FACTOR));
mNextLightIdleDelayFlex = Math.min(mConstants.LIGHT_MAX_IDLE_TIMEOUT_FLEX,
@@ -3420,7 +3420,7 @@
} else if (mCurLightIdleBudget > mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET) {
mCurLightIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET;
}
- scheduleLightAlarmLocked(mCurLightIdleBudget, mConstants.FLEX_TIME_SHORT);
+ scheduleLightAlarmLocked(mCurLightIdleBudget, mConstants.FLEX_TIME_SHORT, true);
if (DEBUG) Slog.d(TAG,
"Moved from LIGHT_STATE_IDLE to LIGHT_STATE_IDLE_MAINTENANCE.");
mLightState = LIGHT_STATE_IDLE_MAINTENANCE;
@@ -3431,7 +3431,8 @@
// We'd like to do maintenance, but currently don't have network
// connectivity... let's try to wait until the network comes back.
// We'll only wait for another full idle period, however, and then give up.
- scheduleLightAlarmLocked(mNextLightIdleDelay, mNextLightIdleDelayFlex / 2);
+ scheduleLightAlarmLocked(mNextLightIdleDelay,
+ mNextLightIdleDelayFlex / 2, true);
if (DEBUG) Slog.d(TAG, "Moved to LIGHT_WAITING_FOR_NETWORK.");
mLightState = LIGHT_STATE_WAITING_FOR_NETWORK;
EventLogTags.writeDeviceIdleLight(mLightState, reason);
@@ -3964,18 +3965,23 @@
}
}
- void scheduleLightAlarmLocked(long delay, long flex) {
+ @GuardedBy("this")
+ void scheduleLightAlarmLocked(long delay, long flex, boolean wakeup) {
if (DEBUG) {
- Slog.d(TAG, "scheduleLightAlarmLocked(" + delay
+ Slog.d(TAG, "scheduleLightAlarmLocked(wakeup=" + wakeup + ", " + delay
+ (mConstants.USE_WINDOW_ALARMS ? "/" + flex : "") + ")");
}
mNextLightAlarmTime = SystemClock.elapsedRealtime() + delay;
if (mConstants.USE_WINDOW_ALARMS) {
- mAlarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP, mNextLightAlarmTime, flex,
- "DeviceIdleController.light", mLightAlarmListener, mHandler);
+ mAlarmManager.setWindow(wakeup ? AlarmManager.ELAPSED_REALTIME_WAKEUP :
+ AlarmManager.ELAPSED_REALTIME,
+ mNextLightAlarmTime, flex, "DeviceIdleController.light", mLightAlarmListener,
+ mHandler);
} else {
- mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, mNextLightAlarmTime,
- "DeviceIdleController.light", mLightAlarmListener, mHandler);
+ mAlarmManager.set(wakeup ? AlarmManager.ELAPSED_REALTIME_WAKEUP :
+ AlarmManager.ELAPSED_REALTIME,
+ mNextLightAlarmTime, "DeviceIdleController.light", mLightAlarmListener,
+ mHandler);
}
}
diff --git a/core/api/current.txt b/core/api/current.txt
index c3b5b94..87f951e 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -9178,10 +9178,10 @@
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void disconnect();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean discoverServices();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean executeReliableWrite();
- method public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
- method public int getConnectionState(android.bluetooth.BluetoothDevice);
+ method @Deprecated public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
+ method @Deprecated public int getConnectionState(android.bluetooth.BluetoothDevice);
method public android.bluetooth.BluetoothDevice getDevice();
- method public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int[]);
+ method @Deprecated public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int[]);
method public android.bluetooth.BluetoothGattService getService(java.util.UUID);
method public java.util.List<android.bluetooth.BluetoothGattService> getServices();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean readCharacteristic(android.bluetooth.BluetoothGattCharacteristic);
@@ -26888,11 +26888,13 @@
method @NonNull public android.net.VpnService.Builder addDnsServer(@NonNull java.net.InetAddress);
method @NonNull public android.net.VpnService.Builder addDnsServer(@NonNull String);
method @NonNull public android.net.VpnService.Builder addRoute(@NonNull java.net.InetAddress, int);
+ method @NonNull public android.net.VpnService.Builder addRoute(@NonNull android.net.IpPrefix);
method @NonNull public android.net.VpnService.Builder addRoute(@NonNull String, int);
method @NonNull public android.net.VpnService.Builder addSearchDomain(@NonNull String);
method @NonNull public android.net.VpnService.Builder allowBypass();
method @NonNull public android.net.VpnService.Builder allowFamily(int);
method @Nullable public android.os.ParcelFileDescriptor establish();
+ method @NonNull public android.net.VpnService.Builder excludeRoute(@NonNull android.net.IpPrefix);
method @NonNull public android.net.VpnService.Builder setBlocking(boolean);
method @NonNull public android.net.VpnService.Builder setConfigureIntent(@NonNull android.app.PendingIntent);
method @NonNull public android.net.VpnService.Builder setHttpProxy(@NonNull android.net.ProxyInfo);
@@ -38281,9 +38283,11 @@
public abstract class CarrierService extends android.app.Service {
ctor public CarrierService();
- method public final void notifyCarrierNetworkChange(boolean);
+ method @Deprecated public final void notifyCarrierNetworkChange(boolean);
+ method public final void notifyCarrierNetworkChange(int, boolean);
method @CallSuper public android.os.IBinder onBind(android.content.Intent);
- method public abstract android.os.PersistableBundle onLoadConfig(android.service.carrier.CarrierIdentifier);
+ method @Deprecated public abstract android.os.PersistableBundle onLoadConfig(android.service.carrier.CarrierIdentifier);
+ method @Nullable public android.os.PersistableBundle onLoadConfig(int, @Nullable android.service.carrier.CarrierIdentifier);
field public static final String CARRIER_SERVICE_INTERFACE = "android.service.carrier.CarrierService";
}
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 389c335..5261019 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -11698,6 +11698,14 @@
field public static final int ROAMING_TYPE_UNKNOWN = 1; // 0x1
}
+ public final class SignalStrengthUpdateRequest implements android.os.Parcelable {
+ method public boolean isSystemThresholdReportingRequestedWhileIdle();
+ }
+
+ public static final class SignalStrengthUpdateRequest.Builder {
+ method @NonNull @RequiresPermission("android.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH") public android.telephony.SignalStrengthUpdateRequest.Builder setSystemThresholdReportingRequestedWhileIdle(boolean);
+ }
+
public final class SmsCbCmasInfo implements android.os.Parcelable {
ctor public SmsCbCmasInfo(int, int, int, int, int, int);
method public int describeContents();
@@ -12017,6 +12025,8 @@
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCarrierPrivilegeStatus(int);
method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List<java.lang.String> getCarrierPrivilegedPackagesForAllActiveSubscriptions();
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.CarrierRestrictionRules getCarrierRestrictionRules();
+ method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getCarrierServicePackageName();
+ method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getCarrierServicePackageNameForLogicalSlot(int);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCdmaEnhancedRoamingIndicatorDisplayNumber();
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMdn();
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMdn(int);
@@ -13634,6 +13644,7 @@
field public static final int PUBLISH_STATE_NOT_PUBLISHED = 2; // 0x2
field public static final int PUBLISH_STATE_OK = 1; // 0x1
field public static final int PUBLISH_STATE_OTHER_ERROR = 6; // 0x6
+ field public static final int PUBLISH_STATE_PUBLISHING = 7; // 0x7
field public static final int PUBLISH_STATE_RCS_PROVISION_ERROR = 4; // 0x4
field public static final int PUBLISH_STATE_REQUEST_TIMEOUT = 5; // 0x5
field public static final int PUBLISH_STATE_VOICE_PROVISION_ERROR = 3; // 0x3
@@ -13896,6 +13907,7 @@
package android.telephony.ims.stub {
public interface CapabilityExchangeEventListener {
+ method public default void onPublishUpdated(int, @NonNull String, int, @NonNull String) throws android.telephony.ims.ImsException;
method public void onRemoteCapabilityRequest(@NonNull android.net.Uri, @NonNull java.util.Set<java.lang.String>, @NonNull android.telephony.ims.stub.CapabilityExchangeEventListener.OptionsRequestCallback) throws android.telephony.ims.ImsException;
method public void onRequestPublishCapabilities(int) throws android.telephony.ims.ImsException;
method public void onUnpublish() throws android.telephony.ims.ImsException;
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 0171f0a..f9739a4 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -130,6 +130,7 @@
import android.net.IEthernetManager;
import android.net.IIpSecService;
import android.net.INetworkPolicyManager;
+import android.net.INetworkStatsService;
import android.net.IPacProxyManager;
import android.net.IVpnManager;
import android.net.IpSecManager;
@@ -981,7 +982,11 @@
new CachedServiceFetcher<NetworkStatsManager>() {
@Override
public NetworkStatsManager createService(ContextImpl ctx) throws ServiceNotFoundException {
- return new NetworkStatsManager(ctx.getOuterContext());
+ // TODO: Replace with an initializer in the module, see
+ // {@code ConnectivityFrameworkInitializer}.
+ final INetworkStatsService service = INetworkStatsService.Stub.asInterface(
+ ServiceManager.getServiceOrThrow(Context.NETWORK_STATS_SERVICE));
+ return new NetworkStatsManager(ctx.getOuterContext(), service);
}});
registerService(Context.PERSISTENT_DATA_BLOCK_SERVICE, PersistentDataBlockManager.class,
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index b23c3eb..5612e7c 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -56,7 +56,7 @@
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceManager;
-import android.os.SystemProperties;
+import android.sysprop.BluetoothProperties;
import android.util.Log;
import android.util.Pair;
@@ -1337,7 +1337,7 @@
return true;
}
Log.e(TAG, "factoryReset(): Setting persist.bluetooth.factoryreset to retry later");
- SystemProperties.set("persist.bluetooth.factoryreset", "true");
+ BluetoothProperties.factory_reset(true);
} catch (RemoteException e) {
Log.e(TAG, "", e);
} finally {
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index 4e7c01a..fe8d1ba 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -1806,32 +1806,33 @@
}
/**
- * Not supported - please use {@link BluetoothManager#getConnectedDevices(int)}
+ * @deprecated Not supported - please use {@link BluetoothManager#getConnectedDevices(int)}
* with {@link BluetoothProfile#GATT} as argument
- *
* @throws UnsupportedOperationException
*/
@Override
@RequiresNoPermission
+ @Deprecated
public int getConnectionState(BluetoothDevice device) {
throw new UnsupportedOperationException("Use BluetoothManager#getConnectionState instead.");
}
/**
- * Not supported - please use {@link BluetoothManager#getConnectedDevices(int)}
+ * @deprecated Not supported - please use {@link BluetoothManager#getConnectedDevices(int)}
* with {@link BluetoothProfile#GATT} as argument
*
* @throws UnsupportedOperationException
*/
@Override
@RequiresNoPermission
+ @Deprecated
public List<BluetoothDevice> getConnectedDevices() {
throw new UnsupportedOperationException(
"Use BluetoothManager#getConnectedDevices instead.");
}
/**
- * Not supported - please use
+ * @deprecated Not supported - please use
* {@link BluetoothManager#getDevicesMatchingConnectionStates(int, int[])}
* with {@link BluetoothProfile#GATT} as first argument
*
@@ -1839,6 +1840,7 @@
*/
@Override
@RequiresNoPermission
+ @Deprecated
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
throw new UnsupportedOperationException(
"Use BluetoothManager#getDevicesMatchingConnectionStates instead.");
diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java
index f913349..540e5a7 100644
--- a/core/java/android/bluetooth/le/BluetoothLeScanner.java
+++ b/core/java/android/bluetooth/le/BluetoothLeScanner.java
@@ -514,16 +514,27 @@
@Override
public void onScanResult(final ScanResult scanResult) {
Attributable.setAttributionSource(scanResult, mAttributionSource);
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "onScanResult() - mScannerId=" + mScannerId);
+ }
if (VDBG) Log.d(TAG, "onScanResult() - " + scanResult.toString());
// Check null in case the scan has been stopped
synchronized (this) {
- if (mScannerId <= 0) return;
+ if (mScannerId <= 0) {
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "Ignoring result as scan stopped.");
+ }
+ return;
+ };
}
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "onScanResult() - handler run");
+ }
mScanCallback.onScanResult(ScanSettings.CALLBACK_TYPE_ALL_MATCHES, scanResult);
}
});
diff --git a/core/java/android/net/VpnService.java b/core/java/android/net/VpnService.java
index 2ced056..1ae1b05 100644
--- a/core/java/android/net/VpnService.java
+++ b/core/java/android/net/VpnService.java
@@ -41,6 +41,7 @@
import android.os.ServiceManager;
import android.os.UserHandle;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.net.NetworkUtilsInternal;
import com.android.internal.net.VpnConfig;
@@ -50,6 +51,7 @@
import java.net.InetAddress;
import java.net.Socket;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Set;
@@ -471,6 +473,13 @@
}
}
+ private static void checkNonPrefixBytes(@NonNull InetAddress address, int prefixLength) {
+ final IpPrefix prefix = new IpPrefix(address, prefixLength);
+ if (!prefix.getAddress().equals(address)) {
+ throw new IllegalArgumentException("Bad address");
+ }
+ }
+
/**
* Helper class to create a VPN interface. This class should be always
* used within the scope of the outer {@link VpnService}.
@@ -481,9 +490,9 @@
private final VpnConfig mConfig = new VpnConfig();
@UnsupportedAppUsage
- private final List<LinkAddress> mAddresses = new ArrayList<LinkAddress>();
+ private final List<LinkAddress> mAddresses = new ArrayList<>();
@UnsupportedAppUsage
- private final List<RouteInfo> mRoutes = new ArrayList<RouteInfo>();
+ private final List<RouteInfo> mRoutes = new ArrayList<>();
public Builder() {
mConfig.user = VpnService.this.getClass().getName();
@@ -555,7 +564,6 @@
throw new IllegalArgumentException("Bad address");
}
mAddresses.add(new LinkAddress(address, prefixLength));
- mConfig.updateAllowedFamilies(address);
return this;
}
@@ -579,28 +587,68 @@
* Add a network route to the VPN interface. Both IPv4 and IPv6
* routes are supported.
*
+ * If a route with the same destination is already present, its type will be updated.
+ *
+ * @throws IllegalArgumentException if the route is invalid.
+ */
+ @NonNull
+ private Builder addRoute(@NonNull IpPrefix prefix, int type) {
+ check(prefix.getAddress(), prefix.getPrefixLength());
+
+ final RouteInfo newRoute = new RouteInfo(prefix, /* gateway */
+ null, /* interface */ null, type);
+
+ final int index = findRouteIndexByDestination(newRoute);
+
+ if (index == -1) {
+ mRoutes.add(newRoute);
+ } else {
+ mRoutes.set(index, newRoute);
+ }
+
+ return this;
+ }
+
+ /**
+ * Add a network route to the VPN interface. Both IPv4 and IPv6
+ * routes are supported.
+ *
* Adding a route implicitly allows traffic from that address family
* (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily
*
+ * Calling this method overrides previous calls to {@link #excludeRoute} for the same
+ * destination.
+ *
+ * If multiple routes match the packet destination, route with the longest prefix takes
+ * precedence.
+ *
* @throws IllegalArgumentException if the route is invalid.
*/
@NonNull
public Builder addRoute(@NonNull InetAddress address, int prefixLength) {
- check(address, prefixLength);
+ checkNonPrefixBytes(address, prefixLength);
- int offset = prefixLength / 8;
- byte[] bytes = address.getAddress();
- if (offset < bytes.length) {
- for (bytes[offset] <<= prefixLength % 8; offset < bytes.length; ++offset) {
- if (bytes[offset] != 0) {
- throw new IllegalArgumentException("Bad address");
- }
- }
- }
- mRoutes.add(new RouteInfo(new IpPrefix(address, prefixLength), null, null,
- RouteInfo.RTN_UNICAST));
- mConfig.updateAllowedFamilies(address);
- return this;
+ return addRoute(new IpPrefix(address, prefixLength), RouteInfo.RTN_UNICAST);
+ }
+
+ /**
+ * Add a network route to the VPN interface. Both IPv4 and IPv6
+ * routes are supported.
+ *
+ * Adding a route implicitly allows traffic from that address family
+ * (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily
+ *
+ * Calling this method overrides previous calls to {@link #excludeRoute} for the same
+ * destination.
+ *
+ * If multiple routes match the packet destination, route with the longest prefix takes
+ * precedence.
+ *
+ * @throws IllegalArgumentException if the route is invalid.
+ */
+ @NonNull
+ public Builder addRoute(@NonNull IpPrefix prefix) {
+ return addRoute(prefix, RouteInfo.RTN_UNICAST);
}
/**
@@ -611,6 +659,12 @@
* Adding a route implicitly allows traffic from that address family
* (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily
*
+ * Calling this method overrides previous calls to {@link #excludeRoute} for the same
+ * destination.
+ *
+ * If multiple routes match the packet destination, route with the longest prefix takes
+ * precedence.
+ *
* @throws IllegalArgumentException if the route is invalid.
* @see #addRoute(InetAddress, int)
*/
@@ -620,6 +674,23 @@
}
/**
+ * Exclude a network route from the VPN interface. Both IPv4 and IPv6
+ * routes are supported.
+ *
+ * Calling this method overrides previous calls to {@link #addRoute} for the same
+ * destination.
+ *
+ * If multiple routes match the packet destination, route with the longest prefix takes
+ * precedence.
+ *
+ * @throws IllegalArgumentException if the route is invalid.
+ */
+ @NonNull
+ public Builder excludeRoute(@NonNull IpPrefix prefix) {
+ return addRoute(prefix, RouteInfo.RTN_THROW);
+ }
+
+ /**
* Add a DNS server to the VPN connection. Both IPv4 and IPv6
* addresses are supported. If none is set, the DNS servers of
* the default network will be used.
@@ -900,5 +971,23 @@
throw new IllegalStateException(e);
}
}
+
+ private int findRouteIndexByDestination(RouteInfo route) {
+ for (int i = 0; i < mRoutes.size(); i++) {
+ if (mRoutes.get(i).getDestination().equals(route.getDestination())) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Method for testing, to observe mRoutes while builder is being used.
+ * @hide
+ */
+ @VisibleForTesting
+ public List<RouteInfo> routes() {
+ return Collections.unmodifiableList(mRoutes);
+ }
}
}
diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java
index ddb6533..d974e0c 100644
--- a/core/java/android/os/Trace.java
+++ b/core/java/android/os/Trace.java
@@ -131,6 +131,10 @@
private static native void nativeAsyncTraceBegin(long tag, String name, int cookie);
@FastNative
private static native void nativeAsyncTraceEnd(long tag, String name, int cookie);
+ @FastNative
+ private static native void nativeInstant(long tag, String name);
+ @FastNative
+ private static native void nativeInstantForTrack(long tag, String trackName, String name);
private Trace() {
}
@@ -258,6 +262,42 @@
}
/**
+ * Writes a trace message to indicate that a given section of code was invoked.
+ *
+ * @param traceTag The trace tag.
+ * @param methodName The method name to appear in the trace.
+ * @hide
+ */
+ public static void instant(long traceTag, String methodName) {
+ if (methodName == null) {
+ throw new IllegalArgumentException("methodName cannot be null");
+ }
+ if (isTagEnabled(traceTag)) {
+ nativeInstant(traceTag, methodName);
+ }
+ }
+
+ /**
+ * Writes a trace message to indicate that a given section of code was invoked.
+ *
+ * @param traceTag The trace tag.
+ * @param trackName The track where the event should appear in the trace.
+ * @param methodName The method name to appear in the trace.
+ * @hide
+ */
+ public static void instantForTrack(long traceTag, String trackName, String methodName) {
+ if (trackName == null) {
+ throw new IllegalArgumentException("trackName cannot be null");
+ }
+ if (methodName == null) {
+ throw new IllegalArgumentException("methodName cannot be null");
+ }
+ if (isTagEnabled(traceTag)) {
+ nativeInstantForTrack(traceTag, trackName, methodName);
+ }
+ }
+
+ /**
* Checks whether or not tracing is currently enabled. This is useful to avoid intermediate
* string creation for trace sections that require formatting. It is not necessary
* to guard all Trace method calls as they internally already check this. However it is
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index 9f3a847..0adc00e 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -5374,5 +5374,21 @@
*/
public static final String COLUMN_NR_ADVANCED_CALLING_ENABLED =
"nr_advanced_calling_enabled";
+
+ /**
+ * TelephonyProvider column name for the phone number from source CARRIER
+ *
+ * @hide
+ */
+ public static final String COLUMN_PHONE_NUMBER_SOURCE_CARRIER =
+ "phone_number_source_carrier";
+
+ /**
+ * TelephonyProvider column name for the phone number from source IMS
+ *
+ * @hide
+ */
+ public static final String COLUMN_PHONE_NUMBER_SOURCE_IMS =
+ "phone_number_source_ims";
}
}
diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java
index 859fd80..e7f8920 100644
--- a/core/java/android/telephony/TelephonyRegistryManager.java
+++ b/core/java/android/telephony/TelephonyRegistryManager.java
@@ -285,6 +285,8 @@
* UI. There is no timeout associated with showing this UX, so a carrier app must be sure to
* call with active set to false sometime after calling with it set to {@code true}.
* <p>
+ * This will apply to all subscriptions the carrier app has carrier privileges on.
+ * <p>
* Requires Permission: calling app has carrier privileges.
*
* @param active Whether the carrier network change is or shortly will be
@@ -300,6 +302,31 @@
}
/**
+ * Informs the system of an intentional upcoming carrier network change by a carrier app on the
+ * given {@code subscriptionId}. This call only used to allow the system to provide alternative
+ * UI while telephony is performing an action that may result in intentional, temporary network
+ * lack of connectivity.
+ * <p>
+ * Based on the active parameter passed in, this method will either show or hide the
+ * alternative UI. There is no timeout associated with showing this UX, so a carrier app must be
+ * sure to call with active set to false sometime after calling with it set to {@code true}.
+ * <p>
+ * Requires Permission: calling app has carrier privileges.
+ *
+ * @param subscriptionId the subscription of the carrier network.
+ * @param active whether the carrier network change is or shortly will be active. Set this value
+ * to true to begin showing alternative UI and false to stop.
+ * @see TelephonyManager#hasCarrierPrivileges
+ */
+ public void notifyCarrierNetworkChange(int subscriptionId, boolean active) {
+ try {
+ sRegistry.notifyCarrierNetworkChangeWithSubId(subscriptionId, active);
+ } catch (RemoteException ex) {
+ // system server crash
+ }
+ }
+
+ /**
* Notify call state changed on certain subscription.
*
* @param slotIndex for which call state changed. Can be derived from subId except when subId is
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index cf12955..2320434 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -26842,44 +26842,38 @@
* Handles drag events sent by the system following a call to
* {@link android.view.View#startDragAndDrop(ClipData,DragShadowBuilder,Object,int)
* startDragAndDrop()}.
- *<p>
- * When the system calls this method, it passes a
- * {@link android.view.DragEvent} object. A call to
- * {@link android.view.DragEvent#getAction()} returns one of the action type constants defined
- * in DragEvent. The method uses these to determine what is happening in the drag and drop
- * operation.
- * </p>
* <p>
- * The default implementation returns false, except if an {@link OnReceiveContentListener}
- * is {@link #setOnReceiveContentListener set} for this view. If an
- * {@link OnReceiveContentListener} is set, the default implementation...
+ * The system calls this method and passes a {@link DragEvent} object in response to drag and
+ * drop events. This method can then call {@link DragEvent#getAction()} to determine the state
+ * of the drag and drop operation.
+ * <p>
+ * The default implementation returns {@code false} unless an {@link OnReceiveContentListener}
+ * has been set for this view (see {@link #setOnReceiveContentListener}), in which case
+ * the default implementation does the following:
* <ul>
- * <li>returns true for an
- * {@link android.view.DragEvent#ACTION_DRAG_STARTED ACTION_DRAG_STARTED} event
- * <li>calls {@link #performReceiveContent} for an
- * {@link android.view.DragEvent#ACTION_DROP ACTION_DROP} event
- * <li>returns true for an {@link android.view.DragEvent#ACTION_DROP ACTION_DROP} event, if
- * the listener consumed some or all of the content
+ * <li>Returns {@code true} for an
+ * {@link DragEvent#ACTION_DRAG_STARTED ACTION_DRAG_STARTED} event
+ * <li>Calls {@link #performReceiveContent} for an
+ * {@link DragEvent#ACTION_DROP ACTION_DROP} event
+ * <li>Returns {@code true} for an {@link DragEvent#ACTION_DROP ACTION_DROP} event if the
+ * {@code OnReceiveContentListener} consumed some or all of the content
* </ul>
- * </p>
*
- * @param event The {@link android.view.DragEvent} sent by the system.
- * The {@link android.view.DragEvent#getAction()} method returns an action type constant defined
- * in DragEvent, indicating the type of drag event represented by this object.
- * @return {@code true} if the method was successful, otherwise {@code false}.
- * <p>
- * The method should return {@code true} in response to an action type of
- * {@link android.view.DragEvent#ACTION_DRAG_STARTED} to receive drag events for the current
- * operation.
- * </p>
- * <p>
- * The method should also return {@code true} in response to an action type of
- * {@link android.view.DragEvent#ACTION_DROP} if it consumed the drop, or
- * {@code false} if it didn't.
- * </p>
- * <p>
- * For all other events, the return value is ignored.
- * </p>
+ * @param event The {@link DragEvent} object sent by the system. The
+ * {@link DragEvent#getAction()} method returns an action type constant that indicates the
+ * type of drag event represented by this object.
+ * @return {@code true} if the method successfully handled the drag event, otherwise
+ * {@code false}.
+ * <p>
+ * The method must return {@code true} in response to an
+ * {@link DragEvent#ACTION_DRAG_STARTED ACTION_DRAG_STARTED} action type to continue to
+ * receive drag events for the current drag and drop operation.
+ * <p>
+ * The method should return {@code true} in response to an
+ * {@link DragEvent#ACTION_DROP ACTION_DROP} action type if the dropped data was consumed
+ * (at least partially); {@code false}, if none of the data was consumed.
+ * <p>
+ * For all other events, the return value is {@code false}.
*/
public boolean onDragEvent(DragEvent event) {
if (mListenerInfo == null || mListenerInfo.mOnReceiveContentListener == null) {
@@ -28844,27 +28838,27 @@
}
/**
- * Interface definition for a callback to be invoked when a drag is being dispatched
- * to this view. The callback will be invoked before the hosting view's own
- * onDrag(event) method. If the listener wants to fall back to the hosting view's
- * onDrag(event) behavior, it should return 'false' from this callback.
+ * Interface definition for a listener that's invoked when a drag event is dispatched to this
+ * view. The listener is invoked before the view's own
+ * {@link #onDragEvent(DragEvent)} method. To fall back to the view's
+ * {@code onDragEvent(DragEvent)} behavior, return {@code false} from the listener method.
*
* <div class="special reference">
- * <h3>Developer Guides</h3>
- * <p>For a guide to implementing drag and drop features, read the
- * <a href="{@docRoot}guide/topics/ui/drag-drop.html">Drag and Drop</a> developer guide.</p>
+ * <h3>Developer Guides</h3>
+ * <p>For a guide to implementing drag and drop features, see the
+ * <a href="{@docRoot}guide/topics/ui/drag-drop.html">Drag and drop</a> developer guide.</p>
* </div>
*/
public interface OnDragListener {
/**
- * Called when a drag event is dispatched to a view. This allows listeners
- * to get a chance to override base View behavior.
+ * Called when a drag event is dispatched to a view. Enables listeners to override the
+ * base behavior provided by {@link #onDragEvent(DragEvent)}.
*
- * @param v The View that received the drag event.
- * @param event The {@link android.view.DragEvent} object for the drag event.
- * @return {@code true} if the drag event was handled successfully, or {@code false}
- * if the drag event was not handled. Note that {@code false} will trigger the View
- * to call its {@link #onDragEvent(DragEvent) onDragEvent()} handler.
+ * @param v The {@code View} that received the drag event.
+ * @param event The event object for the drag event.
+ * @return {@code true} if the drag event was handled successfully; {@code false}, if the
+ * drag event was not handled. <b>Note:</b> A {@code false} return value triggers the
+ * view's {@link #onDragEvent(DragEvent)} handler.
*/
boolean onDrag(View v, DragEvent event);
}
diff --git a/core/java/android/view/inputmethod/InputConnection.java b/core/java/android/view/inputmethod/InputConnection.java
index 5f036a3..4d7d182 100644
--- a/core/java/android/view/inputmethod/InputConnection.java
+++ b/core/java/android/view/inputmethod/InputConnection.java
@@ -770,20 +770,25 @@
boolean beginBatchEdit();
/**
- * Tell the editor that you are done with a batch edit previously
- * initiated with {@link #beginBatchEdit}. This ends the latest
- * batch only.
+ * Tell the editor that you are done with a batch edit previously initiated with
+ * {@link #beginBatchEdit()}. This ends the latest batch only.
*
- * <p><strong>IME authors:</strong> make sure you call this
- * exactly once for each call to {@link #beginBatchEdit}.</p>
+ * <p><strong>IME authors:</strong> make sure you call this exactly once for each call to
+ * {@link #beginBatchEdit()}.</p>
*
- * <p><strong>Editor authors:</strong> please be careful about
- * batch edit nesting. Updates still to be held back until the end
- * of the last batch edit.</p>
+ * <p><strong>Editor authors:</strong> please be careful about batch edit nesting. Updates still
+ * to be held back until the end of the last batch edit. In case you are delegating this API
+ * call to the one obtained from
+ * {@link android.widget.EditText#onCreateInputConnection(EditorInfo)}, there was an off-by-one
+ * that had returned {@code true} when its nested batch edit count becomes {@code 0} as a result
+ * of invoking this API. This bug is fixed in {@link android.os.Build.VERSION_CODES#TIRAMISU}.
+ * </p>
*
- * @return true if there is still a batch edit in progress after closing
- * the latest one (in other words, if the nesting count is > 0), false
- * otherwise or if the input connection is no longer valid.
+ * @return For editor authors, you must return {@code true} if a batch edit is still in progress
+ * after closing the latest one (in other words, if the nesting count is still a
+ * positive number). Return {@code false} otherwise. For IME authors, you will
+ * always receive {@code true} as long as the request was sent to the editor, and
+ * receive {@code false} only if the input connection is no longer valid.
*/
boolean endBatchEdit();
diff --git a/core/java/com/android/internal/net/VpnConfig.java b/core/java/com/android/internal/net/VpnConfig.java
index 2e7629a..2ae56f8 100644
--- a/core/java/com/android/internal/net/VpnConfig.java
+++ b/core/java/com/android/internal/net/VpnConfig.java
@@ -34,8 +34,6 @@
import android.os.Parcelable;
import android.os.UserHandle;
-import java.net.Inet4Address;
-import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -93,8 +91,8 @@
public String interfaze;
public String session;
public int mtu = -1;
- public List<LinkAddress> addresses = new ArrayList<LinkAddress>();
- public List<RouteInfo> routes = new ArrayList<RouteInfo>();
+ public List<LinkAddress> addresses = new ArrayList<>();
+ public List<RouteInfo> routes = new ArrayList<>();
public List<String> dnsServers;
public List<String> searchDomains;
public List<String> allowedApplications;
@@ -114,12 +112,32 @@
public VpnConfig() {
}
- public void updateAllowedFamilies(InetAddress address) {
- if (address instanceof Inet4Address) {
- allowIPv4 = true;
- } else {
- allowIPv6 = true;
- }
+ public VpnConfig(VpnConfig other) {
+ user = other.user;
+ interfaze = other.interfaze;
+ session = other.session;
+ mtu = other.mtu;
+ addresses = copyOf(other.addresses);
+ routes = copyOf(other.routes);
+ dnsServers = copyOf(other.dnsServers);
+ searchDomains = copyOf(other.searchDomains);
+ allowedApplications = copyOf(other.allowedApplications);
+ disallowedApplications = copyOf(other.disallowedApplications);
+ configureIntent = other.configureIntent;
+ startTime = other.startTime;
+ legacy = other.legacy;
+ blocking = other.blocking;
+ allowBypass = other.allowBypass;
+ allowIPv4 = other.allowIPv4;
+ allowIPv6 = other.allowIPv6;
+ isMetered = other.isMetered;
+ underlyingNetworks = other.underlyingNetworks != null ? Arrays.copyOf(
+ other.underlyingNetworks, other.underlyingNetworks.length) : null;
+ proxyInfo = other.proxyInfo;
+ }
+
+ private static <T> List<T> copyOf(List<T> list) {
+ return list != null ? new ArrayList<>(list) : null;
}
public void addLegacyRoutes(String routesStr) {
@@ -131,7 +149,6 @@
//each route is ip/prefix
RouteInfo info = new RouteInfo(new IpPrefix(route), null, null, RouteInfo.RTN_UNICAST);
this.routes.add(info);
- updateAllowedFamilies(info.getDestination().getAddress());
}
}
@@ -144,7 +161,6 @@
//each address is ip/prefix
LinkAddress addr = new LinkAddress(address);
this.addresses.add(addr);
- updateAllowedFamilies(addr.getAddress());
}
}
diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index 6ba0279..15d4246 100644
--- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -77,6 +77,7 @@
void notifySubscriptionInfoChanged();
void notifyOpportunisticSubscriptionInfoChanged();
void notifyCarrierNetworkChange(in boolean active);
+ void notifyCarrierNetworkChangeWithSubId(in int subId, in boolean active);
void notifyUserMobileDataStateChangedForPhoneId(in int phoneId, in int subId, in boolean state);
void notifyDisplayInfoChanged(int slotIndex, int subId, in TelephonyDisplayInfo telephonyDisplayInfo);
void notifyPhoneCapabilityChanged(in PhoneCapability capability);
diff --git a/core/java/com/android/internal/widget/EditableInputConnection.java b/core/java/com/android/internal/widget/EditableInputConnection.java
index 02ffe8c..040d78b 100644
--- a/core/java/com/android/internal/widget/EditableInputConnection.java
+++ b/core/java/com/android/internal/widget/EditableInputConnection.java
@@ -92,7 +92,7 @@
// contribution to mTextView's nested batch edit count is zero.
mTextView.endBatchEdit();
mBatchEditNesting--;
- return true;
+ return mBatchEditNesting > 0;
}
}
return false;
diff --git a/core/jni/android_os_Trace.cpp b/core/jni/android_os_Trace.cpp
index f67007c..85fd5d9 100644
--- a/core/jni/android_os_Trace.cpp
+++ b/core/jni/android_os_Trace.cpp
@@ -90,6 +90,22 @@
atrace_set_tracing_enabled(enabled);
}
+static void android_os_Trace_nativeInstant(JNIEnv* env, jclass,
+ jlong tag, jstring nameStr) {
+ withString(env, nameStr, [tag](char* str) {
+ atrace_instant(tag, str);
+ });
+}
+
+static void android_os_Trace_nativeInstantForTrack(JNIEnv* env, jclass,
+ jlong tag, jstring trackStr, jstring nameStr) {
+ withString(env, trackStr, [env, tag, nameStr](char* track) {
+ withString(env, nameStr, [tag, track](char* name) {
+ atrace_instant_for_track(tag, track, name);
+ });
+ });
+}
+
static const JNINativeMethod gTraceMethods[] = {
/* name, signature, funcPtr */
{ "nativeSetAppTracingAllowed",
@@ -116,6 +132,12 @@
{ "nativeAsyncTraceEnd",
"(JLjava/lang/String;I)V",
(void*)android_os_Trace_nativeAsyncTraceEnd },
+ { "nativeInstant",
+ "(JLjava/lang/String;)V",
+ (void*)android_os_Trace_nativeInstant },
+ { "nativeInstantForTrack",
+ "(JLjava/lang/String;Ljava/lang/String;)V",
+ (void*)android_os_Trace_nativeInstantForTrack },
// ----------- @CriticalNative ----------------
{ "nativeGetEnabledTags",
diff --git a/core/jni/android_view_InputEventReceiver.cpp b/core/jni/android_view_InputEventReceiver.cpp
index a699f91..7d0f60a 100644
--- a/core/jni/android_view_InputEventReceiver.cpp
+++ b/core/jni/android_view_InputEventReceiver.cpp
@@ -447,10 +447,6 @@
skipCallbacks = true;
}
}
-
- if (skipCallbacks) {
- mInputConsumer.sendFinishedSignal(seq, false);
- }
}
}
diff --git a/packages/ConnectivityT/framework-t/src/android/app/usage/NetworkStatsManager.java b/packages/ConnectivityT/framework-t/src/android/app/usage/NetworkStatsManager.java
index 8a6c85d..ca83309 100644
--- a/packages/ConnectivityT/framework-t/src/android/app/usage/NetworkStatsManager.java
+++ b/packages/ConnectivityT/framework-t/src/android/app/usage/NetworkStatsManager.java
@@ -45,8 +45,6 @@
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.ServiceManager.ServiceNotFoundException;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.DataUnit;
@@ -135,15 +133,6 @@
private int mFlags;
- /**
- * {@hide}
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public NetworkStatsManager(Context context) throws ServiceNotFoundException {
- this(context, INetworkStatsService.Stub.asInterface(
- ServiceManager.getServiceOrThrow(Context.NETWORK_STATS_SERVICE)));
- }
-
/** @hide */
@VisibleForTesting
public NetworkStatsManager(Context context, INetworkStatsService service) {
diff --git a/packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt b/packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt
index c1db8ed..9006417 100644
--- a/packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt
@@ -16,6 +16,7 @@
package com.android.systemui.log
+import android.os.Trace
import android.util.Log
import com.android.systemui.log.dagger.LogModule
import java.io.PrintWriter
@@ -169,7 +170,7 @@
buffer.add(message as LogMessageImpl)
if (logcatEchoTracker.isBufferLoggable(name, message.level) ||
logcatEchoTracker.isTagLoggable(message.tag, message.level)) {
- echoToLogcat(message)
+ echo(message)
}
}
@@ -219,7 +220,7 @@
pw.println(message.printer(message))
}
- private fun echoToLogcat(message: LogMessage) {
+ private fun echo(message: LogMessage) {
val strMessage = message.printer(message)
when (message.level) {
LogLevel.VERBOSE -> Log.v(message.tag, strMessage)
@@ -229,6 +230,7 @@
LogLevel.ERROR -> Log.e(message.tag, strMessage)
LogLevel.WTF -> Log.wtf(message.tag, strMessage)
}
+ Trace.instantForTrack(Trace.TRACE_TAG_APP, "UI Events", strMessage)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/RecommendationViewHolder.kt b/packages/SystemUI/src/com/android/systemui/media/RecommendationViewHolder.kt
index 142628c..c0f79d5 100644
--- a/packages/SystemUI/src/com/android/systemui/media/RecommendationViewHolder.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/RecommendationViewHolder.kt
@@ -21,7 +21,6 @@
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
-import androidx.annotation.IntegerRes
import com.android.systemui.R
import com.android.systemui.util.animation.TransitionLayout
@@ -47,14 +46,14 @@
itemView.requireViewById(R.id.media_cover4_container),
itemView.requireViewById(R.id.media_cover5_container),
itemView.requireViewById(R.id.media_cover6_container))
- val mediaCoverItemsResIds = listOf<@IntegerRes Int>(
+ val mediaCoverItemsResIds = listOf<Int>(
R.id.media_cover1,
R.id.media_cover2,
R.id.media_cover3,
R.id.media_cover4,
R.id.media_cover5,
R.id.media_cover6)
- val mediaCoverContainersResIds = listOf<@IntegerRes Int>(
+ val mediaCoverContainersResIds = listOf<Int>(
R.id.media_cover1_container,
R.id.media_cover2_container,
R.id.media_cover3_container,
diff --git a/services/art-profile b/services/art-profile
index af58bca..2d9e95e 100644
--- a/services/art-profile
+++ b/services/art-profile
@@ -1464,7 +1464,7 @@
HPLcom/android/server/DeviceIdleController;->resetIdleManagementLocked()V+]Lcom/android/server/AnyMotionDetector;Lcom/android/server/AnyMotionDetector;]Lcom/android/server/DeviceIdleController;Lcom/android/server/DeviceIdleController;
HPLcom/android/server/DeviceIdleController;->resetLightIdleManagementLocked()V+]Lcom/android/server/DeviceIdleController;Lcom/android/server/DeviceIdleController;
HPLcom/android/server/DeviceIdleController;->scheduleAlarmLocked(JZ)V+]Landroid/app/AlarmManager;Landroid/app/AlarmManager;
-HPLcom/android/server/DeviceIdleController;->scheduleLightAlarmLocked(JJ)V+]Landroid/app/AlarmManager;Landroid/app/AlarmManager;
+HPLcom/android/server/DeviceIdleController;->scheduleLightAlarmLocked(JJZ)V+]Landroid/app/AlarmManager;Landroid/app/AlarmManager;
HPLcom/android/server/DeviceIdleController;->scheduleMotionRegistrationAlarmLocked()V+]Lcom/android/server/DeviceIdleController$Injector;Lcom/android/server/DeviceIdleController$Injector;]Landroid/app/AlarmManager;Landroid/app/AlarmManager;
HSPLcom/android/server/DeviceIdleController;->scheduleMotionTimeoutAlarmLocked()V+]Landroid/app/AlarmManager;Landroid/app/AlarmManager;]Lcom/android/server/DeviceIdleController$Injector;Lcom/android/server/DeviceIdleController$Injector;
HPLcom/android/server/DeviceIdleController;->scheduleReportActiveLocked(Ljava/lang/String;I)V+]Lcom/android/server/DeviceIdleController$MyHandler;Lcom/android/server/DeviceIdleController$MyHandler;
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 91cd2f6..d7c1cfb 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -366,7 +366,7 @@
private List<BarringInfo> mBarringInfo = null;
- private boolean mCarrierNetworkChangeState = false;
+ private boolean[] mCarrierNetworkChangeState = null;
private PhoneCapability mPhoneCapability = null;
@@ -675,6 +675,7 @@
mOutgoingCallEmergencyNumber = copyOf(mOutgoingCallEmergencyNumber, mNumPhones);
mOutgoingSmsEmergencyNumber = copyOf(mOutgoingSmsEmergencyNumber, mNumPhones);
mTelephonyDisplayInfos = copyOf(mTelephonyDisplayInfos, mNumPhones);
+ mCarrierNetworkChangeState = copyOf(mCarrierNetworkChangeState, mNumPhones);
mIsDataEnabled= copyOf(mIsDataEnabled, mNumPhones);
mDataEnabledReason = copyOf(mDataEnabledReason, mNumPhones);
mAllowedNetworkTypeReason = copyOf(mAllowedNetworkTypeReason, mNumPhones);
@@ -720,6 +721,7 @@
mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
mPreciseDataConnectionStates.add(new ArrayMap<>());
mBarringInfo.add(i, new BarringInfo());
+ mCarrierNetworkChangeState[i] = false;
mTelephonyDisplayInfos[i] = null;
mIsDataEnabled[i] = false;
mDataEnabledReason[i] = TelephonyManager.DATA_ENABLED_REASON_USER;
@@ -784,6 +786,7 @@
mOutgoingCallEmergencyNumber = new EmergencyNumber[numPhones];
mOutgoingSmsEmergencyNumber = new EmergencyNumber[numPhones];
mBarringInfo = new ArrayList<>();
+ mCarrierNetworkChangeState = new boolean[numPhones];
mTelephonyDisplayInfos = new TelephonyDisplayInfo[numPhones];
mPhysicalChannelConfigs = new ArrayList<>();
mAllowedNetworkTypeReason = new int[numPhones];
@@ -820,6 +823,7 @@
mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
mPreciseDataConnectionStates.add(new ArrayMap<>());
mBarringInfo.add(i, new BarringInfo());
+ mCarrierNetworkChangeState[i] = false;
mTelephonyDisplayInfos[i] = null;
mIsDataEnabled[i] = false;
mDataEnabledReason[i] = TelephonyManager.DATA_ENABLED_REASON_USER;
@@ -1230,7 +1234,7 @@
}
if (events.contains(TelephonyCallback.EVENT_CARRIER_NETWORK_CHANGED)) {
try {
- r.callback.onCarrierNetworkChange(mCarrierNetworkChangeState);
+ r.callback.onCarrierNetworkChange(mCarrierNetworkChangeState[r.phoneId]);
} catch (RemoteException ex) {
remove(r.binder);
}
@@ -1724,23 +1728,37 @@
throw new SecurityException("notifyCarrierNetworkChange without carrier privilege");
}
- synchronized (mRecords) {
- mCarrierNetworkChangeState = active;
- for (int subId : subIds) {
- int phoneId = getPhoneIdFromSubId(subId);
+ for (int subId : subIds) {
+ notifyCarrierNetworkChangeWithPermission(subId, active);
+ }
+ }
- if (VDBG) {
- log("notifyCarrierNetworkChange: active=" + active + "subId: " + subId);
- }
- for (Record r : mRecords) {
- if (r.matchTelephonyCallbackEvent(
- TelephonyCallback.EVENT_CARRIER_NETWORK_CHANGED)
- && idMatch(r, subId, phoneId)) {
- try {
- r.callback.onCarrierNetworkChange(active);
- } catch (RemoteException ex) {
- mRemoveList.add(r.binder);
- }
+ @Override
+ public void notifyCarrierNetworkChangeWithSubId(int subId, boolean active) {
+ if (!TelephonyPermissions.checkCarrierPrivilegeForSubId(mContext, subId)) {
+ throw new SecurityException(
+ "notifyCarrierNetworkChange without carrier privilege on subId " + subId);
+ }
+
+ notifyCarrierNetworkChangeWithPermission(subId, active);
+ }
+
+ private void notifyCarrierNetworkChangeWithPermission(int subId, boolean active) {
+ synchronized (mRecords) {
+ int phoneId = getPhoneIdFromSubId(subId);
+ mCarrierNetworkChangeState[phoneId] = active;
+
+ if (VDBG) {
+ log("notifyCarrierNetworkChange: active=" + active + "subId: " + subId);
+ }
+ for (Record r : mRecords) {
+ if (r.matchTelephonyCallbackEvent(
+ TelephonyCallback.EVENT_CARRIER_NETWORK_CHANGED)
+ && idMatch(r, subId, phoneId)) {
+ try {
+ r.callback.onCarrierNetworkChange(active);
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
}
}
}
@@ -2788,6 +2806,7 @@
pw.println("mOutgoingCallEmergencyNumber=" + mOutgoingCallEmergencyNumber[i]);
pw.println("mOutgoingSmsEmergencyNumber=" + mOutgoingSmsEmergencyNumber[i]);
pw.println("mBarringInfo=" + mBarringInfo.get(i));
+ pw.println("mCarrierNetworkChangeState=" + mCarrierNetworkChangeState[i]);
pw.println("mTelephonyDisplayInfo=" + mTelephonyDisplayInfos[i]);
pw.println("mIsDataEnabled=" + mIsDataEnabled);
pw.println("mDataEnabledReason=" + mDataEnabledReason);
@@ -2797,7 +2816,7 @@
pw.println("mLinkCapacityEstimateList=" + mLinkCapacityEstimateLists.get(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/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index bf4ef48..e145d03 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -1208,8 +1208,11 @@
for (RouteInfo route : mConfig.routes) {
lp.addRoute(route);
InetAddress address = route.getDestination().getAddress();
- allowIPv4 |= address instanceof Inet4Address;
- allowIPv6 |= address instanceof Inet6Address;
+
+ if (route.getType() == RouteInfo.RTN_UNICAST) {
+ allowIPv4 |= address instanceof Inet4Address;
+ allowIPv6 |= address instanceof Inet6Address;
+ }
}
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
index e472b06..d710308 100644
--- a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
@@ -1047,7 +1047,8 @@
verifyLightStateConditions(LIGHT_STATE_IDLE);
inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked(
longThat(l -> l == mConstants.LIGHT_IDLE_TIMEOUT),
- longThat(l -> l == mConstants.LIGHT_IDLE_TIMEOUT_INITIAL_FLEX));
+ longThat(l -> l == mConstants.LIGHT_IDLE_TIMEOUT_INITIAL_FLEX),
+ eq(false));
// Should just alternate between IDLE and IDLE_MAINTENANCE now.
@@ -1055,19 +1056,22 @@
verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked(
longThat(l -> l >= mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET),
- longThat(l -> l == mConstants.FLEX_TIME_SHORT));
+ longThat(l -> l == mConstants.FLEX_TIME_SHORT),
+ eq(true));
mDeviceIdleController.stepLightIdleStateLocked("testing");
verifyLightStateConditions(LIGHT_STATE_IDLE);
inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked(
longThat(l -> l > mConstants.LIGHT_IDLE_TIMEOUT),
- longThat(l -> l > mConstants.LIGHT_IDLE_TIMEOUT_INITIAL_FLEX));
+ longThat(l -> l > mConstants.LIGHT_IDLE_TIMEOUT_INITIAL_FLEX),
+ eq(false));
mDeviceIdleController.stepLightIdleStateLocked("testing");
verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked(
longThat(l -> l >= mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET),
- longThat(l -> l == mConstants.FLEX_TIME_SHORT));
+ longThat(l -> l == mConstants.FLEX_TIME_SHORT),
+ eq(true));
// Test that motion doesn't reset the idle timeout.
mDeviceIdleController.handleMotionDetectedLocked(50, "test");
@@ -1076,7 +1080,8 @@
verifyLightStateConditions(LIGHT_STATE_IDLE);
inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked(
longThat(l -> l > mConstants.LIGHT_IDLE_TIMEOUT),
- longThat(l -> l > mConstants.LIGHT_IDLE_TIMEOUT_INITIAL_FLEX));
+ longThat(l -> l > mConstants.LIGHT_IDLE_TIMEOUT_INITIAL_FLEX),
+ eq(false));
}
///////////////// EXIT conditions ///////////////////
diff --git a/telephony/java/android/service/carrier/CarrierService.java b/telephony/java/android/service/carrier/CarrierService.java
index d06ec11..ae91d4d 100644
--- a/telephony/java/android/service/carrier/CarrierService.java
+++ b/telephony/java/android/service/carrier/CarrierService.java
@@ -15,6 +15,8 @@
package android.service.carrier;
import android.annotation.CallSuper;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
@@ -22,9 +24,12 @@
import android.os.IBinder;
import android.os.PersistableBundle;
import android.os.ResultReceiver;
+import android.telephony.SubscriptionManager;
import android.telephony.TelephonyRegistryManager;
import android.util.Log;
+import com.android.internal.util.ArrayUtils;
+
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -87,7 +92,54 @@
* PersistableBundle} may be overridden by the system's default configuration service.
* </p>
*
- * @param id contains details about the current carrier that can be used do decide what
+ * @param id contains details about the current carrier that can be used to decide what
+ * configuration values to return. Instead of using details like MCCMNC to decide
+ * current carrier, it also contains subscription carrier id
+ * {@link android.telephony.TelephonyManager#getSimCarrierId()}, a platform-wide
+ * unique identifier for each carrier, CarrierConfigService can directly use carrier
+ * id as the key to look up the carrier info.
+ * @return a {@link PersistableBundle} object containing the configuration or null if default
+ * values should be used.
+ * @deprecated use {@link #onLoadConfig(int, CarrierIdentifier)} instead.
+ */
+ @Deprecated
+ public abstract PersistableBundle onLoadConfig(CarrierIdentifier id);
+
+ /**
+ * Override this method to set carrier configuration on the given {@code subscriptionId}.
+ * <p>
+ * This method will be called by telephony services to get carrier-specific configuration
+ * values. The returned config will be saved by the system until,
+ * <ol>
+ * <li>The carrier app package is updated, or</li>
+ * <li>The carrier app requests a reload with
+ * {@link android.telephony.CarrierConfigManager#notifyConfigChangedForSubId
+ * notifyConfigChangedForSubId}.</li>
+ * </ol>
+ * This method can be called after a SIM card loads, which may be before or after boot.
+ * </p>
+ * <p>
+ * This method should not block for a long time. If expensive operations (e.g. network access)
+ * are required, this method can schedule the work and return null. Then, use
+ * {@link android.telephony.CarrierConfigManager#notifyConfigChangedForSubId
+ * notifyConfigChangedForSubId} to trigger a reload when the config is ready.
+ * </p>
+ * <p>
+ * Implementations should use the keys defined in {@link android.telephony.CarrierConfigManager
+ * CarrierConfigManager}. Any configuration values not set in the returned {@link
+ * PersistableBundle} may be overridden by the system's default configuration service.
+ * </p>
+ * <p>
+ * By default, this method just calls {@link #onLoadConfig(CarrierIdentifier)} with specified
+ * CarrierIdentifier {@code id}. Carrier app with target SDK
+ * {@link android.os.Build.VERSION_CODES#TIRAMISU} and above should override this method to
+ * load carrier configuration on the given {@code subscriptionId}.
+ * Note that {@link #onLoadConfig(CarrierIdentifier)} is still called prior to
+ * {@link android.os.Build.VERSION_CODES#TIRAMISU}.
+ * </p>
+ *
+ * @param subscriptionId the subscription on which the carrier app should load configuration
+ * @param id contains details about the current carrier that can be used to decide what
* configuration values to return. Instead of using details like MCCMNC to decide
* current carrier, it also contains subscription carrier id
* {@link android.telephony.TelephonyManager#getSimCarrierId()}, a platform-wide
@@ -96,7 +148,11 @@
* @return a {@link PersistableBundle} object containing the configuration or null if default
* values should be used.
*/
- public abstract PersistableBundle onLoadConfig(CarrierIdentifier id);
+ @SuppressLint("NullableCollection")
+ @Nullable
+ public PersistableBundle onLoadConfig(int subscriptionId, @Nullable CarrierIdentifier id) {
+ return onLoadConfig(id);
+ }
/**
* Informs the system of an intentional upcoming carrier network change by
@@ -115,7 +171,12 @@
* active. Set this value to true to begin showing
* alternative UI and false to stop.
* @see android.telephony.TelephonyManager#hasCarrierPrivileges
+ * @deprecated use {@link #notifyCarrierNetworkChange(int, boolean)} instead.
+ * With no parameter to specify the subscription, this API will
+ * apply to all subscriptions that the carrier app has carrier
+ * privileges on.
*/
+ @Deprecated
public final void notifyCarrierNetworkChange(boolean active) {
TelephonyRegistryManager telephonyRegistryMgr =
(TelephonyRegistryManager) this.getSystemService(
@@ -126,6 +187,31 @@
}
/**
+ * Informs the system of an intentional upcoming carrier network change by a carrier app on the
+ * given {@code subscriptionId}. This call is optional and is only used to allow the system to
+ * provide alternative UI while telephony is performing an action that may result in
+ * intentional, temporary network lack of connectivity.
+ *
+ * <p>Based on the active parameter passed in, this method will either show or hide the
+ * alternative UI. There is no timeout associated with showing this UX, so a carrier app must
+ * be sure to call with active set to false sometime after calling with it set to true.
+ *
+ * <p>Requires Permission: calling app has carrier privileges.
+ *
+ * @param subscriptionId the subscription of the carrier network that trigger the change.
+ * @param active whether the carrier network change is or shortly will be active. Set this
+ * value to true to begin showing alternative UI and false to stop.
+ * @see android.telephony.TelephonyManager#hasCarrierPrivileges
+ */
+ public final void notifyCarrierNetworkChange(int subscriptionId, boolean active) {
+ TelephonyRegistryManager telephonyRegistryMgr = this.getSystemService(
+ TelephonyRegistryManager.class);
+ if (telephonyRegistryMgr != null) {
+ telephonyRegistryMgr.notifyCarrierNetworkChange(subscriptionId, active);
+ }
+ }
+
+ /**
* If overriding this method, call through to the super method for any unknown actions.
* {@inheritDoc}
*/
@@ -149,10 +235,16 @@
public static final String KEY_CONFIG_BUNDLE = "config_bundle";
@Override
- public void getCarrierConfig(CarrierIdentifier id, ResultReceiver result) {
+ public void getCarrierConfig(int phoneId, CarrierIdentifier id, ResultReceiver result) {
try {
+ int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+ int[] subIds = SubscriptionManager.getSubId(phoneId);
+ if (!ArrayUtils.isEmpty(subIds)) {
+ // There should be at most one active subscription mapping to the phoneId.
+ subId = subIds[0];
+ }
Bundle data = new Bundle();
- data.putParcelable(KEY_CONFIG_BUNDLE, CarrierService.this.onLoadConfig(id));
+ data.putParcelable(KEY_CONFIG_BUNDLE, CarrierService.this.onLoadConfig(subId, id));
result.send(RESULT_OK, data);
} catch (Exception e) {
Log.e(LOG_TAG, "Error in onLoadConfig: " + e.getMessage(), e);
diff --git a/telephony/java/android/service/carrier/ICarrierService.aidl b/telephony/java/android/service/carrier/ICarrierService.aidl
index ac6f9614..054a280 100644
--- a/telephony/java/android/service/carrier/ICarrierService.aidl
+++ b/telephony/java/android/service/carrier/ICarrierService.aidl
@@ -29,5 +29,5 @@
interface ICarrierService {
/** @see android.service.carrier.CarrierService#onLoadConfig */
- oneway void getCarrierConfig(in CarrierIdentifier id, in ResultReceiver result);
+ oneway void getCarrierConfig(in int phoneId, in CarrierIdentifier id, in ResultReceiver result);
}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index d3fc033..95b9fda 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -3718,6 +3718,17 @@
"esim_max_download_retry_attempts_int";
/**
+ * List of opportunistic carrier-ids associated with CBRS Primary SIM. When CBRS pSIM is
+ * inserted, opportunistic eSIM is download and this configuration is used for grouping pSIM
+ * and opportunistic eSIM. Also when a new CBRS pSIM is inserted, old opportunistic eSIMs are
+ * deleted using the carrier-ids in this configuration.
+ *
+ * @hide
+ */
+ public static final String KEY_OPPORTUNISTIC_CARRIER_IDS_INT_ARRAY =
+ "opportunistic_carrier_ids_int_array";
+
+ /**
* Controls RSRP threshold at which OpportunisticNetworkService will decide whether
* the opportunistic network is good enough for internet data.
*/
@@ -5774,6 +5785,7 @@
sDefaults.putString(KEY_SMDP_SERVER_ADDRESS_STRING, "");
sDefaults.putInt(KEY_ESIM_MAX_DOWNLOAD_RETRY_ATTEMPTS_INT, 5);
sDefaults.putInt(KEY_ESIM_DOWNLOAD_RETRY_BACKOFF_TIMER_SEC_INT, 60);
+ sDefaults.putIntArray(KEY_OPPORTUNISTIC_CARRIER_IDS_INT_ARRAY, new int[] {0});
/* Default value is minimum RSRP level needed for SIGNAL_STRENGTH_GOOD */
sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_RSRP_INT, -108);
/* Default value is minimum RSRP level needed for SIGNAL_STRENGTH_MODERATE */
diff --git a/telephony/java/android/telephony/SignalStrengthUpdateRequest.java b/telephony/java/android/telephony/SignalStrengthUpdateRequest.java
index 9cb80f1..4884d54 100644
--- a/telephony/java/android/telephony/SignalStrengthUpdateRequest.java
+++ b/telephony/java/android/telephony/SignalStrengthUpdateRequest.java
@@ -19,6 +19,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
@@ -130,7 +131,10 @@
/**
* Set the builder object if require reporting on the system thresholds when device is idle.
*
- * <p>This can only used by the system caller. Requires permission
+ * <p>This is intended to be used by the system privileged caller only. When setting to
+ * {@code true}, signal strength update request through
+ * {@link TelephonyManager#setSignalStrengthUpdateRequest(SignalStrengthUpdateRequest)}
+ * will require permission
* {@link android.Manifest.permission#LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH}.
*
* @param isSystemThresholdReportingRequestedWhileIdle true if request reporting on the
@@ -138,6 +142,7 @@
* @return the builder to facilitate the chaining
* @hide
*/
+ @SystemApi
@RequiresPermission(android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH)
public @NonNull Builder setSystemThresholdReportingRequestedWhileIdle(
boolean isSystemThresholdReportingRequestedWhileIdle) {
@@ -191,6 +196,7 @@
*
* @hide
*/
+ @SystemApi
public boolean isSystemThresholdReportingRequestedWhileIdle() {
return mIsSystemThresholdReportingRequestedWhileIdle;
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 6286390b..29ffcd1 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -70,6 +70,7 @@
import android.os.WorkSource;
import android.provider.Settings.SettingNotFoundException;
import android.service.carrier.CarrierIdentifier;
+import android.service.carrier.CarrierService;
import android.sysprop.TelephonyProperties;
import android.telecom.CallScreeningService;
import android.telecom.InCallService;
@@ -9178,6 +9179,57 @@
return null;
}
+ /**
+ * Returns the package name that provides the {@link CarrierService} implementation for the
+ * current subscription, or {@code null} if no package with carrier privileges declares one.
+ *
+ * <p>If this object has been created with {@link #createForSubscriptionId}, then the provided
+ * subscription ID is used. Otherwise, the default subscription ID will be used.
+ *
+ * @return The system-selected package that provides the {@link CarrierService} implementation
+ * for the current subscription, or {@code null} if none is resolved
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ public @Nullable String getCarrierServicePackageName() {
+ // TODO(b/205736323) plumb this through to CarrierPrivilegesTracker, which will cache the
+ // value instead of re-querying every time.
+ List<String> carrierServicePackages =
+ getCarrierPackageNamesForIntent(
+ new Intent(CarrierService.CARRIER_SERVICE_INTERFACE));
+ if (carrierServicePackages != null && !carrierServicePackages.isEmpty()) {
+ return carrierServicePackages.get(0);
+ }
+ return null;
+ }
+
+ /**
+ * Returns the package name that provides the {@link CarrierService} implementation for the
+ * specified {@code logicalSlotIndex}, or {@code null} if no package with carrier privileges
+ * declares one.
+ *
+ * @param logicalSlotIndex The slot index to fetch the {@link CarrierService} package for
+ * @return The system-selected package that provides the {@link CarrierService} implementation
+ * for the slot, or {@code null} if none is resolved
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ public @Nullable String getCarrierServicePackageNameForLogicalSlot(int logicalSlotIndex) {
+ // TODO(b/205736323) plumb this through to CarrierPrivilegesTracker, which will cache the
+ // value instead of re-querying every time.
+ List<String> carrierServicePackages =
+ getCarrierPackageNamesForIntentAndPhone(
+ new Intent(CarrierService.CARRIER_SERVICE_INTERFACE), logicalSlotIndex);
+ if (carrierServicePackages != null && !carrierServicePackages.isEmpty()) {
+ return carrierServicePackages.get(0);
+ }
+ return null;
+ }
+
/** @hide */
@RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public List<String> getPackagesWithCarrierPrivileges() {
diff --git a/telephony/java/android/telephony/ims/RcsUceAdapter.java b/telephony/java/android/telephony/ims/RcsUceAdapter.java
index 7a1c092..61de3ac 100644
--- a/telephony/java/android/telephony/ims/RcsUceAdapter.java
+++ b/telephony/java/android/telephony/ims/RcsUceAdapter.java
@@ -28,13 +28,10 @@
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
-import android.telephony.CarrierConfigManager;
-import android.telephony.SubscriptionManager;
import android.telephony.TelephonyFrameworkInitializer;
import android.telephony.ims.aidl.IImsRcsController;
import android.telephony.ims.aidl.IRcsUceControllerCallback;
import android.telephony.ims.aidl.IRcsUcePublishStateCallback;
-import android.telephony.ims.feature.RcsFeature;
import android.util.Log;
import java.lang.annotation.Retention;
@@ -337,6 +334,14 @@
@SystemApi
public static final int PUBLISH_STATE_OTHER_ERROR = 6;
+ /**
+ * The device is currently trying to publish its capabilities to the network.
+ * @hide
+ */
+ @SystemApi
+ public static final int PUBLISH_STATE_PUBLISHING = 7;
+
+
/**@hide*/
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = "PUBLISH_STATE_", value = {
@@ -345,7 +350,8 @@
PUBLISH_STATE_VOICE_PROVISION_ERROR,
PUBLISH_STATE_RCS_PROVISION_ERROR,
PUBLISH_STATE_REQUEST_TIMEOUT,
- PUBLISH_STATE_OTHER_ERROR
+ PUBLISH_STATE_OTHER_ERROR,
+ PUBLISH_STATE_PUBLISHING
})
public @interface PublishState {}
@@ -480,9 +486,12 @@
* <p>
* Be sure to check the availability of this feature using
* {@link ImsRcsManager#isAvailable(int, int)} and ensuring
- * {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_OPTIONS_UCE} or
- * {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_PRESENCE_UCE} is enabled or else
- * this operation will fail with {@link #ERROR_NOT_AVAILABLE} or {@link #ERROR_NOT_ENABLED}.
+ * {@link
+ * android.telephony.ims.feature.RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_OPTIONS_UCE} or
+ * {@link
+ * android.telephony.ims.feature.RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_PRESENCE_UCE} is
+ * enabled or else this operation will fail with {@link #ERROR_NOT_AVAILABLE} or
+ * {@link #ERROR_NOT_ENABLED}.
*
* @param contactNumbers A list of numbers that the capabilities are being requested for.
* @param executor The executor that will be used when the request is completed and the
@@ -573,8 +582,10 @@
* <p>
* Be sure to check the availability of this feature using
* {@link ImsRcsManager#isAvailable(int, int)} and ensuring
- * {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_OPTIONS_UCE} or
- * {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_PRESENCE_UCE} is
+ * {@link
+ * android.telephony.ims.feature.RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_OPTIONS_UCE} or
+ * {@link
+ * android.telephony.ims.feature.RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_PRESENCE_UCE} is
* enabled or else this operation will fail with
* {@link #ERROR_NOT_AVAILABLE} or {@link #ERROR_NOT_ENABLED}.
*
@@ -690,7 +701,8 @@
* Registers a {@link OnPublishStateChangedListener} with the system, which will provide publish
* state updates for the subscription specified in {@link ImsManager@getRcsManager(subid)}.
* <p>
- * Use {@link SubscriptionManager.OnSubscriptionsChangedListener} to listen to subscription
+ * Use {@link android.telephony.SubscriptionManager.OnSubscriptionsChangedListener} to listen
+ * to subscription
* changed events and call
* {@link #removeOnPublishStateChangedListener(OnPublishStateChangedListener)} to clean up.
* <p>
@@ -792,7 +804,8 @@
* cache associated with those contacts as the local cache becomes stale.
* <p>
* This setting will only enable this feature if
- * {@link CarrierConfigManager.Ims#KEY_RCS_BULK_CAPABILITY_EXCHANGE_BOOL} is also enabled.
+ * {@link android.telephony.CarrierConfigManager.Ims#KEY_RCS_BULK_CAPABILITY_EXCHANGE_BOOL} is
+ * also enabled.
* <p>
* Note: This setting does not affect whether or not the device publishes its service
* capabilities if the subscription supports presence publication.
@@ -843,7 +856,8 @@
* session.
* <p>
* This setting will only enable this feature if
- * {@link CarrierConfigManager.Ims#KEY_RCS_BULK_CAPABILITY_EXCHANGE_BOOL} is also enabled.
+ * {@link android.telephony.CarrierConfigManager.Ims#KEY_RCS_BULK_CAPABILITY_EXCHANGE_BOOL} is
+ * also enabled.
* <p>
* Note: This setting does not affect whether or not the device publishes its service
* capabilities if the subscription supports presence publication.
diff --git a/telephony/java/android/telephony/ims/aidl/CapabilityExchangeAidlWrapper.java b/telephony/java/android/telephony/ims/aidl/CapabilityExchangeAidlWrapper.java
index c3d7325..c27fa4f 100644
--- a/telephony/java/android/telephony/ims/aidl/CapabilityExchangeAidlWrapper.java
+++ b/telephony/java/android/telephony/ims/aidl/CapabilityExchangeAidlWrapper.java
@@ -81,6 +81,26 @@
}
/**
+ * Receives the status of changes in the publishing connection from ims service
+ * and deliver this callback to the framework.
+ */
+ public void onPublishUpdated(int reasonCode, @NonNull String reasonPhrase,
+ int reasonHeaderCause, @NonNull String reasonHeaderText) throws ImsException {
+ ICapabilityExchangeEventListener listener = mListenerBinder;
+ if (listener == null) {
+ return;
+ }
+ try {
+ listener.onPublishUpdated(reasonCode, reasonPhrase,
+ reasonHeaderCause, reasonHeaderText);
+ } catch (RemoteException e) {
+ Log.w(LOG_TAG, "onPublishUpdated exception: " + e);
+ throw new ImsException("Remote is not available",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
+ }
+
+ /**
* Receives the callback of the remote capability request from the network and deliver this
* request to the framework.
*/
diff --git a/telephony/java/android/telephony/ims/aidl/ICapabilityExchangeEventListener.aidl b/telephony/java/android/telephony/ims/aidl/ICapabilityExchangeEventListener.aidl
index 078ac91..c675bc3 100644
--- a/telephony/java/android/telephony/ims/aidl/ICapabilityExchangeEventListener.aidl
+++ b/telephony/java/android/telephony/ims/aidl/ICapabilityExchangeEventListener.aidl
@@ -31,6 +31,8 @@
oneway interface ICapabilityExchangeEventListener {
void onRequestPublishCapabilities(int publishTriggerType);
void onUnpublish();
+ void onPublishUpdated(int reasonCode, String reasonPhrase, int reasonHeaderCause,
+ String reasonHeaderText);
void onRemoteCapabilityRequest(in Uri contactUri,
in List<String> remoteCapabilities, IOptionsRequestCallback cb);
}
diff --git a/telephony/java/android/telephony/ims/stub/CapabilityExchangeEventListener.java b/telephony/java/android/telephony/ims/stub/CapabilityExchangeEventListener.java
index a3be8da..9293a40 100644
--- a/telephony/java/android/telephony/ims/stub/CapabilityExchangeEventListener.java
+++ b/telephony/java/android/telephony/ims/stub/CapabilityExchangeEventListener.java
@@ -90,6 +90,30 @@
void onUnpublish() throws ImsException;
/**
+ * Notify the framework that the ImsService has refreshed the PUBLISH
+ * internally, which has resulted in a new PUBLISH result.
+ * <p>
+ * This method must return both SUCCESS (200 OK) and FAILURE (300+) codes in order to
+ * keep the AOSP stack up to date.
+ * @param reasonCode The SIP response code sent from the network.
+ * @param reasonPhrase The optional reason response from the network. If the
+ * network provided no reason with the sip code, the string should be empty.
+ * @param reasonHeaderCause The “cause” parameter of the “reason” header
+ * included in the SIP message.
+ * @param reasonHeaderText The “text” parameter of the “reason” header
+ * included in the SIP message.
+ * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is not
+ * currently connected to the framework. This can happen if the {@link RcsFeature} is not
+ * {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received
+ * the {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare
+ * cases when the Telephony stack has crashed.
+ *
+ */
+ default void onPublishUpdated(int reasonCode, @NonNull String reasonPhrase,
+ int reasonHeaderCause, @NonNull String reasonHeaderText) throws ImsException {
+ }
+
+ /**
* Inform the framework of an OPTIONS query from a remote device for this device's UCE
* capabilities.
* <p>