summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/current.txt3
-rw-r--r--core/api/system-current.txt14
-rw-r--r--core/java/android/bluetooth/BluetoothAdapter.java4
-rw-r--r--core/java/android/os/Trace.java40
-rw-r--r--core/java/android/telephony/TelephonyRegistryManager.java20
-rw-r--r--core/java/android/util/FeatureFlagUtils.java6
-rw-r--r--core/java/android/view/View.java90
-rw-r--r--core/java/android/view/inputmethod/InputConnection.java31
-rw-r--r--core/java/com/android/internal/telephony/ITelephonyRegistry.aidl3
-rw-r--r--core/java/com/android/internal/widget/EditableInputConnection.java2
-rw-r--r--core/jni/android_os_Trace.cpp22
-rw-r--r--core/jni/android_view_InputEventReceiver.cpp4
-rw-r--r--packages/ConnectivityT/framework-t/src/android/net/IpSecAlgorithm.java2
-rw-r--r--packages/ConnectivityT/framework-t/src/android/net/IpSecManager.java12
-rw-r--r--packages/ConnectivityT/framework-t/src/android/net/IpSecTransformResponse.java3
-rw-r--r--packages/ConnectivityT/framework-t/src/android/net/IpSecTunnelInterfaceResponse.java3
-rw-r--r--packages/ConnectivityT/framework-t/src/android/net/IpSecUdpEncapResponse.java4
-rw-r--r--packages/ConnectivityT/service/src/com/android/server/IpSecService.java130
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java19
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java4
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java165
-rw-r--r--packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt6
-rw-r--r--services/core/java/com/android/server/TelephonyRegistry.java27
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java12
-rw-r--r--services/core/java/com/android/server/am/AppProfiler.java6
-rw-r--r--services/core/java/com/android/server/am/PhantomProcessList.java6
-rw-r--r--services/core/java/com/android/server/wm/RefreshRatePolicy.java14
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java12
-rw-r--r--telephony/java/android/telephony/SignalStrengthUpdateRequest.java8
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java160
-rw-r--r--telephony/java/android/telephony/TelephonyScanManager.java8
-rw-r--r--telephony/java/android/telephony/ims/RcsClientConfiguration.java50
-rw-r--r--telephony/java/android/telephony/ims/RcsUceAdapter.java38
-rw-r--r--telephony/java/android/telephony/ims/aidl/CapabilityExchangeAidlWrapper.java20
-rw-r--r--telephony/java/android/telephony/ims/aidl/ICapabilityExchangeEventListener.aidl2
-rw-r--r--telephony/java/android/telephony/ims/stub/CapabilityExchangeEventListener.java24
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephony.aidl16
37 files changed, 785 insertions, 205 deletions
diff --git a/core/api/current.txt b/core/api/current.txt
index d9753ab5e4a0..c3b5b943477f 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -42841,6 +42841,7 @@ package android.telephony {
method public int getPhoneType();
method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PHONE_STATE}) public int getPreferredOpportunisticDataSubscription();
method @Nullable @RequiresPermission(allOf={android.Manifest.permission.READ_PHONE_STATE, android.Manifest.permission.ACCESS_COARSE_LOCATION}) public android.telephony.ServiceState getServiceState();
+ method @Nullable @RequiresPermission(allOf={android.Manifest.permission.READ_PHONE_STATE, android.Manifest.permission.ACCESS_COARSE_LOCATION}) public android.telephony.ServiceState getServiceState(boolean, boolean);
method @Nullable public android.telephony.SignalStrength getSignalStrength();
method public int getSimCarrierId();
method @Nullable public CharSequence getSimCarrierIdName();
@@ -42893,8 +42894,10 @@ package android.telephony {
method public boolean isWorldPhone();
method @Deprecated public void listen(android.telephony.PhoneStateListener, int);
method public void registerTelephonyCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyCallback);
+ method public void registerTelephonyCallback(boolean, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyCallback);
method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void requestCellInfoUpdate(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback);
method @RequiresPermission(allOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public android.telephony.NetworkScan requestNetworkScan(android.telephony.NetworkScanRequest, java.util.concurrent.Executor, android.telephony.TelephonyScanManager.NetworkScanCallback);
+ method @Nullable @RequiresPermission(allOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public android.telephony.NetworkScan requestNetworkScan(boolean, @NonNull android.telephony.NetworkScanRequest, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyScanManager.NetworkScanCallback);
method public void sendDialerSpecialCode(String);
method public String sendEnvelopeWithStatus(String);
method @RequiresPermission(android.Manifest.permission.CALL_PHONE) public void sendUssdRequest(String, android.telephony.TelephonyManager.UssdResponseCallback, android.os.Handler);
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index ca3c51152514..da9a4c50d3cb 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -11698,6 +11698,14 @@ package android.telephony {
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();
@@ -13490,12 +13498,14 @@ package android.telephony.ims {
}
public final class RcsClientConfiguration implements android.os.Parcelable {
- ctor public RcsClientConfiguration(@NonNull String, @NonNull String, @NonNull String, @NonNull String);
+ ctor @Deprecated public RcsClientConfiguration(@NonNull String, @NonNull String, @NonNull String, @NonNull String);
+ ctor public RcsClientConfiguration(@NonNull String, @NonNull String, @NonNull String, @NonNull String, boolean);
method public int describeContents();
method @NonNull public String getClientVendor();
method @NonNull public String getClientVersion();
method @NonNull public String getRcsProfile();
method @NonNull public String getRcsVersion();
+ method public boolean isRcsEnabledByUser();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.RcsClientConfiguration> CREATOR;
field public static final String RCS_PROFILE_1_0 = "UP_1.0";
@@ -13632,6 +13642,7 @@ package android.telephony.ims {
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
@@ -13894,6 +13905,7 @@ package android.telephony.ims.feature {
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/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index b23c3eb0ceae..5612e7cf56ce 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -56,7 +56,7 @@ import android.os.ParcelUuid;
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 @@ public final class BluetoothAdapter {
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/os/Trace.java b/core/java/android/os/Trace.java
index ddb6533547bb..d974e0c0713a 100644
--- a/core/java/android/os/Trace.java
+++ b/core/java/android/os/Trace.java
@@ -131,6 +131,10 @@ public final class Trace {
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 @@ public final class Trace {
}
/**
+ * 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/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java
index cb1cff9cda22..859fd804dea5 100644
--- a/core/java/android/telephony/TelephonyRegistryManager.java
+++ b/core/java/android/telephony/TelephonyRegistryManager.java
@@ -247,8 +247,8 @@ public class TelephonyRegistryManager {
} else if (listener.mSubId != null) {
subId = listener.mSubId;
}
- sRegistry.listenWithEventList(
- subId, pkg, featureId, listener.callback, eventsList, notifyNow);
+ sRegistry.listenWithEventList(false, false, subId, pkg, featureId,
+ listener.callback, eventsList, notifyNow);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -263,11 +263,13 @@ public class TelephonyRegistryManager {
* @param events List events
* @param notifyNow Whether to notify instantly
*/
- private void listenFromCallback(int subId, @NonNull String pkg, @NonNull String featureId,
+ private void listenFromCallback(boolean renounceFineLocationAccess,
+ boolean renounceCoarseLocationAccess, int subId,
+ @NonNull String pkg, @NonNull String featureId,
@NonNull TelephonyCallback telephonyCallback, @NonNull int[] events,
boolean notifyNow) {
try {
- sRegistry.listenWithEventList(
+ sRegistry.listenWithEventList(renounceFineLocationAccess, renounceCoarseLocationAccess,
subId, pkg, featureId, telephonyCallback.callback, events, notifyNow);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -1161,14 +1163,17 @@ public class TelephonyRegistryManager {
*
* @param callback The {@link TelephonyCallback} object to register.
*/
- public void registerTelephonyCallback(@NonNull @CallbackExecutor Executor executor,
+ public void registerTelephonyCallback(boolean renounceFineLocationAccess,
+ boolean renounceCoarseLocationAccess,
+ @NonNull @CallbackExecutor Executor executor,
int subId, String pkgName, String attributionTag, @NonNull TelephonyCallback callback,
boolean notifyNow) {
if (callback == null) {
throw new IllegalStateException("telephony service is null.");
}
callback.init(executor);
- listenFromCallback(subId, pkgName, attributionTag, callback,
+ listenFromCallback(renounceFineLocationAccess, renounceCoarseLocationAccess, subId,
+ pkgName, attributionTag, callback,
getEventsFromCallback(callback).stream().mapToInt(i -> i).toArray(), notifyNow);
}
@@ -1179,6 +1184,7 @@ public class TelephonyRegistryManager {
*/
public void unregisterTelephonyCallback(int subId, String pkgName, String attributionTag,
@NonNull TelephonyCallback callback, boolean notifyNow) {
- listenFromCallback(subId, pkgName, attributionTag, callback, new int[0], notifyNow);
+ listenFromCallback(false, false, subId,
+ pkgName, attributionTag, callback, new int[0], notifyNow);
}
}
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 6c3c38359957..546d6de82935 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -51,6 +51,10 @@ public class FeatureFlagUtils {
/** @hide */
public static final String SETTINGS_ENABLE_SECURITY_HUB = "settings_enable_security_hub";
+ /** @hide */
+ public static final String SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS =
+ "settings_enable_monitor_phantom_procs";
+
private static final Map<String, String> DEFAULT_FLAGS;
static {
@@ -72,12 +76,14 @@ public class FeatureFlagUtils {
DEFAULT_FLAGS.put(SETTINGS_PROVIDER_MODEL, "true");
DEFAULT_FLAGS.put(SETTINGS_USE_NEW_BACKUP_ELIGIBILITY_RULES, "true");
DEFAULT_FLAGS.put(SETTINGS_ENABLE_SECURITY_HUB, "true");
+ DEFAULT_FLAGS.put(SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS, "true");
}
private static final Set<String> PERSISTENT_FLAGS;
static {
PERSISTENT_FLAGS = new HashSet<>();
PERSISTENT_FLAGS.add(SETTINGS_PROVIDER_MODEL);
+ PERSISTENT_FLAGS.add(SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS);
}
/**
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index cf12955787b1..2320434f14f6 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -26842,44 +26842,38 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* 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 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
- * 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 5f036a348808..4d7d182f0013 100644
--- a/core/java/android/view/inputmethod/InputConnection.java
+++ b/core/java/android/view/inputmethod/InputConnection.java
@@ -770,20 +770,25 @@ public interface InputConnection {
boolean beginBatchEdit();
/**
- * 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>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>
+ * 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>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/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index a0a0f3276b99..6ba0279313b1 100644
--- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -43,7 +43,8 @@ interface ITelephonyRegistry {
void removeOnSubscriptionsChangedListener(String pkg,
IOnSubscriptionsChangedListener callback);
- void listenWithEventList(in int subId, String pkg, String featureId,
+ void listenWithEventList(in boolean renounceFineLocationAccess,
+ in boolean renounceCoarseLocationAccess, in int subId, String pkg, String featureId,
IPhoneStateListener callback, in int[] events, boolean notifyNow);
@UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
void notifyCallStateForAllSubs(int state, String incomingNumber);
diff --git a/core/java/com/android/internal/widget/EditableInputConnection.java b/core/java/com/android/internal/widget/EditableInputConnection.java
index 02ffe8c5268e..040d78b65afa 100644
--- a/core/java/com/android/internal/widget/EditableInputConnection.java
+++ b/core/java/com/android/internal/widget/EditableInputConnection.java
@@ -92,7 +92,7 @@ public class EditableInputConnection extends BaseInputConnection
// 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 f67007cda209..85fd5d99e473 100644
--- a/core/jni/android_os_Trace.cpp
+++ b/core/jni/android_os_Trace.cpp
@@ -90,6 +90,22 @@ static void android_os_Trace_nativeSetTracingEnabled(JNIEnv*, jclass, jboolean e
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 @@ static const JNINativeMethod gTraceMethods[] = {
{ "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 a699f912806d..7d0f60adeb5c 100644
--- a/core/jni/android_view_InputEventReceiver.cpp
+++ b/core/jni/android_view_InputEventReceiver.cpp
@@ -447,10 +447,6 @@ status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,
skipCallbacks = true;
}
}
-
- if (skipCallbacks) {
- mInputConsumer.sendFinishedSignal(seq, false);
- }
}
}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/IpSecAlgorithm.java b/packages/ConnectivityT/framework-t/src/android/net/IpSecAlgorithm.java
index 86052484eaf6..840af28b77e7 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/IpSecAlgorithm.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/IpSecAlgorithm.java
@@ -297,7 +297,7 @@ public final class IpSecAlgorithm implements Parcelable {
return mTruncLenBits;
}
- /* Parcelable Implementation */
+ /** Parcelable Implementation */
public int describeContents() {
return 0;
}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/IpSecManager.java b/packages/ConnectivityT/framework-t/src/android/net/IpSecManager.java
index c10680761ff1..837629911ccd 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/IpSecManager.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/IpSecManager.java
@@ -99,9 +99,9 @@ public final class IpSecManager {
/** @hide */
public interface Status {
- public static final int OK = 0;
- public static final int RESOURCE_UNAVAILABLE = 1;
- public static final int SPI_UNAVAILABLE = 2;
+ int OK = 0;
+ int RESOURCE_UNAVAILABLE = 1;
+ int SPI_UNAVAILABLE = 2;
}
/** @hide */
@@ -276,7 +276,7 @@ public final class IpSecManager {
* @param destinationAddress the destination address for traffic bearing the requested SPI.
* For inbound traffic, the destination should be an address currently assigned on-device.
* @return the reserved SecurityParameterIndex
- * @throws {@link #ResourceUnavailableException} indicating that too many SPIs are
+ * @throws ResourceUnavailableException indicating that too many SPIs are
* currently allocated for this user
*/
@NonNull
@@ -307,9 +307,9 @@ public final class IpSecManager {
* @param requestedSpi the requested SPI. The range 1-255 is reserved and may not be used. See
* RFC 4303 Section 2.1.
* @return the reserved SecurityParameterIndex
- * @throws {@link #ResourceUnavailableException} indicating that too many SPIs are
+ * @throws ResourceUnavailableException indicating that too many SPIs are
* currently allocated for this user
- * @throws {@link #SpiUnavailableException} indicating that the requested SPI could not be
+ * @throws SpiUnavailableException indicating that the requested SPI could not be
* reserved
*/
@NonNull
diff --git a/packages/ConnectivityT/framework-t/src/android/net/IpSecTransformResponse.java b/packages/ConnectivityT/framework-t/src/android/net/IpSecTransformResponse.java
index a38488954fc0..363f3165ee65 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/IpSecTransformResponse.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/IpSecTransformResponse.java
@@ -60,7 +60,8 @@ public final class IpSecTransformResponse implements Parcelable {
resourceId = in.readInt();
}
- public static final @android.annotation.NonNull Parcelable.Creator<IpSecTransformResponse> CREATOR =
+ @android.annotation.NonNull
+ public static final Parcelable.Creator<IpSecTransformResponse> CREATOR =
new Parcelable.Creator<IpSecTransformResponse>() {
public IpSecTransformResponse createFromParcel(Parcel in) {
return new IpSecTransformResponse(in);
diff --git a/packages/ConnectivityT/framework-t/src/android/net/IpSecTunnelInterfaceResponse.java b/packages/ConnectivityT/framework-t/src/android/net/IpSecTunnelInterfaceResponse.java
index e3411e003d6b..127e30a69394 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/IpSecTunnelInterfaceResponse.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/IpSecTunnelInterfaceResponse.java
@@ -65,7 +65,8 @@ public final class IpSecTunnelInterfaceResponse implements Parcelable {
interfaceName = in.readString();
}
- public static final @android.annotation.NonNull Parcelable.Creator<IpSecTunnelInterfaceResponse> CREATOR =
+ @android.annotation.NonNull
+ public static final Parcelable.Creator<IpSecTunnelInterfaceResponse> CREATOR =
new Parcelable.Creator<IpSecTunnelInterfaceResponse>() {
public IpSecTunnelInterfaceResponse createFromParcel(Parcel in) {
return new IpSecTunnelInterfaceResponse(in);
diff --git a/packages/ConnectivityT/framework-t/src/android/net/IpSecUdpEncapResponse.java b/packages/ConnectivityT/framework-t/src/android/net/IpSecUdpEncapResponse.java
index 4e7ba9b515d0..732cf198a9cc 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/IpSecUdpEncapResponse.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/IpSecUdpEncapResponse.java
@@ -18,6 +18,7 @@ package android.net;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
+
import java.io.FileDescriptor;
import java.io.IOException;
@@ -83,7 +84,8 @@ public final class IpSecUdpEncapResponse implements Parcelable {
fileDescriptor = in.readParcelable(ParcelFileDescriptor.class.getClassLoader());
}
- public static final @android.annotation.NonNull Parcelable.Creator<IpSecUdpEncapResponse> CREATOR =
+ @android.annotation.NonNull
+ public static final Parcelable.Creator<IpSecUdpEncapResponse> CREATOR =
new Parcelable.Creator<IpSecUdpEncapResponse>() {
public IpSecUdpEncapResponse createFromParcel(Parcel in) {
return new IpSecUdpEncapResponse(in);
diff --git a/packages/ConnectivityT/service/src/com/android/server/IpSecService.java b/packages/ConnectivityT/service/src/com/android/server/IpSecService.java
index aeb814327e66..f251b86b7a09 100644
--- a/packages/ConnectivityT/service/src/com/android/server/IpSecService.java
+++ b/packages/ConnectivityT/service/src/com/android/server/IpSecService.java
@@ -119,6 +119,7 @@ public class IpSecService extends IIpSecService.Stub {
/* Binder context for this service */
private final Context mContext;
+ private final Dependencies mDeps;
/**
* The next non-repeating global ID for tracking resources between users, this service, and
@@ -129,23 +130,24 @@ public class IpSecService extends IIpSecService.Stub {
@GuardedBy("IpSecService.this")
private int mNextResourceId = 1;
- interface IpSecServiceConfiguration {
- INetd getNetdInstance() throws RemoteException;
-
- static IpSecServiceConfiguration GETSRVINSTANCE =
- new IpSecServiceConfiguration() {
- @Override
- public INetd getNetdInstance() throws RemoteException {
- final INetd netd = NetdService.getInstance();
- if (netd == null) {
- throw new RemoteException("Failed to Get Netd Instance");
- }
- return netd;
- }
- };
+ /**
+ * Dependencies of IpSecService, for injection in tests.
+ */
+ @VisibleForTesting
+ public static class Dependencies {
+ /**
+ * Get a reference to INetd.
+ */
+ public INetd getNetdInstance(Context context) throws RemoteException {
+ final INetd netd = INetd.Stub.asInterface((IBinder)
+ context.getSystemService(Context.NETD_SERVICE));
+ if (netd == null) {
+ throw new RemoteException("Failed to Get Netd Instance");
+ }
+ return netd;
+ }
}
- private final IpSecServiceConfiguration mSrvConfig;
final UidFdTagger mUidFdTagger;
/**
@@ -491,8 +493,8 @@ public class IpSecService extends IIpSecService.Stub {
* <p>This class associates kernel resources with the UID that owns and controls them.
*/
private abstract class OwnedResourceRecord implements IResource {
- final int pid;
- final int uid;
+ final int mPid;
+ final int mUid;
protected final int mResourceId;
OwnedResourceRecord(int resourceId) {
@@ -501,8 +503,8 @@ public class IpSecService extends IIpSecService.Stub {
throw new IllegalArgumentException("Resource ID must not be INVALID_RESOURCE_ID");
}
mResourceId = resourceId;
- pid = Binder.getCallingPid();
- uid = Binder.getCallingUid();
+ mPid = Binder.getCallingPid();
+ mUid = Binder.getCallingUid();
getResourceTracker().take();
}
@@ -512,7 +514,7 @@ public class IpSecService extends IIpSecService.Stub {
/** Convenience method; retrieves the user resource record for the stored UID. */
protected UserRecord getUserRecord() {
- return mUserResourceTracker.getUserRecord(uid);
+ return mUserResourceTracker.getUserRecord(mUid);
}
@Override
@@ -527,9 +529,9 @@ public class IpSecService extends IIpSecService.Stub {
.append("{mResourceId=")
.append(mResourceId)
.append(", pid=")
- .append(pid)
+ .append(mPid)
.append(", uid=")
- .append(uid)
+ .append(mUid)
.append("}")
.toString();
}
@@ -545,7 +547,7 @@ public class IpSecService extends IIpSecService.Stub {
SparseArray<RefcountedResource<T>> mArray = new SparseArray<>();
private final String mTypeName;
- public RefcountedResourceArray(String typeName) {
+ RefcountedResourceArray(String typeName) {
this.mTypeName = typeName;
}
@@ -625,10 +627,10 @@ public class IpSecService extends IIpSecService.Stub {
public void freeUnderlyingResources() {
int spi = mSpi.getSpi();
try {
- mSrvConfig
- .getNetdInstance()
+ mDeps
+ .getNetdInstance(mContext)
.ipSecDeleteSecurityAssociation(
- uid,
+ mUid,
mConfig.getSourceAddress(),
mConfig.getDestinationAddress(),
spi,
@@ -678,11 +680,14 @@ public class IpSecService extends IIpSecService.Stub {
private final String mSourceAddress;
private final String mDestinationAddress;
private int mSpi;
+ private final Context mContext;
private boolean mOwnedByTransform = false;
- SpiRecord(int resourceId, String sourceAddress, String destinationAddress, int spi) {
+ SpiRecord(Context context, int resourceId, String sourceAddress,
+ String destinationAddress, int spi) {
super(resourceId);
+ mContext = context;
mSourceAddress = sourceAddress;
mDestinationAddress = destinationAddress;
mSpi = spi;
@@ -693,10 +698,10 @@ public class IpSecService extends IIpSecService.Stub {
public void freeUnderlyingResources() {
try {
if (!mOwnedByTransform) {
- mSrvConfig
- .getNetdInstance()
+ mDeps
+ .getNetdInstance(mContext)
.ipSecDeleteSecurityAssociation(
- uid, mSourceAddress, mDestinationAddress, mSpi, 0 /* mark */,
+ mUid, mSourceAddress, mDestinationAddress, mSpi, 0 /* mark */,
0 /* mask */, 0 /* if_id */);
}
} catch (ServiceSpecificException | RemoteException e) {
@@ -816,8 +821,10 @@ public class IpSecService extends IIpSecService.Stub {
private final int mIfId;
private Network mUnderlyingNetwork;
+ private final Context mContext;
TunnelInterfaceRecord(
+ Context context,
int resourceId,
String interfaceName,
Network underlyingNetwork,
@@ -828,6 +835,7 @@ public class IpSecService extends IIpSecService.Stub {
int intfId) {
super(resourceId);
+ mContext = context;
mInterfaceName = interfaceName;
mUnderlyingNetwork = underlyingNetwork;
mLocalAddress = localAddr;
@@ -844,19 +852,19 @@ public class IpSecService extends IIpSecService.Stub {
// Teardown VTI
// Delete global policies
try {
- final INetd netd = mSrvConfig.getNetdInstance();
+ final INetd netd = mDeps.getNetdInstance(mContext);
netd.ipSecRemoveTunnelInterface(mInterfaceName);
for (int selAddrFamily : ADDRESS_FAMILIES) {
netd.ipSecDeleteSecurityPolicy(
- uid,
+ mUid,
selAddrFamily,
IpSecManager.DIRECTION_OUT,
mOkey,
0xffffffff,
mIfId);
netd.ipSecDeleteSecurityPolicy(
- uid,
+ mUid,
selAddrFamily,
IpSecManager.DIRECTION_IN,
mIkey,
@@ -1012,7 +1020,7 @@ public class IpSecService extends IIpSecService.Stub {
* @param context Binder context for this service
*/
private IpSecService(Context context) {
- this(context, IpSecServiceConfiguration.GETSRVINSTANCE);
+ this(context, new Dependencies());
}
static IpSecService create(Context context)
@@ -1025,16 +1033,16 @@ public class IpSecService extends IIpSecService.Stub {
@NonNull
private AppOpsManager getAppOpsManager() {
AppOpsManager appOps = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
- if(appOps == null) throw new RuntimeException("System Server couldn't get AppOps");
+ if (appOps == null) throw new RuntimeException("System Server couldn't get AppOps");
return appOps;
}
/** @hide */
@VisibleForTesting
- public IpSecService(Context context, IpSecServiceConfiguration config) {
+ public IpSecService(Context context, Dependencies deps) {
this(
context,
- config,
+ deps,
(fd, uid) -> {
try {
TrafficStats.setThreadStatsUid(uid);
@@ -1047,13 +1055,13 @@ public class IpSecService extends IIpSecService.Stub {
/** @hide */
@VisibleForTesting
- public IpSecService(Context context, IpSecServiceConfiguration config,
- UidFdTagger uidFdTagger) {
+ public IpSecService(Context context, Dependencies deps, UidFdTagger uidFdTagger) {
mContext = context;
- mSrvConfig = config;
+ mDeps = deps;
mUidFdTagger = uidFdTagger;
}
+ /** Called by system server when system is ready. */
public void systemReady() {
if (isNetdAlive()) {
Log.d(TAG, "IpSecService is ready");
@@ -1076,7 +1084,7 @@ public class IpSecService extends IIpSecService.Stub {
synchronized boolean isNetdAlive() {
try {
- final INetd netd = mSrvConfig.getNetdInstance();
+ final INetd netd = mDeps.getNetdInstance(mContext);
if (netd == null) {
return false;
}
@@ -1142,14 +1150,15 @@ public class IpSecService extends IIpSecService.Stub {
}
spi =
- mSrvConfig
- .getNetdInstance()
+ mDeps
+ .getNetdInstance(mContext)
.ipSecAllocateSpi(callingUid, "", destinationAddress, requestedSpi);
Log.d(TAG, "Allocated SPI " + spi);
userRecord.mSpiRecords.put(
resourceId,
new RefcountedResource<SpiRecord>(
- new SpiRecord(resourceId, "", destinationAddress, spi), binder));
+ new SpiRecord(mContext, resourceId, "",
+ destinationAddress, spi), binder));
} catch (ServiceSpecificException e) {
if (e.errorCode == OsConstants.ENOENT) {
return new IpSecSpiResponse(
@@ -1229,7 +1238,7 @@ public class IpSecService extends IIpSecService.Stub {
* <p>Since the socket is created on behalf of an unprivileged application, all traffic
* should be accounted to the UID of the unprivileged application.
*/
- public void tag(FileDescriptor fd, int uid) throws IOException;
+ void tag(FileDescriptor fd, int uid) throws IOException;
}
/**
@@ -1266,7 +1275,7 @@ public class IpSecService extends IIpSecService.Stub {
OsConstants.UDP_ENCAP,
OsConstants.UDP_ENCAP_ESPINUDP);
- mSrvConfig.getNetdInstance().ipSecSetEncapSocketOwner(
+ mDeps.getNetdInstance(mContext).ipSecSetEncapSocketOwner(
new ParcelFileDescriptor(sockFd), callingUid);
if (port != 0) {
Log.v(TAG, "Binding to port " + port);
@@ -1329,7 +1338,7 @@ public class IpSecService extends IIpSecService.Stub {
// Create VTI
// Add inbound/outbound global policies
// (use reqid = 0)
- final INetd netd = mSrvConfig.getNetdInstance();
+ final INetd netd = mDeps.getNetdInstance(mContext);
netd.ipSecAddTunnelInterface(intfName, localAddr, remoteAddr, ikey, okey, resourceId);
BinderUtils.withCleanCallingIdentity(() -> {
@@ -1384,6 +1393,7 @@ public class IpSecService extends IIpSecService.Stub {
resourceId,
new RefcountedResource<TunnelInterfaceRecord>(
new TunnelInterfaceRecord(
+ mContext,
resourceId,
intfName,
underlyingNetwork,
@@ -1425,8 +1435,8 @@ public class IpSecService extends IIpSecService.Stub {
try {
// We can assume general validity of the IP address, since we get them as a
// LinkAddress, which does some validation.
- mSrvConfig
- .getNetdInstance()
+ mDeps
+ .getNetdInstance(mContext)
.interfaceAddAddress(
tunnelInterfaceInfo.mInterfaceName,
localAddr.getAddress().getHostAddress(),
@@ -1454,8 +1464,8 @@ public class IpSecService extends IIpSecService.Stub {
try {
// We can assume general validity of the IP address, since we get them as a
// LinkAddress, which does some validation.
- mSrvConfig
- .getNetdInstance()
+ mDeps
+ .getNetdInstance(mContext)
.interfaceDelAddress(
tunnelInterfaceInfo.mInterfaceName,
localAddr.getAddress().getHostAddress(),
@@ -1669,8 +1679,8 @@ public class IpSecService extends IIpSecService.Stub {
cryptName = crypt.getName();
}
- mSrvConfig
- .getNetdInstance()
+ mDeps
+ .getNetdInstance(mContext)
.ipSecAddSecurityAssociation(
Binder.getCallingUid(),
c.getMode(),
@@ -1771,7 +1781,7 @@ public class IpSecService extends IIpSecService.Stub {
TransformRecord info = userRecord.mTransformRecords.getResourceOrThrow(resourceId);
// TODO: make this a function.
- if (info.pid != getCallingPid() || info.uid != callingUid) {
+ if (info.mPid != getCallingPid() || info.mUid != callingUid) {
throw new SecurityException("Only the owner of an IpSec Transform may apply it!");
}
@@ -1781,8 +1791,8 @@ public class IpSecService extends IIpSecService.Stub {
c.getMode() == IpSecTransform.MODE_TRANSPORT,
"Transform mode was not Transport mode; cannot be applied to a socket");
- mSrvConfig
- .getNetdInstance()
+ mDeps
+ .getNetdInstance(mContext)
.ipSecApplyTransportModeTransform(
socket,
callingUid,
@@ -1801,8 +1811,8 @@ public class IpSecService extends IIpSecService.Stub {
@Override
public synchronized void removeTransportModeTransforms(ParcelFileDescriptor socket)
throws RemoteException {
- mSrvConfig
- .getNetdInstance()
+ mDeps
+ .getNetdInstance(mContext)
.ipSecRemoveTransportModeTransform(socket);
}
@@ -1878,8 +1888,8 @@ public class IpSecService extends IIpSecService.Stub {
// Always update the policy with the relevant XFRM_IF_ID
for (int selAddrFamily : ADDRESS_FAMILIES) {
- mSrvConfig
- .getNetdInstance()
+ mDeps
+ .getNetdInstance(mContext)
.ipSecUpdateSecurityPolicy(
callingUid,
selAddrFamily,
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
index b429fe6d4939..3debd9a179da 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
@@ -87,7 +87,7 @@ public class CachedBluetoothDeviceManager {
}
// Check the member devices for the coordinated set if it exists
final Set<CachedBluetoothDevice> memberDevices = cachedDevice.getMemberDevice();
- if (memberDevices != null) {
+ if (!memberDevices.isEmpty()) {
for (CachedBluetoothDevice memberDevice : memberDevices) {
if (memberDevice.getDevice().equals(device)) {
return memberDevice;
@@ -141,7 +141,7 @@ public class CachedBluetoothDeviceManager {
final Set<CachedBluetoothDevice> memberDevices = device.getMemberDevice();
// TODO: check the CSIP group size instead of the real member device set size, and adjust
// the size restriction.
- if (memberDevices.size() == 1) {
+ if (!memberDevices.isEmpty()) {
for (CachedBluetoothDevice memberDevice : memberDevices) {
if (memberDevice.isConnected()) {
return memberDevice.getConnectionSummary();
@@ -166,7 +166,7 @@ public class CachedBluetoothDeviceManager {
if (!cachedDevice.getDevice().equals(device)) {
// Check the member devices of the coordinated set if it exists
Set<CachedBluetoothDevice> memberDevices = cachedDevice.getMemberDevice();
- if (memberDevices != null) {
+ if (!memberDevices.isEmpty()) {
for (CachedBluetoothDevice memberDevice : memberDevices) {
if (memberDevice.getDevice().equals(device)) {
return true;
@@ -230,9 +230,10 @@ public class CachedBluetoothDeviceManager {
private void clearNonBondedSubDevices() {
for (int i = mCachedDevices.size() - 1; i >= 0; i--) {
CachedBluetoothDevice cachedDevice = mCachedDevices.get(i);
- final Set<CachedBluetoothDevice> memberDevices = cachedDevice.getMemberDevice();
- if (memberDevices != null) {
- for (CachedBluetoothDevice memberDevice : memberDevices) {
+ Set<CachedBluetoothDevice> memberDevices = cachedDevice.getMemberDevice();
+ if (!memberDevices.isEmpty()) {
+ for (Object it : memberDevices.toArray()) {
+ CachedBluetoothDevice memberDevice = (CachedBluetoothDevice) it;
// Member device exists and it is not bonded
if (memberDevice.getDevice().getBondState() == BluetoothDevice.BOND_NONE) {
cachedDevice.removeMemberDevice(memberDevice);
@@ -257,7 +258,7 @@ public class CachedBluetoothDeviceManager {
CachedBluetoothDevice cachedDevice = mCachedDevices.get(i);
cachedDevice.setJustDiscovered(false);
final Set<CachedBluetoothDevice> memberDevices = cachedDevice.getMemberDevice();
- if (memberDevices != null) {
+ if (!memberDevices.isEmpty()) {
for (CachedBluetoothDevice memberDevice : memberDevices) {
memberDevice.setJustDiscovered(false);
}
@@ -277,7 +278,7 @@ public class CachedBluetoothDeviceManager {
for (int i = mCachedDevices.size() - 1; i >= 0; i--) {
CachedBluetoothDevice cachedDevice = mCachedDevices.get(i);
final Set<CachedBluetoothDevice> memberDevices = cachedDevice.getMemberDevice();
- if (memberDevices != null) {
+ if (!memberDevices.isEmpty()) {
for (CachedBluetoothDevice memberDevice : memberDevices) {
if (memberDevice.getBondState() != BluetoothDevice.BOND_BONDED) {
cachedDevice.removeMemberDevice(memberDevice);
@@ -315,7 +316,7 @@ public class CachedBluetoothDeviceManager {
public synchronized void onDeviceUnpaired(CachedBluetoothDevice device) {
CachedBluetoothDevice mainDevice = mCsipDeviceManager.findMainDevice(device);
final Set<CachedBluetoothDevice> memberDevices = device.getMemberDevice();
- if (memberDevices != null) {
+ if (!memberDevices.isEmpty()) {
// Main device is unpaired, to unpair the member device
for (CachedBluetoothDevice memberDevice : memberDevices) {
memberDevice.unpair();
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java
index 1d29966838d3..36d9cf83120a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java
@@ -193,7 +193,7 @@ public class CsipDeviceManager {
return true;
}
final Set<CachedBluetoothDevice> memberSet = cachedDevice.getMemberDevice();
- if (memberSet == null) {
+ if (memberSet.isEmpty()) {
break;
}
@@ -225,7 +225,7 @@ public class CsipDeviceManager {
for (CachedBluetoothDevice cachedDevice : mCachedDevices) {
if (isValidGroupId(cachedDevice.getGroupId())) {
Set<CachedBluetoothDevice> memberSet = cachedDevice.getMemberDevice();
- if (memberSet == null) {
+ if (memberSet.isEmpty()) {
continue;
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
index 2c4f57fa77be..d53a3e896868 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
@@ -26,7 +26,9 @@ import static org.mockito.Mockito.when;
import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothUuid;
import android.content.Context;
+import android.os.ParcelUuid;
import org.junit.Before;
import org.junit.Test;
@@ -37,6 +39,8 @@ import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
@RunWith(RobolectricTestRunner.class)
public class CachedBluetoothDeviceManagerTest {
@@ -51,6 +55,10 @@ public class CachedBluetoothDeviceManagerTest {
private final static String DEVICE_ADDRESS_3 = "AA:BB:CC:DD:EE:33";
private final static long HISYNCID1 = 10;
private final static long HISYNCID2 = 11;
+ private final static Map<Integer, ParcelUuid> CAP_GROUP1 =
+ Map.of(1, BluetoothUuid.CAP);
+ private final static Map<Integer, ParcelUuid> CAP_GROUP2 =
+ Map.of(2, BluetoothUuid.CAP);
private final BluetoothClass DEVICE_CLASS_1 =
new BluetoothClass(BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES);
private final BluetoothClass DEVICE_CLASS_2 =
@@ -70,6 +78,8 @@ public class CachedBluetoothDeviceManagerTest {
@Mock
private HearingAidProfile mHearingAidProfile;
@Mock
+ private CsipSetCoordinatorProfile mCsipSetCoordinatorProfile;
+ @Mock
private BluetoothDevice mDevice1;
@Mock
private BluetoothDevice mDevice2;
@@ -105,8 +115,12 @@ public class CachedBluetoothDeviceManagerTest {
when(mA2dpProfile.isProfileReady()).thenReturn(true);
when(mPanProfile.isProfileReady()).thenReturn(true);
when(mHearingAidProfile.isProfileReady()).thenReturn(true);
+ when(mCsipSetCoordinatorProfile.isProfileReady())
+ .thenReturn(true);
doAnswer((invocation) -> mHearingAidProfile).
when(mLocalProfileManager).getHearingAidProfile();
+ doAnswer((invocation) -> mCsipSetCoordinatorProfile)
+ .when(mLocalProfileManager).getCsipSetCoordinatorProfile();
mCachedDeviceManager = new CachedBluetoothDeviceManager(mContext, mLocalBluetoothManager);
mCachedDevice1 = spy(new CachedBluetoothDevice(mContext, mLocalProfileManager, mDevice1));
mCachedDevice2 = spy(new CachedBluetoothDevice(mContext, mLocalProfileManager, mDevice2));
@@ -298,7 +312,7 @@ public class CachedBluetoothDeviceManagerTest {
* Test to verify OnDeviceUnpaired() for main hearing Aid device unpair.
*/
@Test
- public void onDeviceUnpaired_unpairMainDevice() {
+ public void onDeviceUnpaired_unpairHearingAidMainDevice() {
when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
@@ -398,4 +412,153 @@ public class CachedBluetoothDeviceManagerTest {
when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_NONE);
assertThat(mCachedDeviceManager.onDeviceDisappeared(cachedDevice1)).isTrue();
}
+
+ /**
+ * Test to verify getMemberDevice(), new device has the same group id.
+ */
+ @Test
+ public void addDevice_sameGroupId_validMemberDevice() {
+ doAnswer((invocation) -> CAP_GROUP1).when(mCsipSetCoordinatorProfile)
+ .getGroupUuidMapByDevice(mDevice1);
+ doAnswer((invocation) -> CAP_GROUP1).when(mCsipSetCoordinatorProfile)
+ .getGroupUuidMapByDevice(mDevice2);
+ doAnswer((invocation) -> CAP_GROUP1).when(mCsipSetCoordinatorProfile)
+ .getGroupUuidMapByDevice(mDevice3);
+ CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
+ CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
+ CachedBluetoothDevice cachedDevice3 = mCachedDeviceManager.addDevice(mDevice3);
+
+ assertThat(cachedDevice1.getMemberDevice()).contains(cachedDevice2);
+ assertThat(cachedDevice1.getMemberDevice()).contains(cachedDevice3);
+ }
+
+ /**
+ * Test to verify getMemberDevice(), new device has the different group id.
+ */
+ @Test
+ public void addDevice_differentGroupId_validMemberDevice() {
+ doAnswer((invocation) -> CAP_GROUP1).when(mCsipSetCoordinatorProfile)
+ .getGroupUuidMapByDevice(mDevice1);
+ doAnswer((invocation) -> CAP_GROUP2).when(mCsipSetCoordinatorProfile)
+ .getGroupUuidMapByDevice(mDevice2);
+ CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
+ CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
+
+ assertThat(cachedDevice1.getMemberDevice()).isEmpty();
+ }
+
+ /**
+ * Test to verify addDevice(), new device has the same group id.
+ */
+ @Test
+ public void addDevice_sameGroupId_validCachedDevices_mainDevicesAdded_memberDevicesNotAdded() {
+ doAnswer((invocation) -> CAP_GROUP1).when(mCsipSetCoordinatorProfile)
+ .getGroupUuidMapByDevice(mDevice1);
+ doAnswer((invocation) -> CAP_GROUP1).when(mCsipSetCoordinatorProfile)
+ .getGroupUuidMapByDevice(mDevice2);
+ CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
+ CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
+
+ Collection<CachedBluetoothDevice> devices = mCachedDeviceManager.getCachedDevicesCopy();
+ assertThat(devices).contains(cachedDevice1);
+ assertThat(devices).doesNotContain(cachedDevice2);
+ }
+
+ /**
+ * Test to verify addDevice(), new device has the different group id.
+ */
+ @Test
+ public void addDevice_differentGroupId_validCachedDevices_bothAdded() {
+ doAnswer((invocation) -> CAP_GROUP1).when(mCsipSetCoordinatorProfile)
+ .getGroupUuidMapByDevice(mDevice1);
+ doAnswer((invocation) -> CAP_GROUP2).when(mCsipSetCoordinatorProfile)
+ .getGroupUuidMapByDevice(mDevice2);
+ CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
+ CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
+
+ Collection<CachedBluetoothDevice> devices = mCachedDeviceManager.getCachedDevicesCopy();
+ assertThat(devices).contains(cachedDevice1);
+ assertThat(devices).contains(cachedDevice2);
+ }
+
+ /**
+ * Test to verify clearNonBondedDevices() for csip set member device.
+ */
+ @Test
+ public void clearNonBondedDevices_nonBondedMemberDevice() {
+ when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+ when(mDevice2.getBondState()).thenReturn(BluetoothDevice.BOND_NONE);
+ when(mDevice3.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+ CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
+ CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
+ CachedBluetoothDevice cachedDevice3 = mCachedDeviceManager.addDevice(mDevice3);
+ cachedDevice1.setMemberDevice(cachedDevice2);
+ cachedDevice1.setMemberDevice(cachedDevice3);
+
+ assertThat(cachedDevice1.getMemberDevice()).contains(cachedDevice2);
+ assertThat(cachedDevice1.getMemberDevice()).contains(cachedDevice3);
+ mCachedDeviceManager.clearNonBondedDevices();
+
+ assertThat(cachedDevice1.getMemberDevice().contains(cachedDevice2)).isFalse();
+ assertThat(cachedDevice1.getMemberDevice().contains(cachedDevice3)).isTrue();
+ }
+
+ /**
+ * Test to verify OnDeviceUnpaired() for csip device unpair.
+ */
+ @Test
+ public void onDeviceUnpaired_unpairCsipMainDevice() {
+ when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+ CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
+ CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
+ cachedDevice1.setGroupId(1);
+ cachedDevice2.setGroupId(1);
+ cachedDevice1.setMemberDevice(cachedDevice2);
+
+ // Call onDeviceUnpaired for the one in mCachedDevices.
+ mCachedDeviceManager.onDeviceUnpaired(cachedDevice1);
+ verify(mDevice2).removeBond();
+ }
+
+ /**
+ * Test to verify OnDeviceUnpaired() for csip device unpair.
+ */
+ @Test
+ public void onDeviceUnpaired_unpairCsipSubDevice() {
+ when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+ CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
+ CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
+ cachedDevice1.setGroupId(1);
+ cachedDevice2.setGroupId(1);
+ cachedDevice1.setMemberDevice(cachedDevice2);
+
+ // Call onDeviceUnpaired for the one in mCachedDevices.
+ mCachedDeviceManager.onDeviceUnpaired(cachedDevice2);
+ verify(mDevice1).removeBond();
+ }
+
+ /**
+ * Test to verify isSubDevice_validSubDevice().
+ */
+ @Test
+ public void isSubDevice_validMemberDevice() {
+ doReturn(CAP_GROUP1).when(mCsipSetCoordinatorProfile).getGroupUuidMapByDevice(mDevice1);
+ mCachedDeviceManager.addDevice(mDevice1);
+
+ // Both device are not sub device in default value.
+ assertThat(mCachedDeviceManager.isSubDevice(mDevice1)).isFalse();
+ assertThat(mCachedDeviceManager.isSubDevice(mDevice2)).isFalse();
+
+ // Add Device-2 as device with Device-1 with the same group id, and add Device-3 with
+ // the different group id.
+ doReturn(CAP_GROUP1).when(mCsipSetCoordinatorProfile).getGroupUuidMapByDevice(mDevice2);
+ doReturn(CAP_GROUP2).when(mCsipSetCoordinatorProfile).getGroupUuidMapByDevice(mDevice3);
+ mCachedDeviceManager.addDevice(mDevice2);
+ mCachedDeviceManager.addDevice(mDevice3);
+
+ // Verify Device-2 is sub device, but Device-1, and Device-3 is not.
+ assertThat(mCachedDeviceManager.isSubDevice(mDevice1)).isFalse();
+ assertThat(mCachedDeviceManager.isSubDevice(mDevice2)).isTrue();
+ assertThat(mCachedDeviceManager.isSubDevice(mDevice3)).isFalse();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt b/packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt
index c1db8edf4119..90064172dd36 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 @@ class LogBuffer(
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 @@ class LogBuffer(
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 @@ class LogBuffer(
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/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 4775127389d3..91cd2f6ad676 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -152,6 +152,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
int callerUid;
int callerPid;
+ boolean renounceFineLocationAccess;
+ boolean renounceCoarseLocationAccess;
Set<Integer> eventList;
@@ -995,14 +997,25 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
@Override
- public void listenWithEventList(int subId, String callingPackage, String callingFeatureId,
- IPhoneStateListener callback, int[] events, boolean notifyNow) {
+ public void listenWithEventList(boolean renounceFineLocationAccess,
+ boolean renounceCoarseLocationAccess, int subId, String callingPackage,
+ String callingFeatureId, IPhoneStateListener callback,
+ int[] events, boolean notifyNow) {
Set<Integer> eventList = Arrays.stream(events).boxed().collect(Collectors.toSet());
- listen(callingPackage, callingFeatureId, callback, eventList, notifyNow, subId);
+ listen(renounceFineLocationAccess, renounceFineLocationAccess, callingPackage,
+ callingFeatureId, callback, eventList, notifyNow, subId);
}
private void listen(String callingPackage, @Nullable String callingFeatureId,
IPhoneStateListener callback, Set<Integer> events, boolean notifyNow, int subId) {
+ listen(false, false, callingPackage,
+ callingFeatureId, callback, events, notifyNow, subId);
+ }
+
+ private void listen(boolean renounceFineLocationAccess,
+ boolean renounceCoarseLocationAccess, String callingPackage,
+ @Nullable String callingFeatureId, IPhoneStateListener callback,
+ Set<Integer> events, boolean notifyNow, int subId) {
int callerUserId = UserHandle.getCallingUserId();
mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
String str = "listen: E pkg=" + pii(callingPackage) + " uid=" + Binder.getCallingUid()
@@ -1047,6 +1060,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
r.callback = callback;
r.callingPackage = callingPackage;
r.callingFeatureId = callingFeatureId;
+ r.renounceCoarseLocationAccess = renounceCoarseLocationAccess;
+ r.renounceFineLocationAccess = renounceFineLocationAccess;
r.callerUid = Binder.getCallingUid();
r.callerPid = Binder.getCallingPid();
// Legacy applications pass SubscriptionManager.DEFAULT_SUB_ID,
@@ -3199,6 +3214,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
* If you don't need app compat logic, use {@link #checkFineLocationAccess(Record)}.
*/
private boolean checkFineLocationAccess(Record r, int minSdk) {
+ if (r.renounceFineLocationAccess) {
+ return false;
+ }
LocationAccessPolicy.LocationPermissionQuery query =
new LocationAccessPolicy.LocationPermissionQuery.Builder()
.setCallingPackage(r.callingPackage)
@@ -3225,6 +3243,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
* If you don't need app compat logic, use {@link #checkCoarseLocationAccess(Record)}.
*/
private boolean checkCoarseLocationAccess(Record r, int minSdk) {
+ if (r.renounceCoarseLocationAccess) {
+ return false;
+ }
LocationAccessPolicy.LocationPermissionQuery query =
new LocationAccessPolicy.LocationPermissionQuery.Builder()
.setCallingPackage(r.callingPackage)
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index c9112578705e..dd5ba6e55bae 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -91,6 +91,7 @@ import static android.provider.Settings.Global.DEBUG_APP;
import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
import static android.text.format.DateUtils.DAY_IN_MILLIS;
+import static android.util.FeatureFlagUtils.SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
@@ -300,6 +301,7 @@ import android.text.style.SuggestionSpan;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.EventLog;
+import android.util.FeatureFlagUtils;
import android.util.IntArray;
import android.util.Log;
import android.util.Pair;
@@ -14257,6 +14259,8 @@ public class ActivityManagerService extends IActivityManager.Stub
private void checkExcessivePowerUsage() {
updateCpuStatsNow();
+ final boolean monitorPhantomProcs = mSystemReady && FeatureFlagUtils.isEnabled(mContext,
+ SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS);
synchronized (mProcLock) {
final boolean doCpuKills = mLastPowerCheckUptime != 0;
final long curUptime = SystemClock.uptimeMillis();
@@ -14282,9 +14286,11 @@ public class ActivityManagerService extends IActivityManager.Stub
updateAppProcessCpuTimeLPr(uptimeSince, doCpuKills, checkDur, cpuLimit, app);
- // Also check the phantom processes if there is any
- updatePhantomProcessCpuTimeLPr(
- uptimeSince, doCpuKills, checkDur, cpuLimit, app);
+ if (monitorPhantomProcs) {
+ // Also check the phantom processes if there is any
+ updatePhantomProcessCpuTimeLPr(
+ uptimeSince, doCpuKills, checkDur, cpuLimit, app);
+ }
}
});
}
diff --git a/services/core/java/com/android/server/am/AppProfiler.java b/services/core/java/com/android/server/am/AppProfiler.java
index 36c0de919279..1496b30338f8 100644
--- a/services/core/java/com/android/server/am/AppProfiler.java
+++ b/services/core/java/com/android/server/am/AppProfiler.java
@@ -19,6 +19,7 @@ package com.android.server.am;
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
import static android.os.Process.FIRST_APPLICATION_UID;
+import static android.util.FeatureFlagUtils.SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS;
import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_LOW;
@@ -77,6 +78,7 @@ import android.provider.DeviceConfig.Properties;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.DebugUtils;
+import android.util.FeatureFlagUtils;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
@@ -1792,6 +1794,8 @@ public class AppProfiler {
}
void updateCpuStatsNow() {
+ final boolean monitorPhantomProcs = mService.mSystemReady && FeatureFlagUtils.isEnabled(
+ mService.mContext, SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS);
synchronized (mProcessCpuTracker) {
mProcessCpuMutexFree.set(false);
final long now = SystemClock.uptimeMillis();
@@ -1830,7 +1834,7 @@ public class AppProfiler {
}
}
- if (haveNewCpuStats) {
+ if (monitorPhantomProcs && haveNewCpuStats) {
mService.mPhantomProcessList.updateProcessCpuStatesLocked(mProcessCpuTracker);
}
diff --git a/services/core/java/com/android/server/am/PhantomProcessList.java b/services/core/java/com/android/server/am/PhantomProcessList.java
index b07684c9a004..2ec1aedd18f9 100644
--- a/services/core/java/com/android/server/am/PhantomProcessList.java
+++ b/services/core/java/com/android/server/am/PhantomProcessList.java
@@ -18,6 +18,7 @@ package com.android.server.am;
import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_ERROR;
import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT;
+import static android.util.FeatureFlagUtils.SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
@@ -28,6 +29,7 @@ import android.app.ApplicationExitInfo.SubReason;
import android.os.Handler;
import android.os.Process;
import android.os.StrictMode;
+import android.util.FeatureFlagUtils;
import android.util.Slog;
import android.util.SparseArray;
@@ -419,6 +421,10 @@ public final class PhantomProcessList {
* order of the oom adjs of their parent process.
*/
void trimPhantomProcessesIfNecessary() {
+ if (!mService.mSystemReady || !FeatureFlagUtils.isEnabled(mService.mContext,
+ SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS)) {
+ return;
+ }
synchronized (mService.mProcLock) {
synchronized (mLock) {
mTrimPhantomProcessScheduled = false;
diff --git a/services/core/java/com/android/server/wm/RefreshRatePolicy.java b/services/core/java/com/android/server/wm/RefreshRatePolicy.java
index b63843dd20d4..7bddb620c94d 100644
--- a/services/core/java/com/android/server/wm/RefreshRatePolicy.java
+++ b/services/core/java/com/android/server/wm/RefreshRatePolicy.java
@@ -164,7 +164,19 @@ class RefreshRatePolicy {
return 0;
}
- return w.mAttrs.preferredMinDisplayRefreshRate;
+ if (w.mAttrs.preferredMinDisplayRefreshRate > 0) {
+ return w.mAttrs.preferredMinDisplayRefreshRate;
+ }
+
+ String packageName = w.getOwningPackage();
+ // If app is using Camera, we set both the min and max refresh rate to the camera's
+ // preferred refresh rate to make sure we don't end up with a refresh rate lower
+ // than the camera capture rate, which will lead to dropping camera frames.
+ if (mNonHighRefreshRatePackages.contains(packageName)) {
+ return mLowRefreshRateMode.getRefreshRate();
+ }
+
+ return 0;
}
float getPreferredMaxRefreshRate(WindowState w) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java
index c4cccf022322..19247604ad10 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java
@@ -104,7 +104,8 @@ public class RefreshRatePolicyTest extends WindowTestsBase {
mPolicy.addNonHighRefreshRatePackage("com.android.test");
assertEquals(0, mPolicy.getPreferredModeId(cameraUsingWindow));
assertEquals(0, mPolicy.getPreferredRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
- assertEquals(0, mPolicy.getPreferredMinRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
+ assertEquals(LOW_REFRESH_RATE,
+ mPolicy.getPreferredMinRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
assertEquals(LOW_REFRESH_RATE,
mPolicy.getPreferredMaxRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
mPolicy.removeNonHighRefreshRatePackage("com.android.test");
@@ -165,7 +166,8 @@ public class RefreshRatePolicyTest extends WindowTestsBase {
assertEquals(HI_MODE_ID, mPolicy.getPreferredModeId(overrideWindow));
assertEquals(HI_REFRESH_RATE,
mPolicy.getPreferredRefreshRate(overrideWindow), FLOAT_TOLERANCE);
- assertEquals(0, mPolicy.getPreferredMinRefreshRate(overrideWindow), FLOAT_TOLERANCE);
+ assertEquals(LOW_REFRESH_RATE,
+ mPolicy.getPreferredMinRefreshRate(overrideWindow), FLOAT_TOLERANCE);
assertEquals(LOW_REFRESH_RATE,
mPolicy.getPreferredMaxRefreshRate(overrideWindow), FLOAT_TOLERANCE);
}
@@ -180,7 +182,8 @@ public class RefreshRatePolicyTest extends WindowTestsBase {
assertEquals(0, mPolicy.getPreferredModeId(overrideWindow));
assertEquals(HI_REFRESH_RATE,
mPolicy.getPreferredRefreshRate(overrideWindow), FLOAT_TOLERANCE);
- assertEquals(0, mPolicy.getPreferredMinRefreshRate(overrideWindow), FLOAT_TOLERANCE);
+ assertEquals(LOW_REFRESH_RATE,
+ mPolicy.getPreferredMinRefreshRate(overrideWindow), FLOAT_TOLERANCE);
assertEquals(LOW_REFRESH_RATE,
mPolicy.getPreferredMaxRefreshRate(overrideWindow), FLOAT_TOLERANCE);
}
@@ -257,7 +260,8 @@ public class RefreshRatePolicyTest extends WindowTestsBase {
mPolicy.addNonHighRefreshRatePackage("com.android.test");
assertEquals(0, mPolicy.getPreferredModeId(cameraUsingWindow));
assertEquals(0, mPolicy.getPreferredRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
- assertEquals(0, mPolicy.getPreferredMinRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
+ assertEquals(LOW_REFRESH_RATE,
+ mPolicy.getPreferredMinRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
assertEquals(LOW_REFRESH_RATE,
mPolicy.getPreferredMaxRefreshRate(cameraUsingWindow), FLOAT_TOLERANCE);
diff --git a/telephony/java/android/telephony/SignalStrengthUpdateRequest.java b/telephony/java/android/telephony/SignalStrengthUpdateRequest.java
index 9cb80f1814f9..4884d549e2e0 100644
--- a/telephony/java/android/telephony/SignalStrengthUpdateRequest.java
+++ b/telephony/java/android/telephony/SignalStrengthUpdateRequest.java
@@ -19,6 +19,7 @@ package android.telephony;
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 @@ public final class SignalStrengthUpdateRequest implements Parcelable {
/**
* 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 @@ public final class SignalStrengthUpdateRequest implements Parcelable {
* @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 @@ public final class SignalStrengthUpdateRequest implements Parcelable {
*
* @hide
*/
+ @SystemApi
public boolean isSystemThresholdReportingRequestedWhileIdle() {
return mIsSystemThresholdReportingRequestedWhileIdle;
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 1029214b0222..6286390ba139 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -8321,12 +8321,58 @@ public class TelephonyManager {
public NetworkScan requestNetworkScan(
NetworkScanRequest request, Executor executor,
TelephonyScanManager.NetworkScanCallback callback) {
- synchronized (this) {
+ return requestNetworkScan(false, request, executor, callback);
+ }
+
+ /**
+ * Request a network scan.
+ *
+ * This method is asynchronous, so the network scan results will be returned by callback.
+ * The returned NetworkScan will contain a callback method which can be used to stop the scan.
+ *
+ * <p>Requires Permission:
+ * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling
+ * app has carrier privileges (see {@link #hasCarrierPrivileges})
+ * and {@link android.Manifest.permission#ACCESS_FINE_LOCATION}.
+ *
+ * If the system-wide location switch is off, apps may still call this API, with the
+ * following constraints:
+ * <ol>
+ * <li>The app must hold the {@code android.permission.NETWORK_SCAN} permission.</li>
+ * <li>The app must not supply any specific bands or channels to scan.</li>
+ * <li>The app must only specify MCC/MNC pairs that are
+ * associated to a SIM in the device.</li>
+ * <li>Returned results will have no meaningful info other than signal strength
+ * and MCC/MNC info.</li>
+ * </ol>
+ *
+ * @param renounceFineLocationAccess Set this to true if the caller would not like to receive
+ * location related information which will be sent if the caller already possess
+ * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and do not renounce the permission
+ * @param request Contains all the RAT with bands/channels that need to be scanned.
+ * @param executor The executor through which the callback should be invoked. Since the scan
+ * request may trigger multiple callbacks and they must be invoked in the same order as
+ * they are received by the platform, the user should provide an executor which executes
+ * tasks one at a time in serial order. For example AsyncTask.SERIAL_EXECUTOR.
+ * @param callback Returns network scan results or errors.
+ * @return A NetworkScan obj which contains a callback which can be used to stop the scan.
+ */
+ @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
+ @RequiresPermission(allOf = {
+ android.Manifest.permission.MODIFY_PHONE_STATE,
+ Manifest.permission.ACCESS_FINE_LOCATION
+ })
+ public @Nullable NetworkScan requestNetworkScan(
+ boolean renounceFineLocationAccess, @NonNull NetworkScanRequest request,
+ @NonNull Executor executor,
+ @NonNull TelephonyScanManager.NetworkScanCallback callback) {
+ synchronized (sCacheLock) {
if (mTelephonyScanManager == null) {
mTelephonyScanManager = new TelephonyScanManager();
}
}
- return mTelephonyScanManager.requestNetworkScan(getSubId(), request, executor, callback,
+ return mTelephonyScanManager.requestNetworkScan(getSubId(), renounceFineLocationAccess,
+ request, executor, callback,
getOpPackageName(), getAttributionTag());
}
@@ -11387,7 +11433,6 @@ public class TelephonyManager {
* <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
* or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges})
* and {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}.
- *
* May return {@code null} when the subscription is inactive or when there was an error
* communicating with the phone process.
*/
@@ -11397,7 +11442,39 @@ public class TelephonyManager {
Manifest.permission.ACCESS_COARSE_LOCATION
})
public @Nullable ServiceState getServiceState() {
- return getServiceStateForSubscriber(getSubId());
+ return getServiceState(false, false);
+ }
+
+ /**
+ * Returns the current {@link ServiceState} information.
+ *
+ * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
+ * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}
+ *
+ * If you want continuous updates of service state info, register a {@link PhoneStateListener}
+ * via {@link #listen} with the {@link PhoneStateListener#LISTEN_SERVICE_STATE} event.
+ *
+ * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+ * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges})
+ * and {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}.
+ * @param renounceFineLocationAccess Set this to true if the caller would not like to receive
+ * location related information which will be sent if the caller already possess
+ * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and do not renounce the permission
+ * @param renounceCoarseLocationAccess Set this to true if the caller would not like to
+ * receive location related information which will be sent if the caller already possess
+ * {@link Manifest.permission#ACCESS_COARSE_LOCATION} and do not renounce the permissions.
+ * May return {@code null} when the subscription is inactive or when there was an error
+ * communicating with the phone process.
+ */
+ @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
+ @RequiresPermission(allOf = {
+ Manifest.permission.READ_PHONE_STATE,
+ Manifest.permission.ACCESS_COARSE_LOCATION
+ })
+ public @Nullable ServiceState getServiceState(boolean renounceFineLocationAccess,
+ boolean renounceCoarseLocationAccess) {
+ return getServiceStateForSubscriber(getSubId(), renounceFineLocationAccess,
+ renounceCoarseLocationAccess);
}
/**
@@ -11406,15 +11483,22 @@ public class TelephonyManager {
*
* May return {@code null} when the subscription is inactive or when there was an error
* communicating with the phone process.
- * @hide
+ * @param renounceFineLocationAccess Set this to true if the caller would not like to receive
+ * location related information which will be sent if the caller already possess
+ * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and do not renounce the permission
+ * @param renounceCoarseLocationAccess Set this to true if the caller would not like to
+ * receive location related information which will be sent if the caller already possess
+ * {@link Manifest.permission#ACCESS_COARSE_LOCATION} and do not renounce the permissions.
*/
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
- public ServiceState getServiceStateForSubscriber(int subId) {
+ private ServiceState getServiceStateForSubscriber(int subId,
+ boolean renounceFineLocationAccess,
+ boolean renounceCoarseLocationAccess) {
try {
ITelephony service = getITelephony();
if (service != null) {
- return service.getServiceStateForSubscriber(subId, getOpPackageName(),
- getAttributionTag());
+ return service.getServiceStateForSubscriber(subId, renounceFineLocationAccess,
+ renounceCoarseLocationAccess,
+ getOpPackageName(), getAttributionTag());
}
} catch (RemoteException e) {
Log.e(TAG, "Error calling ITelephony#getServiceStateForSubscriber", e);
@@ -11427,6 +11511,19 @@ public class TelephonyManager {
}
/**
+ * Returns the service state information on specified subscription. Callers require
+ * either READ_PRIVILEGED_PHONE_STATE or READ_PHONE_STATE to retrieve the information.
+ *
+ * May return {@code null} when the subscription is inactive or when there was an error
+ * communicating with the phone process.
+ * @hide
+ */
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+ public ServiceState getServiceStateForSubscriber(int subId) {
+ return getServiceStateForSubscriber(getSubId(), false, false);
+ }
+
+ /**
* Returns the URI for the per-account voicemail ringtone set in Phone settings.
*
* @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
@@ -15274,7 +15371,49 @@ public class TelephonyManager {
*/
public void registerTelephonyCallback(@NonNull @CallbackExecutor Executor executor,
@NonNull TelephonyCallback callback) {
+ registerTelephonyCallback(false, false, executor, callback);
+ }
+ /**
+ * Registers a callback object to receive notification of changes in specified telephony states.
+ * <p>
+ * To register a callback, pass a {@link TelephonyCallback} which implements
+ * interfaces of events. For example,
+ * FakeServiceStateCallback extends {@link TelephonyCallback} implements
+ * {@link TelephonyCallback.ServiceStateListener}.
+ *
+ * At registration, and when a specified telephony state changes, the telephony manager invokes
+ * the appropriate callback method on the callback object and passes the current (updated)
+ * values.
+ * <p>
+ *
+ * If this TelephonyManager object has been created with {@link #createForSubscriptionId},
+ * applies to the given subId. Otherwise, applies to
+ * {@link SubscriptionManager#getDefaultSubscriptionId()}. To register events for multiple
+ * subIds, pass a separate callback object to each TelephonyManager object created with
+ * {@link #createForSubscriptionId}.
+ *
+ * Note: if you call this method while in the middle of a binder transaction, you <b>must</b>
+ * call {@link android.os.Binder#clearCallingIdentity()} before calling this method. A
+ * {@link SecurityException} will be thrown otherwise.
+ *
+ * This API should be used sparingly -- large numbers of callbacks will cause system
+ * instability. If a process has registered too many callbacks without unregistering them, it
+ * may encounter an {@link IllegalStateException} when trying to register more callbacks.
+ *
+ * @param renounceFineLocationAccess Set this to true if the caller would not like to receive
+ * location related information which will be sent if the caller already possess
+ * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and do not renounce the permissions.
+ * @param renounceCoarseLocationAccess Set this to true if the caller would not like to
+ * receive location related information which will be sent if the caller already possess
+ * {@link Manifest.permission#ACCESS_COARSE_LOCATION} and do not renounce the permissions.
+ * @param executor The executor of where the callback will execute.
+ * @param callback The {@link TelephonyCallback} object to register.
+ */
+ public void registerTelephonyCallback(boolean renounceFineLocationAccess,
+ boolean renounceCoarseLocationAccess,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull TelephonyCallback callback) {
if (mContext == null) {
throw new IllegalStateException("telephony service is null.");
}
@@ -15285,7 +15424,8 @@ public class TelephonyManager {
mTelephonyRegistryMgr = (TelephonyRegistryManager)
mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
if (mTelephonyRegistryMgr != null) {
- mTelephonyRegistryMgr.registerTelephonyCallback(executor, mSubId, getOpPackageName(),
+ mTelephonyRegistryMgr.registerTelephonyCallback(renounceFineLocationAccess,
+ renounceCoarseLocationAccess, executor, mSubId, getOpPackageName(),
getAttributionTag(), callback, getITelephony() != null);
} else {
throw new IllegalStateException("telephony service is null.");
diff --git a/telephony/java/android/telephony/TelephonyScanManager.java b/telephony/java/android/telephony/TelephonyScanManager.java
index 9572154ec773..122662d3d7c8 100644
--- a/telephony/java/android/telephony/TelephonyScanManager.java
+++ b/telephony/java/android/telephony/TelephonyScanManager.java
@@ -228,7 +228,9 @@ public final class TelephonyScanManager {
* {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and
* {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
* Or the calling app has carrier privileges. @see #hasCarrierPrivileges
- *
+ * @param renounceFineLocationAccess Set this to true if the caller would not like to receive
+ * location related information which will be sent if the caller already possess
+ * {@link android.Manifest.permission.ACCESS_FINE_LOCATION} and do not renounce the permission
* @param request Contains all the RAT with bands/channels that need to be scanned.
* @param callback Returns network scan results or errors.
* @param callingPackage The package name of the caller
@@ -237,6 +239,7 @@ public final class TelephonyScanManager {
* @hide
*/
public NetworkScan requestNetworkScan(int subId,
+ boolean renounceFineLocationAccess,
NetworkScanRequest request, Executor executor, NetworkScanCallback callback,
String callingPackage, @Nullable String callingFeatureId) {
try {
@@ -252,7 +255,8 @@ public final class TelephonyScanManager {
// the record to the ScanInfo cache.
synchronized (mScanInfo) {
int scanId = telephony.requestNetworkScan(
- subId, request, mMessenger, new Binder(), callingPackage,
+ subId, renounceFineLocationAccess, request, mMessenger,
+ new Binder(), callingPackage,
callingFeatureId);
if (scanId == INVALID_SCAN_ID) {
Rlog.e(TAG, "Failed to initiate network scan");
diff --git a/telephony/java/android/telephony/ims/RcsClientConfiguration.java b/telephony/java/android/telephony/ims/RcsClientConfiguration.java
index 793c37745de6..c25ace0c6a62 100644
--- a/telephony/java/android/telephony/ims/RcsClientConfiguration.java
+++ b/telephony/java/android/telephony/ims/RcsClientConfiguration.java
@@ -50,6 +50,7 @@ public final class RcsClientConfiguration implements Parcelable {
private String mRcsProfile;
private String mClientVendor;
private String mClientVersion;
+ private boolean mRcsEnabledByUser;
/**
* Create a RcsClientConfiguration object.
@@ -63,14 +64,41 @@ public final class RcsClientConfiguration implements Parcelable {
* @param clientVersion Identifies the RCS client version. Refer to GSMA
* RCC.07 "client_version" parameter.
* Example:client_version=RCSAndrd-1.0
+ * @deprecated Use {@link #RcsClientConfiguration(String, String, String, String, boolean)}
+ * instead. Deprecated prototype assumes that the user setting controlling RCS is enabled.
*/
+ @Deprecated
public RcsClientConfiguration(@NonNull String rcsVersion,
@NonNull @StringRcsProfile String rcsProfile,
@NonNull String clientVendor, @NonNull String clientVersion) {
+ this(rcsVersion, rcsProfile, clientVendor, clientVersion, true);
+ }
+
+ /**
+ * Create a RcsClientConfiguration object.
+ * Default messaging application must pass a valid configuration object
+ * @param rcsVersion The parameter identifies the RCS version supported
+ * by the client. Refer to GSMA RCC.07 "rcs_version" parameter.
+ * @param rcsProfile Identifies a fixed set of RCS services that are
+ * supported by the client. See {@link #RCS_PROFILE_1_0 } or
+ * {@link #RCS_PROFILE_2_3 }
+ * @param clientVendor Identifies the vendor providing the RCS client.
+ * @param clientVersion Identifies the RCS client version. Refer to GSMA
+ * RCC.07 "client_version" parameter.
+ * Example:client_version=RCSAndrd-1.0
+ * @param isRcsEnabledByUser The current user setting for whether or not the user has
+ * enabled or disabled RCS. Please refer to GSMA RCC.07 "rcs_state" parameter for how this
+ * can affect provisioning.
+ */
+ public RcsClientConfiguration(@NonNull String rcsVersion,
+ @NonNull @StringRcsProfile String rcsProfile,
+ @NonNull String clientVendor, @NonNull String clientVersion,
+ boolean isRcsEnabledByUser) {
mRcsVersion = rcsVersion;
mRcsProfile = rcsProfile;
mClientVendor = clientVendor;
mClientVersion = clientVersion;
+ mRcsEnabledByUser = isRcsEnabledByUser;
}
/**
@@ -102,6 +130,18 @@ public final class RcsClientConfiguration implements Parcelable {
}
/**
+ * The current user setting provided by the RCS messaging application that determines
+ * whether or not the user has enabled RCS.
+ * <p>
+ * See GSMA RCC.07 "rcs_state" parameter for more information about how this setting
+ * affects provisioning.
+ * @return true if RCS is enabled by the user, false if RCS is disabled by the user.
+ */
+ public boolean isRcsEnabledByUser() {
+ return mRcsEnabledByUser;
+ }
+
+ /**
* {@link Parcelable#writeToParcel}
*/
@Override
@@ -110,6 +150,7 @@ public final class RcsClientConfiguration implements Parcelable {
out.writeString(mRcsProfile);
out.writeString(mClientVendor);
out.writeString(mClientVersion);
+ out.writeBoolean(mRcsEnabledByUser);
}
/**
@@ -124,8 +165,9 @@ public final class RcsClientConfiguration implements Parcelable {
String rcsProfile = in.readString();
String clientVendor = in.readString();
String clientVersion = in.readString();
+ Boolean rcsEnabledByUser = in.readBoolean();
return new RcsClientConfiguration(rcsVersion, rcsProfile,
- clientVendor, clientVersion);
+ clientVendor, clientVersion, rcsEnabledByUser);
}
@Override
@@ -152,11 +194,13 @@ public final class RcsClientConfiguration implements Parcelable {
return mRcsVersion.equals(other.mRcsVersion) && mRcsProfile.equals(other.mRcsProfile)
&& mClientVendor.equals(other.mClientVendor)
- && mClientVersion.equals(other.mClientVersion);
+ && mClientVersion.equals(other.mClientVersion)
+ && (mRcsEnabledByUser == other.mRcsEnabledByUser);
}
@Override
public int hashCode() {
- return Objects.hash(mRcsVersion, mRcsProfile, mClientVendor, mClientVersion);
+ return Objects.hash(mRcsVersion, mRcsProfile, mClientVendor, mClientVersion,
+ mRcsEnabledByUser);
}
}
diff --git a/telephony/java/android/telephony/ims/RcsUceAdapter.java b/telephony/java/android/telephony/ims/RcsUceAdapter.java
index 7a1c09275a6d..61de3ac2b25e 100644
--- a/telephony/java/android/telephony/ims/RcsUceAdapter.java
+++ b/telephony/java/android/telephony/ims/RcsUceAdapter.java
@@ -28,13 +28,10 @@ import android.os.Binder;
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 @@ public class RcsUceAdapter {
@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 @@ public class RcsUceAdapter {
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 @@ public class RcsUceAdapter {
* <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 @@ public class RcsUceAdapter {
* <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 @@ public class RcsUceAdapter {
* 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 @@ public class RcsUceAdapter {
* 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 @@ public class RcsUceAdapter {
* 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 c3d7325f2e0a..c27fa4fc882d 100644
--- a/telephony/java/android/telephony/ims/aidl/CapabilityExchangeAidlWrapper.java
+++ b/telephony/java/android/telephony/ims/aidl/CapabilityExchangeAidlWrapper.java
@@ -81,6 +81,26 @@ public class CapabilityExchangeAidlWrapper implements CapabilityExchangeEventLis
}
/**
+ * 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 078ac919b75e..c675bc3204f6 100644
--- a/telephony/java/android/telephony/ims/aidl/ICapabilityExchangeEventListener.aidl
+++ b/telephony/java/android/telephony/ims/aidl/ICapabilityExchangeEventListener.aidl
@@ -31,6 +31,8 @@ import java.util.List;
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 a3be8dab2891..9293a40d9a33 100644
--- a/telephony/java/android/telephony/ims/stub/CapabilityExchangeEventListener.java
+++ b/telephony/java/android/telephony/ims/stub/CapabilityExchangeEventListener.java
@@ -90,6 +90,30 @@ public interface CapabilityExchangeEventListener {
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>
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 2df5f53147bc..03010f6b27b6 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -900,6 +900,8 @@ interface ITelephony {
* Perform a radio network scan and return the id of this scan.
*
* @param subId the id of the subscription.
+ * @param renounceFineLocationAccess Set this to true if the caller would not like to
+ * receive fine location related information
* @param request Defines all the configs for network scan.
* @param messenger Callback messages will be sent using this messenger.
* @param binder the binder object instantiated in TelephonyManager.
@@ -907,8 +909,9 @@ interface ITelephony {
* @param callingFeatureId The feature in the package
* @return An id for this scan.
*/
- int requestNetworkScan(int subId, in NetworkScanRequest request, in Messenger messenger,
- in IBinder binder, in String callingPackage, String callingFeatureId);
+ int requestNetworkScan(int subId, in boolean renounceFineLocationAccess,
+ in NetworkScanRequest request, in Messenger messenger, in IBinder binder,
+ in String callingPackage, String callingFeatureId);
/**
* Stop an existing radio network scan.
@@ -1387,12 +1390,17 @@ interface ITelephony {
/**
* Get the service state on specified subscription
* @param subId Subscription id
+ * @param renounceFineLocationAccess Set this to true if the caller would not like to
+ * receive fine location related information
+ * @param renounceCoarseLocationAccess Set this to true if the caller would not like to
+ * receive coarse location related information
* @param callingPackage The package making the call
* @param callingFeatureId The feature in the package
* @return Service state on specified subscription.
*/
- ServiceState getServiceStateForSubscriber(int subId, String callingPackage,
- String callingFeatureId);
+ ServiceState getServiceStateForSubscriber(int subId, boolean renounceFineLocationAccess,
+ boolean renounceCoarseLocationAccess,
+ String callingPackage, String callingFeatureId);
/**
* Returns the URI for the per-account voicemail ringtone set in Phone settings.