Merge changes from topic "presubmit-am-c548fd9918a542cebc9e4b0f87a44f0b" into sc-v2-dev-plus-aosp
* changes:
[automerge] Fixing not responsive tiles in split shade 2p: ab0a84d7a8
Fixing not responsive tiles in split shade
diff --git a/Android.bp b/Android.bp
index c9391cb..cdfc33e 100644
--- a/Android.bp
+++ b/Android.bp
@@ -97,7 +97,7 @@
":platform-compat-native-aidl",
// AIDL sources from external directories
- ":android.hardware.security.keymint-V1-java-source",
+ ":android.hardware.security.keymint-V2-java-source",
":android.hardware.security.secureclock-V1-java-source",
":android.security.apc-java-source",
":android.security.authorization-java-source",
diff --git a/Android.mk b/Android.mk
index 46529eb..d9e202c 100644
--- a/Android.mk
+++ b/Android.mk
@@ -15,6 +15,14 @@
#
LOCAL_PATH := $(call my-dir)
+$(eval $(call declare-1p-copy-files,frameworks/base,.ogg))
+$(eval $(call declare-1p-copy-files,frameworks/base,.kl))
+$(eval $(call declare-1p-copy-files,frameworks/base,.kcm))
+$(eval $(call declare-1p-copy-files,frameworks/base,.idc))
+$(eval $(call declare-1p-copy-files,frameworks/base,dirty-image-objects))
+$(eval $(call declare-1p-copy-files,frameworks/base/config,))
+$(eval $(call declare-1p-copy-files,frameworks/native/data,))
+
# Load framework-specific path mappings used later in the build.
include $(LOCAL_PATH)/pathmap.mk
diff --git a/apex/media/Android.bp b/apex/media/Android.bp
index 1a710a9..96e88dd 100644
--- a/apex/media/Android.bp
+++ b/apex/media/Android.bp
@@ -18,11 +18,7 @@
"//frameworks/av/apex/testing",
],
// See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "frameworks_base_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["frameworks_base_license"],
+ default_applicable_licenses: ["Android-Apache-2.0"],
}
sdk {
diff --git a/apex/media/aidl/Android.bp b/apex/media/aidl/Android.bp
index 545a0cd..4ba0d9b 100644
--- a/apex/media/aidl/Android.bp
+++ b/apex/media/aidl/Android.bp
@@ -16,11 +16,7 @@
package {
// See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "frameworks_base_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["frameworks_base_license"],
+ default_applicable_licenses: ["Android-Apache-2.0"],
}
filegroup {
diff --git a/apex/media/framework/Android.bp b/apex/media/framework/Android.bp
index 6195f257e..a5e6df1 100644
--- a/apex/media/framework/Android.bp
+++ b/apex/media/framework/Android.bp
@@ -14,11 +14,7 @@
package {
// See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "frameworks_base_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["frameworks_base_license"],
+ default_applicable_licenses: ["Android-Apache-2.0"],
}
java_library {
@@ -65,6 +61,7 @@
"//frameworks/av/apex:__subpackages__",
"//frameworks/base/apex/media/service",
"//frameworks/base/api", // For framework-all
+ "//packages/modules/Media/apex/service",
],
}
diff --git a/apex/media/service/Android.bp b/apex/media/service/Android.bp
index 271fc53..1911735 100644
--- a/apex/media/service/Android.bp
+++ b/apex/media/service/Android.bp
@@ -13,11 +13,7 @@
// limitations under the License.
package {
// See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "frameworks_base_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["frameworks_base_license"],
+ default_applicable_licenses: ["Android-Apache-2.0"],
}
filegroup {
diff --git a/core/api/current.txt b/core/api/current.txt
index f7e5273..17551f5 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -40057,6 +40057,7 @@
field public static final String KEY_RCS_BULK_CAPABILITY_EXCHANGE_BOOL = "ims.rcs_bulk_capability_exchange_bool";
field public static final String KEY_RCS_FEATURE_TAG_ALLOWED_STRING_ARRAY = "ims.rcs_feature_tag_allowed_string_array";
field public static final String KEY_RCS_REQUIRES_PROVISIONING_BUNDLE = "ims.rcs_requires_provisioning_bundle";
+ field public static final String KEY_USE_SIP_URI_FOR_PRESENCE_SUBSCRIBE_BOOL = "ims.use_sip_uri_for_presence_subscribe_bool";
field public static final String KEY_WIFI_OFF_DEFERRING_TIME_MILLIS_INT = "ims.wifi_off_deferring_time_millis_int";
}
@@ -41133,16 +41134,16 @@
ctor @Deprecated public ServiceState(android.os.Parcel);
method protected void copyFrom(android.telephony.ServiceState);
method public int describeContents();
- method public int getCdmaNetworkId();
- method public int getCdmaSystemId();
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION}) public int getCdmaNetworkId();
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION}) public int getCdmaSystemId();
method public int[] getCellBandwidths();
method public int getChannelNumber();
method public int getDuplexMode();
method public boolean getIsManualSelection();
method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoList();
- method public String getOperatorAlphaLong();
- method public String getOperatorAlphaShort();
- method public String getOperatorNumeric();
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION}) public String getOperatorAlphaLong();
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION}) public String getOperatorAlphaShort();
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION}) public String getOperatorNumeric();
method public boolean getRoaming();
method public int getState();
method public boolean isSearching();
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index c50b9e9..b6057e2 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -13289,6 +13289,7 @@
method @Nullable public android.telephony.ims.RcsContactPresenceTuple getCapabilityTuple(@NonNull String);
method @NonNull public java.util.List<android.telephony.ims.RcsContactPresenceTuple> getCapabilityTuples();
method @NonNull public android.net.Uri getContactUri();
+ method @Nullable public android.net.Uri getEntityUri();
method @NonNull public java.util.Set<java.lang.String> getFeatureTags();
method public int getRequestResult();
method public int getSourceType();
@@ -13317,6 +13318,7 @@
method @NonNull public android.telephony.ims.RcsContactUceCapability.PresenceBuilder addCapabilityTuple(@NonNull android.telephony.ims.RcsContactPresenceTuple);
method @NonNull public android.telephony.ims.RcsContactUceCapability.PresenceBuilder addCapabilityTuples(@NonNull java.util.List<android.telephony.ims.RcsContactPresenceTuple>);
method @NonNull public android.telephony.ims.RcsContactUceCapability build();
+ method @NonNull public android.telephony.ims.RcsContactUceCapability.PresenceBuilder setEntityUri(@NonNull android.net.Uri);
}
public class RcsUceAdapter {
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 550d1d8..3e236b5 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -3103,11 +3103,18 @@
}
}
- /** @hide */
- public void resetNewUserDisclaimer() {
+ /**
+ * Acknoledges that the new managed user disclaimer was viewed by the (human) user
+ * so that {@link #ACTION_SHOW_NEW_USER_DISCLAIMER broadcast} is not sent again the next time
+ * this user is switched to.
+ *
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
+ public void acknowledgeNewUserDisclaimer() {
if (mService != null) {
try {
- mService.resetNewUserDisclaimer();
+ mService.acknowledgeNewUserDisclaimer();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -5673,7 +5680,7 @@
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_SHOW_NEW_USER_DISCLAIMER =
- "android.app.action.ACTION_SHOW_NEW_USER_DISCLAIMER";
+ "android.app.action.SHOW_NEW_USER_DISCLAIMER";
/**
* Widgets are enabled in keyguard
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 7ad8379..4f6ed5c 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -265,7 +265,7 @@
int getLogoutUserId();
void clearLogoutUser();
List<UserHandle> getSecondaryUsers(in ComponentName who);
- void resetNewUserDisclaimer();
+ void acknowledgeNewUserDisclaimer();
void enableSystemApp(in ComponentName admin, in String callerPackage, in String packageName);
int enableSystemAppWithIntent(in ComponentName admin, in String callerPackage, in Intent intent);
diff --git a/core/java/android/app/assist/OWNERS b/core/java/android/app/assist/OWNERS
index 46b5ea0..e857c72 100644
--- a/core/java/android/app/assist/OWNERS
+++ b/core/java/android/app/assist/OWNERS
@@ -1,7 +1,5 @@
-joannechung@google.com
-adamhe@google.com
-tymtsai@google.com
-lpeter@google.com
augale@google.com
-svetoslavganov@android.com
-svetoslavganov@google.com
+joannechung@google.com
+markpun@google.com
+lpeter@google.com
+tymtsai@google.com
diff --git a/core/java/android/app/contentsuggestions/OWNERS b/core/java/android/app/contentsuggestions/OWNERS
index 482abb2..cf54c2a 100644
--- a/core/java/android/app/contentsuggestions/OWNERS
+++ b/core/java/android/app/contentsuggestions/OWNERS
@@ -1,9 +1,7 @@
# Bug component: 643919
-joannechung@google.com
-adamhe@google.com
-tymtsai@google.com
-lpeter@google.com
augale@google.com
-svetoslavganov@android.com
-svetoslavganov@google.com
+joannechung@google.com
+markpun@google.com
+lpeter@google.com
+tymtsai@google.com
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index c9d1f54..2df5eec 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3438,7 +3438,7 @@
public abstract boolean stopServiceAsUser(Intent service, UserHandle user);
/**
- * Connect to an application service, creating it if needed. This defines
+ * Connects to an application service, creating it if needed. This defines
* a dependency between your application and the service. The given
* <var>conn</var> will receive the service object when it is created and be
* told if it dies and restarts. The service will be considered required
@@ -3453,11 +3453,8 @@
* will be invoked instead of
* {@link ServiceConnection#onServiceConnected(ComponentName, IBinder) onServiceConnected()}.
*
- * <p>This method will throw {@link SecurityException} if the calling app does not
- * have permission to bind to the given service.
- *
- * <p class="note">Note: this method <em>cannot be called from a
- * {@link BroadcastReceiver} component</em>. A pattern you can use to
+ * <p class="note"><b>Note:</b> This method <em>cannot</em> be called from a
+ * {@link BroadcastReceiver} component. A pattern you can use to
* communicate from a BroadcastReceiver to a Service is to call
* {@link #startService} with the arguments containing the command to be
* sent, with the service calling its
@@ -3472,34 +3469,34 @@
* specify an explicit component name.
* @param conn Receives information as the service is started and stopped.
* This must be a valid ServiceConnection object; it must not be null.
- * @param flags Operation options for the binding. May be 0,
- * {@link #BIND_AUTO_CREATE}, {@link #BIND_DEBUG_UNBIND},
- * {@link #BIND_NOT_FOREGROUND}, {@link #BIND_ABOVE_CLIENT},
- * {@link #BIND_ALLOW_OOM_MANAGEMENT}, {@link #BIND_WAIVE_PRIORITY}.
- * {@link #BIND_IMPORTANT}, {@link #BIND_ADJUST_WITH_ACTIVITY},
- * {@link #BIND_NOT_PERCEPTIBLE}, or {@link #BIND_INCLUDE_CAPABILITIES}.
- * @return {@code true} if the system is in the process of bringing up a
+ * @param flags Operation options for the binding. Can be:
+ * <ul>
+ * <li>0
+ * <li>{@link #BIND_AUTO_CREATE}
+ * <li>{@link #BIND_DEBUG_UNBIND}
+ * <li>{@link #BIND_NOT_FOREGROUND}
+ * <li>{@link #BIND_ABOVE_CLIENT}
+ * <li>{@link #BIND_ALLOW_OOM_MANAGEMENT}
+ * <li>{@link #BIND_WAIVE_PRIORITY}
+ * <li>{@link #BIND_IMPORTANT}
+ * <li>{@link #BIND_ADJUST_WITH_ACTIVITY}
+ * <li>{@link #BIND_NOT_PERCEPTIBLE}
+ * <li>{@link #BIND_INCLUDE_CAPABILITIES}
+ * </ul>
+ *
+ * @return {@code true} if the system is in the process of bringing up a
* service that your client has permission to bind to; {@code false}
* if the system couldn't find the service or if your client doesn't
- * have permission to bind to it. If this value is {@code true}, you
- * should later call {@link #unbindService} to release the
- * connection.
+ * have permission to bind to it. You should call {@link #unbindService}
+ * to release the connection even if this method returned {@code false}.
*
- * @throws SecurityException If the caller does not have permission to access the service
- * or the service can not be found.
+ * @throws SecurityException If the caller does not have permission to
+ * access the service or the service cannot be found. Call
+ * {@link #unbindService} to release the connection when this exception
+ * is thrown.
*
* @see #unbindService
* @see #startService
- * @see #BIND_AUTO_CREATE
- * @see #BIND_DEBUG_UNBIND
- * @see #BIND_NOT_FOREGROUND
- * @see #BIND_ABOVE_CLIENT
- * @see #BIND_ALLOW_OOM_MANAGEMENT
- * @see #BIND_WAIVE_PRIORITY
- * @see #BIND_IMPORTANT
- * @see #BIND_ADJUST_WITH_ACTIVITY
- * @see #BIND_NOT_PERCEPTIBLE
- * @see #BIND_INCLUDE_CAPABILITIES
*/
public abstract boolean bindService(@RequiresPermission Intent service,
@NonNull ServiceConnection conn, @BindServiceFlags int flags);
diff --git a/core/java/android/content/ServiceConnection.java b/core/java/android/content/ServiceConnection.java
index 21398f6..660a7f0 100644
--- a/core/java/android/content/ServiceConnection.java
+++ b/core/java/android/content/ServiceConnection.java
@@ -63,8 +63,12 @@
* happen, for example, if the application hosting the service it is bound to
* has been updated.
*
- * @param name The concrete component name of the service whose
- * connection is dead.
+ * <p class="note"><b>Note:</b> The app that requested the binding must call
+ * {@link Context#unbindService(ServiceConnection)} to release the tracking
+ * resources associated with this ServiceConnection even if this callback was
+ * invoked following {@link Context#bindService Context.bindService() bindService()}.
+ *
+ * @param name The concrete component name of the service whose connection is dead.
*/
default void onBindingDied(ComponentName name) {
}
@@ -72,10 +76,10 @@
/**
* Called when the service being bound has returned {@code null} from its
* {@link android.app.Service#onBind(Intent) onBind()} method. This indicates
- * that the attempting service binding represented by this ServiceConnection
+ * that the attempted service binding represented by this ServiceConnection
* will never become usable.
*
- * <p class="note">The app which requested the binding must still call
+ * <p class="note"><b>Note:</b> The app that requested the binding must still call
* {@link Context#unbindService(ServiceConnection)} to release the tracking
* resources associated with this ServiceConnection even if this callback was
* invoked following {@link Context#bindService Context.bindService() bindService()}.
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index e3ff089..ee62170 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -638,7 +638,7 @@
/**
* Unregisters a listener for the sensors with which it is registered.
*
- * <p class="note"></p>
+ * <p class="note">
* Note: Don't use this method with a one shot trigger sensor such as
* {@link Sensor#TYPE_SIGNIFICANT_MOTION}.
* Use {@link #cancelTriggerSensor(TriggerEventListener, Sensor)} instead.
diff --git a/core/java/android/service/autofill/OWNERS b/core/java/android/service/autofill/OWNERS
index a088632..9a30e82 100644
--- a/core/java/android/service/autofill/OWNERS
+++ b/core/java/android/service/autofill/OWNERS
@@ -1,9 +1,3 @@
# Bug component: 351486
-joannechung@google.com
-adamhe@google.com
-tymtsai@google.com
-lpeter@google.com
-augale@google.com
-svetoslavganov@android.com
-svetoslavganov@google.com
+include /core/java/android/view/autofill/OWNERS
diff --git a/core/java/android/service/contentcapture/OWNERS b/core/java/android/service/contentcapture/OWNERS
index 6337327..24561c5 100644
--- a/core/java/android/service/contentcapture/OWNERS
+++ b/core/java/android/service/contentcapture/OWNERS
@@ -1,9 +1,3 @@
# Bug component: 544200
-joannechung@google.com
-adamhe@google.com
-tymtsai@google.com
-lpeter@google.com
-augale@google.com
-svetoslavganov@android.com
-svetoslavganov@google.com
+include /core/java/android/view/contentcapture/OWNERS
diff --git a/core/java/android/service/contentsuggestions/OWNERS b/core/java/android/service/contentsuggestions/OWNERS
index 46b5ea0..72fe0b1 100644
--- a/core/java/android/service/contentsuggestions/OWNERS
+++ b/core/java/android/service/contentsuggestions/OWNERS
@@ -1,7 +1,2 @@
-joannechung@google.com
-adamhe@google.com
-tymtsai@google.com
-lpeter@google.com
-augale@google.com
-svetoslavganov@android.com
-svetoslavganov@google.com
+
+include /core/java/android/app/contentsuggestions/OWNERS
diff --git a/core/java/android/service/resumeonreboot/OWNERS b/core/java/android/service/resumeonreboot/OWNERS
index 3a127d5..721fbaf 100644
--- a/core/java/android/service/resumeonreboot/OWNERS
+++ b/core/java/android/service/resumeonreboot/OWNERS
@@ -1,2 +1 @@
-xunchang@google.com
-zhaojiac@google.com
+ejyzhang@google.com
\ No newline at end of file
diff --git a/core/java/android/service/textclassifier/OWNERS b/core/java/android/service/textclassifier/OWNERS
index a535f52..c85c69e 100644
--- a/core/java/android/service/textclassifier/OWNERS
+++ b/core/java/android/service/textclassifier/OWNERS
@@ -1,9 +1,3 @@
# Bug component: 709498
-joannechung@google.com
-adamhe@google.com
-tymtsai@google.com
-lpeter@google.com
-augale@google.com
-svetoslavganov@android.com
-svetoslavganov@google.com
+include /core/java/android/view/textclassifier/OWNERS
diff --git a/core/java/android/service/translation/OWNERS b/core/java/android/service/translation/OWNERS
index a1e663a..440f9a8 100644
--- a/core/java/android/service/translation/OWNERS
+++ b/core/java/android/service/translation/OWNERS
@@ -1,8 +1,3 @@
# Bug component: 994311
-adamhe@google.com
-augale@google.com
-joannechung@google.com
-lpeter@google.com
-svetoslavganov@google.com
-tymtsai@google.com
+include /core/java/android/view/translation/OWNERS
diff --git a/core/java/android/service/voice/OWNERS b/core/java/android/service/voice/OWNERS
index 46b5ea0..59a0c2e 100644
--- a/core/java/android/service/voice/OWNERS
+++ b/core/java/android/service/voice/OWNERS
@@ -1,7 +1,3 @@
-joannechung@google.com
-adamhe@google.com
-tymtsai@google.com
-lpeter@google.com
-augale@google.com
-svetoslavganov@android.com
-svetoslavganov@google.com
+# Bug component: 533220
+
+include /core/java/android/app/assist/OWNERS
diff --git a/core/java/android/view/autofill/OWNERS b/core/java/android/view/autofill/OWNERS
index a088632..108c42c 100644
--- a/core/java/android/view/autofill/OWNERS
+++ b/core/java/android/view/autofill/OWNERS
@@ -1,9 +1,7 @@
# Bug component: 351486
-joannechung@google.com
-adamhe@google.com
-tymtsai@google.com
-lpeter@google.com
augale@google.com
-svetoslavganov@android.com
-svetoslavganov@google.com
+joannechung@google.com
+markpun@google.com
+lpeter@google.com
+tymtsai@google.com
diff --git a/core/java/android/view/contentcapture/OWNERS b/core/java/android/view/contentcapture/OWNERS
index 6337327..1a5cb1e4 100644
--- a/core/java/android/view/contentcapture/OWNERS
+++ b/core/java/android/view/contentcapture/OWNERS
@@ -1,9 +1,7 @@
# Bug component: 544200
-joannechung@google.com
-adamhe@google.com
-tymtsai@google.com
-lpeter@google.com
augale@google.com
-svetoslavganov@android.com
-svetoslavganov@google.com
+joannechung@google.com
+markpun@google.com
+lpeter@google.com
+tymtsai@google.com
diff --git a/core/java/android/view/inputmethod/OWNERS b/core/java/android/view/inputmethod/OWNERS
index d7db7c7..9fa7e8f 100644
--- a/core/java/android/view/inputmethod/OWNERS
+++ b/core/java/android/view/inputmethod/OWNERS
@@ -3,4 +3,4 @@
include /services/core/java/com/android/server/inputmethod/OWNERS
-per-file *InlineSuggestion* = file:/core/java/android/service/autofill/OWNERS
+per-file *InlineSuggestion* = file:/core/java/android/view/autofill/OWNERS
diff --git a/core/java/android/view/textclassifier/OWNERS b/core/java/android/view/textclassifier/OWNERS
index 4bcdeea..a205be2 100644
--- a/core/java/android/view/textclassifier/OWNERS
+++ b/core/java/android/view/textclassifier/OWNERS
@@ -2,8 +2,6 @@
mns@google.com
toki@google.com
-svetoslavganov@android.com
-svetoslavganov@google.com
augale@google.com
joannechung@google.com
tonymak@google.com
diff --git a/core/java/android/view/textclassifier/logging/OWNERS b/core/java/android/view/textclassifier/logging/OWNERS
deleted file mode 100644
index ac80d9f..0000000
--- a/core/java/android/view/textclassifier/logging/OWNERS
+++ /dev/null
@@ -1,8 +0,0 @@
-# Bug component: 709498
-
-mns@google.com
-toki@google.com
-svetoslavganov@android.com
-svetoslavganov@google.com
-augale@google.com
-joannechung@google.com
diff --git a/core/java/android/view/translation/OWNERS b/core/java/android/view/translation/OWNERS
index a1e663a..b772ad3 100644
--- a/core/java/android/view/translation/OWNERS
+++ b/core/java/android/view/translation/OWNERS
@@ -1,8 +1,7 @@
# Bug component: 994311
-adamhe@google.com
augale@google.com
joannechung@google.com
+markpun@google.com
lpeter@google.com
-svetoslavganov@google.com
tymtsai@google.com
diff --git a/core/java/android/widget/inline/OWNERS b/core/java/android/widget/inline/OWNERS
new file mode 100644
index 0000000..9a30e82
--- /dev/null
+++ b/core/java/android/widget/inline/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 351486
+
+include /core/java/android/view/autofill/OWNERS
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 2e17779..c037e7c 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -711,7 +711,7 @@
<protected-broadcast android:name="android.scheduling.action.REBOOT_READY" />
<protected-broadcast android:name="android.app.action.DEVICE_POLICY_CONSTANTS_CHANGED" />
<protected-broadcast android:name="android.app.action.SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED" />
- <protected-broadcast android:name="android.app.action.ACTION_SHOW_NEW_USER_DISCLAIMER" />
+ <protected-broadcast android:name="android.app.action.SHOW_NEW_USER_DISCLAIMER" />
<!-- ====================================================================== -->
<!-- RUNTIME PERMISSIONS -->
diff --git a/core/tests/coretests/src/android/widget/OWNERS b/core/tests/coretests/src/android/widget/OWNERS
new file mode 100644
index 0000000..5a9aed3
--- /dev/null
+++ b/core/tests/coretests/src/android/widget/OWNERS
@@ -0,0 +1,5 @@
+include /core/java/android/widget/OWNERS
+
+per-file *SuggestionsPopup* = file:/core/java/android/text/OWNERS
+
+per-file *FloatingToolbar*, *SelectionToolbar* = file:/core/java/android/view/textclassifier/OWNERS
\ No newline at end of file
diff --git a/data/etc/Android.bp b/data/etc/Android.bp
index be1e2b2..dc07758 100644
--- a/data/etc/Android.bp
+++ b/data/etc/Android.bp
@@ -1,4 +1,4 @@
-// Copyright (C} 2018 The Android Open Source Project
+// Copyright (C) 2018 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License"};
// you may not use this file except in compliance with the License.
@@ -12,7 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-
// Sysconfig files
package {
@@ -134,13 +133,6 @@
}
prebuilt_etc {
- name: "privapp_whitelist_com.android.networkstack.tethering",
- sub_dir: "permissions",
- src: "com.android.networkstack.tethering.xml",
- filename_from_src: true,
-}
-
-prebuilt_etc {
name: "privapp_whitelist_com.android.provision",
system_ext_specific: true,
sub_dir: "permissions",
diff --git a/data/etc/com.android.networkstack.tethering.xml b/data/etc/com.android.networkstack.tethering.xml
deleted file mode 100644
index f26a961..0000000
--- a/data/etc/com.android.networkstack.tethering.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2021 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
--->
-
-<permissions>
- <privapp-permissions package="com.android.networkstack.tethering">
- <permission name="android.permission.BLUETOOTH_PRIVILEGED" />
- <permission name="android.permission.MANAGE_USB"/>
- <permission name="android.permission.MODIFY_PHONE_STATE"/>
- <permission name="android.permission.READ_NETWORK_USAGE_HISTORY"/>
- <permission name="android.permission.TETHER_PRIVILEGED"/>
- <permission name="android.permission.UPDATE_APP_OPS_STATS"/>
- <permission name="android.permission.UPDATE_DEVICE_STATS"/>
- </privapp-permissions>
-</permissions>
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 0d01253..191d400 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -464,6 +464,9 @@
<permission name="android.permission.WIFI_UPDATE_COEX_UNSAFE_CHANNELS" />
<permission name="android.permission.NEARBY_WIFI_DEVICES" />
<permission name="android.permission.OVERRIDE_WIFI_CONFIG" />
+ <!-- Permission needed for CTS test - ConcurrencyTest#testP2pExternalApprover
+ P2P external approver API sets require MANAGE_WIFI_AUTO_JOIN permission. -->
+ <permission name="android.permission.MANAGE_WIFI_AUTO_JOIN" />
<!-- Permission required for CTS test CarrierMessagingServiceWrapperTest -->
<permission name="android.permission.BIND_CARRIER_SERVICES"/>
<!-- Permission required for CTS test - MusicRecognitionManagerTest -->
diff --git a/libs/androidfw/tests/BackupHelpers_test.cpp b/libs/androidfw/tests/BackupHelpers_test.cpp
index 86b7fb3..c2fcb69 100644
--- a/libs/androidfw/tests/BackupHelpers_test.cpp
+++ b/libs/androidfw/tests/BackupHelpers_test.cpp
@@ -50,7 +50,7 @@
TEST_F(BackupHelpersTest, WriteTarFileWithSizeGreaterThan2GB) {
TemporaryFile tf;
// Allocate a 2 GB file.
- off64_t fileSize = 2ll * 1024ll * 1024ll * 1024ll + 512ll;
+ off64_t fileSize = 2LL * 1024LL * 1024LL * 1024LL + 512LL;
ASSERT_EQ(0, posix_fallocate64(tf.fd, 0, fileSize));
off64_t tarSize = 0;
int err = write_tarfile(/* packageName */ String8("test-pkg"), /* domain */ String8(""), /* rootpath */ String8(""), /* filePath */ String8(tf.path), /* outSize */ &tarSize, /* writer */ NULL);
diff --git a/packages/ConnectivityT/framework-t/src/android/net/EthernetManager.java b/packages/ConnectivityT/framework-t/src/android/net/EthernetManager.java
index 1a955c4..72243f9 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/EthernetManager.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/EthernetManager.java
@@ -146,7 +146,7 @@
* @param iface the name of the interface.
* @param state the current state of the interface, or {@link #STATE_ABSENT} if the
* interface was removed.
- * @param role whether the interface is in the client mode or server mode.
+ * @param role whether the interface is in client mode or server mode.
* @param configuration the current IP configuration of the interface.
* @hide
*/
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java
index 9f3371b..eeb56d0 100644
--- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java
+++ b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java
@@ -51,6 +51,7 @@
import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_UID_TAG;
import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_XT;
import static android.os.Trace.TRACE_TAG_NETWORK;
+import static android.system.OsConstants.ENOENT;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
import static android.text.format.DateUtils.DAY_IN_MILLIS;
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
@@ -120,7 +121,6 @@
import android.service.NetworkInterfaceProto;
import android.service.NetworkStatsServiceDumpProto;
import android.system.ErrnoException;
-import android.system.Os;
import android.telephony.PhoneStateListener;
import android.telephony.SubscriptionPlan;
import android.text.TextUtils;
@@ -214,6 +214,14 @@
// This is current path but may be changed soon.
private static final String UID_COUNTERSET_MAP_PATH =
"/sys/fs/bpf/map_netd_uid_counterset_map";
+ private static final String COOKIE_TAG_MAP_PATH =
+ "/sys/fs/bpf/map_netd_cookie_tag_map";
+ private static final String APP_UID_STATS_MAP_PATH =
+ "/sys/fs/bpf/map_netd_app_uid_stats_map";
+ private static final String STATS_MAP_A_PATH =
+ "/sys/fs/bpf/map_netd_stats_map_A";
+ private static final String STATS_MAP_B_PATH =
+ "/sys/fs/bpf/map_netd_stats_map_B";
private final Context mContext;
private final NetworkStatsFactory mStatsFactory;
@@ -341,6 +349,10 @@
*/
private SparseIntArray mActiveUidCounterSet = new SparseIntArray();
private final IBpfMap<U32, U8> mUidCounterSetMap;
+ private final IBpfMap<CookieTagMapKey, CookieTagMapValue> mCookieTagMap;
+ private final IBpfMap<StatsMapKey, StatsMapValue> mStatsMapA;
+ private final IBpfMap<StatsMapKey, StatsMapValue> mStatsMapB;
+ private final IBpfMap<UidStatsMapKey, StatsMapValue> mAppUidStatsMap;
/** Data layer operation counters for splicing into other structures. */
private NetworkStats mUidOperations = new NetworkStats(0L, 10);
@@ -474,6 +486,10 @@
mInterfaceMapUpdater = mDeps.makeBpfInterfaceMapUpdater(mContext, mHandler);
mInterfaceMapUpdater.start();
mUidCounterSetMap = mDeps.getUidCounterSetMap();
+ mCookieTagMap = mDeps.getCookieTagMap();
+ mStatsMapA = mDeps.getStatsMapA();
+ mStatsMapB = mDeps.getStatsMapB();
+ mAppUidStatsMap = mDeps.getAppUidStatsMap();
}
/**
@@ -547,8 +563,48 @@
}
}
- public TagStatsDeleter getTagStatsDeleter() {
- return NetworkStatsService::nativeDeleteTagData;
+ /** Gets the cookie tag map */
+ public IBpfMap<CookieTagMapKey, CookieTagMapValue> getCookieTagMap() {
+ try {
+ return new BpfMap<CookieTagMapKey, CookieTagMapValue>(COOKIE_TAG_MAP_PATH,
+ BpfMap.BPF_F_RDWR, CookieTagMapKey.class, CookieTagMapValue.class);
+ } catch (ErrnoException e) {
+ Log.wtf(TAG, "Cannot create cookie tag map: " + e);
+ return null;
+ }
+ }
+
+ /** Gets stats map A */
+ public IBpfMap<StatsMapKey, StatsMapValue> getStatsMapA() {
+ try {
+ return new BpfMap<StatsMapKey, StatsMapValue>(STATS_MAP_A_PATH,
+ BpfMap.BPF_F_RDWR, StatsMapKey.class, StatsMapValue.class);
+ } catch (ErrnoException e) {
+ Log.wtf(TAG, "Cannot create stats map A: " + e);
+ return null;
+ }
+ }
+
+ /** Gets stats map B */
+ public IBpfMap<StatsMapKey, StatsMapValue> getStatsMapB() {
+ try {
+ return new BpfMap<StatsMapKey, StatsMapValue>(STATS_MAP_B_PATH,
+ BpfMap.BPF_F_RDWR, StatsMapKey.class, StatsMapValue.class);
+ } catch (ErrnoException e) {
+ Log.wtf(TAG, "Cannot create stats map B: " + e);
+ return null;
+ }
+ }
+
+ /** Gets the uid stats map */
+ public IBpfMap<UidStatsMapKey, StatsMapValue> getAppUidStatsMap() {
+ try {
+ return new BpfMap<UidStatsMapKey, StatsMapValue>(APP_UID_STATS_MAP_PATH,
+ BpfMap.BPF_F_RDWR, UidStatsMapKey.class, StatsMapValue.class);
+ } catch (ErrnoException e) {
+ Log.wtf(TAG, "Cannot create app uid stats map: " + e);
+ return null;
+ }
}
}
@@ -1790,6 +1846,63 @@
currentTime);
}
+ // deleteKernelTagData can ignore ENOENT; otherwise we should log an error
+ private void logErrorIfNotErrNoent(final ErrnoException e, final String msg) {
+ if (e.errno != ENOENT) Log.e(TAG, msg, e);
+ }
+
+ private <K extends StatsMapKey, V extends StatsMapValue> void deleteStatsMapTagData(
+ IBpfMap<K, V> statsMap, int uid) {
+ try {
+ statsMap.forEach((key, value) -> {
+ if (key.uid == uid) {
+ try {
+ statsMap.deleteEntry(key);
+ } catch (ErrnoException e) {
+ logErrorIfNotErrNoent(e, "Failed to delete data(uid = " + key.uid + ")");
+ }
+ }
+ });
+ } catch (ErrnoException e) {
+ Log.e(TAG, "FAILED to delete tag data from stats map", e);
+ }
+ }
+
+ /**
+ * Deletes uid tag data from CookieTagMap, StatsMapA, StatsMapB, and UidStatsMap
+ * @param uid
+ */
+ private void deleteKernelTagData(int uid) {
+ try {
+ mCookieTagMap.forEach((key, value) -> {
+ if (value.uid == uid) {
+ try {
+ mCookieTagMap.deleteEntry(key);
+ } catch (ErrnoException e) {
+ logErrorIfNotErrNoent(e, "Failed to delete data(cookie = " + key + ")");
+ }
+ }
+ });
+ } catch (ErrnoException e) {
+ Log.e(TAG, "Failed to delete tag data from cookie tag map", e);
+ }
+
+ deleteStatsMapTagData(mStatsMapA, uid);
+ deleteStatsMapTagData(mStatsMapB, uid);
+
+ try {
+ mUidCounterSetMap.deleteEntry(new U32(uid));
+ } catch (ErrnoException e) {
+ logErrorIfNotErrNoent(e, "Failed to delete tag data from uid counter set map");
+ }
+
+ try {
+ mAppUidStatsMap.deleteEntry(new UidStatsMapKey(uid));
+ } catch (ErrnoException e) {
+ logErrorIfNotErrNoent(e, "Failed to delete tag data from app uid stats map");
+ }
+ }
+
/**
* Clean up {@link #mUidRecorder} after UID is removed.
*/
@@ -1805,10 +1918,7 @@
// Clear kernel stats associated with UID
for (int uid : uids) {
- final int ret = mDeps.getTagStatsDeleter().deleteTagData(uid);
- if (ret < 0) {
- Log.w(TAG, "problem clearing counters for uid " + uid + ": " + Os.strerror(-ret));
- }
+ deleteKernelTagData(uid);
}
}
@@ -2387,12 +2497,4 @@
private static native long nativeGetTotalStat(int type);
private static native long nativeGetIfaceStat(String iface, int type);
private static native long nativeGetUidStat(int uid, int type);
-
- // TODO: use BpfNetMaps to delete tag data and remove this.
- @VisibleForTesting
- interface TagStatsDeleter {
- int deleteTagData(int uid);
- }
-
- private static native int nativeDeleteTagData(int uid);
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
index 86604a2..610e3d5 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
@@ -165,6 +165,31 @@
return sessionInfos.get(sessionInfos.size() - 1);
}
+ boolean isRoutingSessionAvailableForVolumeControl() {
+ if (mVolumeAdjustmentForRemoteGroupSessions) {
+ return true;
+ }
+ List<RoutingSessionInfo> sessions =
+ mRouterManager.getRoutingSessions(mPackageName);
+ boolean foundNonSystemSession = false;
+ boolean isGroup = false;
+ for (RoutingSessionInfo session : sessions) {
+ if (!session.isSystemSession()) {
+ foundNonSystemSession = true;
+ int selectedRouteCount = session.getSelectedRoutes().size();
+ if (selectedRouteCount > 1) {
+ isGroup = true;
+ break;
+ }
+ }
+ }
+ if (!foundNonSystemSession) {
+ Log.d(TAG, "No routing session for " + mPackageName);
+ return false;
+ }
+ return !isGroup;
+ }
+
/**
* Remove a {@code device} from current media.
*
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
index b5facf3..c8db654 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
@@ -197,6 +197,14 @@
}
/**
+ * Returns if the media session is available for volume control.
+ * @return True if this media session is available for colume control, false otherwise.
+ */
+ public boolean isMediaSessionAvailableForVolumeControl() {
+ return mInfoMediaManager.isRoutingSessionAvailableForVolumeControl();
+ }
+
+ /**
* Start scan connected MediaDevice
*/
public void startScan() {
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java
index d7b366e..bb6b293 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java
@@ -206,9 +206,8 @@
when(config.isMandatoryCodec()).thenReturn(false);
when(config.getCodecType()).thenReturn(4);
- when(config.getCodecName()).thenReturn("LDAC");
assertThat(mProfile.getHighQualityAudioOptionLabel(mDevice)).isEqualTo(
- String.format(KNOWN_CODEC_LABEL, config.getCodecName()));
+ String.format(KNOWN_CODEC_LABEL, "LDAC"));
}
@Test
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 d53a3e8..298ee90 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
@@ -28,6 +28,7 @@
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothUuid;
import android.content.Context;
+import android.os.Parcel;
import android.os.ParcelUuid;
import org.junit.Before;
@@ -60,9 +61,9 @@
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);
+ createBtClass(BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES);
private final BluetoothClass DEVICE_CLASS_2 =
- new BluetoothClass(BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE);
+ createBtClass(BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE);
@Mock
private LocalBluetoothProfileManager mLocalProfileManager;
@Mock
@@ -92,6 +93,16 @@
private HearingAidDeviceManager mHearingAidDeviceManager;
private Context mContext;
+ private BluetoothClass createBtClass(int deviceClass) {
+ Parcel p = Parcel.obtain();
+ p.writeInt(deviceClass);
+ p.setDataPosition(0); // reset position of parcel before passing to constructor
+
+ BluetoothClass bluetoothClass = BluetoothClass.CREATOR.createFromParcel(p);
+ p.recycle();
+ return bluetoothClass;
+ }
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java
index 7be176a..a8e6075 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java
@@ -28,6 +28,7 @@
import android.bluetooth.BluetoothHearingAid;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
+import android.os.Parcel;
import org.junit.Before;
import org.junit.Test;
@@ -48,7 +49,7 @@
private final static String DEVICE_ADDRESS_1 = "AA:BB:CC:DD:EE:11";
private final static String DEVICE_ADDRESS_2 = "AA:BB:CC:DD:EE:22";
private final BluetoothClass DEVICE_CLASS =
- new BluetoothClass(BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE);
+ createBtClass(BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE);
@Mock
private LocalBluetoothProfileManager mLocalProfileManager;
@Mock
@@ -67,6 +68,16 @@
private HearingAidDeviceManager mHearingAidDeviceManager;
private Context mContext;
+ private BluetoothClass createBtClass(int deviceClass) {
+ Parcel p = Parcel.obtain();
+ p.writeInt(deviceClass);
+ p.setDataPosition(0); // reset position of parcel before passing to constructor
+
+ BluetoothClass bluetoothClass = BluetoothClass.CREATOR.createFromParcel(p);
+ p.recycle();
+ return bluetoothClass;
+ }
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java
index 6f7f73a..c122a37 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java
@@ -31,6 +31,7 @@
import android.content.Context;
import android.media.MediaRoute2Info;
import android.media.MediaRouter2Manager;
+import android.os.Parcel;
import com.android.settingslib.bluetooth.A2dpProfile;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
@@ -65,9 +66,9 @@
private static final String ROUTER_ID_3 = "RouterId_3";
private static final String TEST_PACKAGE_NAME = "com.test.playmusic";
private final BluetoothClass mHeadreeClass =
- new BluetoothClass(BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES);
+ createBtClass(BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES);
private final BluetoothClass mCarkitClass =
- new BluetoothClass(BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO);
+ createBtClass(BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO);
@Mock
private BluetoothDevice mDevice1;
@@ -118,6 +119,16 @@
private List<MediaDevice> mMediaDevices = new ArrayList<>();
private PhoneMediaDevice mPhoneMediaDevice;
+ private BluetoothClass createBtClass(int deviceClass) {
+ Parcel p = Parcel.obtain();
+ p.writeInt(deviceClass);
+ p.setDataPosition(0); // reset position of parcel before passing to constructor
+
+ BluetoothClass bluetoothClass = BluetoothClass.CREATOR.createFromParcel(p);
+ p.recycle();
+ return bluetoothClass;
+ }
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
diff --git a/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowBluetoothAdapter.java b/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowBluetoothAdapter.java
index 3b7fbc7..c7e96bc 100644
--- a/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowBluetoothAdapter.java
+++ b/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowBluetoothAdapter.java
@@ -69,7 +69,7 @@
}
@Implementation
- protected boolean removeActiveDevice(@BluetoothAdapter.ActiveDeviceUse int profiles) {
+ protected boolean removeActiveDevice(int profiles) {
if (profiles != ACTIVE_DEVICE_AUDIO && profiles != ACTIVE_DEVICE_PHONE_CALL
&& profiles != ACTIVE_DEVICE_ALL) {
return false;
@@ -78,8 +78,7 @@
}
@Implementation
- protected boolean setActiveDevice(BluetoothDevice device,
- @BluetoothAdapter.ActiveDeviceUse int profiles) {
+ protected boolean setActiveDevice(BluetoothDevice device, int profiles) {
if (device == null) {
return false;
}
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 074d85c..8b27522 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -509,6 +509,9 @@
<uses-permission android:name="android.permission.WIFI_UPDATE_COEX_UNSAFE_CHANNELS" />
<uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" />
<uses-permission android:name="android.permission.OVERRIDE_WIFI_CONFIG" />
+ <!-- Permission needed for CTS test - ConcurrencyTest#testP2pExternalApprover
+ P2P external approver API sets require MANAGE_WIFI_AUTO_JOIN permission. -->
+ <uses-permission android:name="android.permission.MANAGE_WIFI_AUTO_JOIN" />
<!-- Permission required for CTS tests to enable/disable rate limiting toasts. -->
<uses-permission android:name="android.permission.MANAGE_TOAST_RATE_LIMITING" />
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
index befb648..789ad62 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
@@ -118,9 +118,11 @@
switch (this) {
case UNINITIALIZED:
case INITIALIZED:
- case DOZE_REQUEST_PULSE:
return parameters.shouldControlScreenOff() ? Display.STATE_ON
: Display.STATE_OFF;
+ case DOZE_REQUEST_PULSE:
+ return parameters.getDisplayNeedsBlanking() ? Display.STATE_OFF
+ : Display.STATE_ON;
case DOZE_AOD_PAUSED:
case DOZE:
return Display.STATE_OFF;
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java
index 3631938..52db1bd 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java
@@ -105,17 +105,7 @@
updateUdfpsController();
if (mUdfpsController == null) {
- mAuthController.addCallback(new AuthController.Callback() {
- @Override
- public void onAllAuthenticatorsRegistered() {
- updateUdfpsController();
- }
-
- @Override
- public void onEnrollmentsChanged() {
- updateUdfpsController();
- }
- });
+ mAuthController.addCallback(mAuthControllerCallback);
}
}
@@ -128,6 +118,11 @@
}
@Override
+ public void destroy() {
+ mAuthController.removeCallback(mAuthControllerCallback);
+ }
+
+ @Override
public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
int screenState = newState.screenState(mParameters);
mDozeHost.cancelGentleSleep();
@@ -222,4 +217,16 @@
mWakeLock.setAcquired(false);
}
}
+
+ private final AuthController.Callback mAuthControllerCallback = new AuthController.Callback() {
+ @Override
+ public void onAllAuthenticatorsRegistered() {
+ updateUdfpsController();
+ }
+
+ @Override
+ public void onEnrollmentsChanged() {
+ updateUdfpsController();
+ }
+ };
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
index c8cd432..a7640ff 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
@@ -28,6 +28,7 @@
import android.view.ViewGroup
import android.view.ViewGroupOverlay
import androidx.annotation.VisibleForTesting
+import com.android.keyguard.KeyguardViewController
import com.android.systemui.R
import com.android.systemui.animation.Interpolators
import com.android.systemui.dagger.SysUISingleton
@@ -39,7 +40,6 @@
import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.notification.stack.StackStateAnimator
import com.android.systemui.statusbar.phone.KeyguardBypassController
-import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.Utils
@@ -82,7 +82,7 @@
private val notifLockscreenUserManager: NotificationLockscreenUserManager,
configurationController: ConfigurationController,
wakefulnessLifecycle: WakefulnessLifecycle,
- private val statusBarKeyguardViewManager: StatusBarKeyguardViewManager
+ private val keyguardViewController: KeyguardViewController
) {
/**
@@ -998,7 +998,7 @@
private fun isLockScreenVisibleToUser(): Boolean {
return !statusBarStateController.isDozing &&
- !statusBarKeyguardViewManager.isBouncerShowing &&
+ !keyguardViewController.isBouncerShowing &&
statusBarStateController.state == StatusBarState.KEYGUARD &&
notifLockscreenUserManager.shouldShowLockscreenNotifications() &&
statusBarStateController.isExpanded &&
@@ -1007,7 +1007,7 @@
private fun isLockScreenShadeVisibleToUser(): Boolean {
return !statusBarStateController.isDozing &&
- !statusBarKeyguardViewManager.isBouncerShowing &&
+ !keyguardViewController.isBouncerShowing &&
(statusBarStateController.state == StatusBarState.SHADE_LOCKED ||
(statusBarStateController.state == StatusBarState.KEYGUARD && qsExpanded))
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
index a82e989..e01916f 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
@@ -111,7 +111,8 @@
}
mBottomDivider.setVisibility(View.GONE);
mCheckBox.setVisibility(View.GONE);
- if (currentlyConnected && mController.isActiveRemoteDevice(device)) {
+ if (currentlyConnected && mController.isActiveRemoteDevice(device)
+ && mController.getSelectableMediaDevice().size() > 0) {
// Init active device layout
mAddIcon.setVisibility(View.VISIBLE);
mAddIcon.setTransitionAlpha(1);
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
index 9eaedd7..0d368fa 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
@@ -84,7 +84,6 @@
private final SystemUIDialogManager mDialogManager;
private final List<MediaDevice> mGroupMediaDevices = new CopyOnWriteArrayList<>();
private final boolean mAboveStatusbar;
- private final boolean mVolumeAdjustmentForRemoteGroupSessions;
private final NotificationEntryManager mNotificationEntryManager;
@VisibleForTesting
final List<MediaDevice> mMediaDevices = new CopyOnWriteArrayList<>();
@@ -117,8 +116,6 @@
mMetricLogger = new MediaOutputMetricLogger(mContext, mPackageName);
mUiEventLogger = uiEventLogger;
mDialogLaunchAnimator = dialogLaunchAnimator;
- mVolumeAdjustmentForRemoteGroupSessions = mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_volumeAdjustmentForRemoteGroupSessions);
mDialogManager = dialogManager;
}
@@ -496,10 +493,15 @@
|| features.contains(MediaRoute2Info.FEATURE_REMOTE_GROUP_PLAYBACK));
}
+ private boolean isPlayBackInfoLocal() {
+ return mMediaController.getPlaybackInfo() != null
+ && mMediaController.getPlaybackInfo().getPlaybackType()
+ == MediaController.PlaybackInfo.PLAYBACK_TYPE_LOCAL;
+ }
+
boolean isVolumeControlEnabled(@NonNull MediaDevice device) {
- // TODO(b/202500642): Also enable volume control for remote non-group sessions.
- return !isActiveRemoteDevice(device)
- || mVolumeAdjustmentForRemoteGroupSessions;
+ return isPlayBackInfoLocal()
+ || mLocalMediaManager.isMediaSessionAvailableForVolumeControl();
}
private final MediaController.Callback mCb = new MediaController.Callback() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index 38cefe6..f1e5b56 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -429,7 +429,6 @@
public void setBrightnessMirrorController(
BrightnessMirrorController brightnessMirrorController) {
mQSPanelController.setBrightnessMirror(brightnessMirrorController);
- mQuickQSPanelController.setBrightnessMirror(brightnessMirrorController);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSBrightnessController.kt b/packages/SystemUI/src/com/android/systemui/qs/QuickQSBrightnessController.kt
deleted file mode 100644
index 65889d7..0000000
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSBrightnessController.kt
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.qs
-
-import androidx.annotation.VisibleForTesting
-import com.android.systemui.settings.brightness.BrightnessController
-import com.android.systemui.settings.brightness.BrightnessSliderController
-import com.android.systemui.settings.brightness.MirroredBrightnessController
-import com.android.systemui.statusbar.policy.BrightnessMirrorController
-import javax.inject.Inject
-
-/**
- * Controls brightness slider in QQS, which is visible only in split shade. It's responsible for
- * showing/hiding it when appropriate and (un)registering listeners
- */
-class QuickQSBrightnessController @VisibleForTesting constructor(
- private val brightnessControllerFactory: () -> BrightnessController
-) : MirroredBrightnessController {
-
- @Inject constructor(
- brightnessControllerFactory: BrightnessController.Factory,
- brightnessSliderControllerFactory: BrightnessSliderController.Factory,
- quickQSPanel: QuickQSPanel
- ) : this(brightnessControllerFactory = {
- val slider = brightnessSliderControllerFactory.create(quickQSPanel.context,
- quickQSPanel)
- slider.init()
- quickQSPanel.setBrightnessView(slider.rootView)
- brightnessControllerFactory.create(slider)
- })
-
- private var isListening = false
- private var brightnessController: BrightnessController? = null
- private var mirrorController: BrightnessMirrorController? = null
-
- fun init(shouldUseSplitNotificationShade: Boolean) {
- refreshVisibility(shouldUseSplitNotificationShade)
- }
-
- /**
- * Starts/Stops listening for brightness changing events.
- * It's fine to call this function even if slider is not visible (which would be the case for
- * all small screen devices), it will just do nothing in that case
- */
- fun setListening(listening: Boolean) {
- if (listening) {
- // controller can be null when slider was never shown
- if (!isListening && brightnessController != null) {
- brightnessController?.registerCallbacks()
- isListening = true
- }
- } else {
- brightnessController?.unregisterCallbacks()
- isListening = false
- }
- }
-
- fun checkRestrictionAndSetEnabled() {
- brightnessController?.checkRestrictionAndSetEnabled()
- }
-
- fun refreshVisibility(shouldUseSplitNotificationShade: Boolean) {
- if (shouldUseSplitNotificationShade) {
- showBrightnessSlider()
- } else {
- hideBrightnessSlider()
- }
- }
-
- override fun setMirror(controller: BrightnessMirrorController) {
- mirrorController = controller
- mirrorController?.let { brightnessController?.setMirror(it) }
- }
-
- private fun hideBrightnessSlider() {
- brightnessController?.hideSlider()
- }
-
- private fun showBrightnessSlider() {
- if (brightnessController == null) {
- brightnessController = brightnessControllerFactory()
- mirrorController?.also { brightnessController?.setMirror(it) }
- brightnessController?.registerCallbacks()
- isListening = true
- }
- brightnessController?.showSlider()
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java
index 92690c7d..fdd764c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java
@@ -30,8 +30,6 @@
import com.android.systemui.qs.customize.QSCustomizerController;
import com.android.systemui.qs.dagger.QSScope;
import com.android.systemui.qs.logging.QSLogger;
-import com.android.systemui.settings.brightness.BrightnessMirrorHandler;
-import com.android.systemui.statusbar.policy.BrightnessMirrorController;
import java.util.ArrayList;
import java.util.List;
@@ -51,9 +49,6 @@
}
};
- // brightness is visible only in split shade
- private final QuickQSBrightnessController mBrightnessController;
- private final BrightnessMirrorHandler mBrightnessMirrorHandler;
private final FooterActionsController mFooterActionsController;
@Inject
@@ -63,13 +58,10 @@
@Named(QUICK_QS_PANEL) MediaHost mediaHost,
MetricsLogger metricsLogger, UiEventLogger uiEventLogger, QSLogger qsLogger,
DumpManager dumpManager,
- QuickQSBrightnessController quickQSBrightnessController,
@Named(QQS_FOOTER) FooterActionsController footerActionsController
) {
super(view, qsTileHost, qsCustomizerController, usingMediaPlayer, mediaHost, metricsLogger,
uiEventLogger, qsLogger, dumpManager);
- mBrightnessController = quickQSBrightnessController;
- mBrightnessMirrorHandler = new BrightnessMirrorHandler(mBrightnessController);
mFooterActionsController = footerActionsController;
}
@@ -79,7 +71,6 @@
mMediaHost.setExpansion(0.0f);
mMediaHost.setShowsOnlyActiveMedia(true);
mMediaHost.init(MediaHierarchyManager.LOCATION_QQS);
- mBrightnessController.init(mShouldUseSplitNotificationShade);
mFooterActionsController.init();
mFooterActionsController.refreshVisibility(mShouldUseSplitNotificationShade);
}
@@ -88,20 +79,17 @@
protected void onViewAttached() {
super.onViewAttached();
mView.addOnConfigurationChangedListener(mOnConfigurationChangedListener);
- mBrightnessMirrorHandler.onQsPanelAttached();
}
@Override
protected void onViewDetached() {
super.onViewDetached();
mView.removeOnConfigurationChangedListener(mOnConfigurationChangedListener);
- mBrightnessMirrorHandler.onQsPanelDettached();
}
@Override
void setListening(boolean listening) {
super.setListening(listening);
- mBrightnessController.setListening(listening);
mFooterActionsController.setListening(listening);
}
@@ -115,14 +103,7 @@
}
@Override
- public void refreshAllTiles() {
- mBrightnessController.checkRestrictionAndSetEnabled();
- super.refreshAllTiles();
- }
-
- @Override
protected void onConfigurationChanged() {
- mBrightnessController.refreshVisibility(mShouldUseSplitNotificationShade);
mFooterActionsController.refreshVisibility(mShouldUseSplitNotificationShade);
}
@@ -146,8 +127,4 @@
public int getNumQuickTiles() {
return mView.getNumQuickTiles();
}
-
- public void setBrightnessMirror(BrightnessMirrorController brightnessMirrorController) {
- mBrightnessMirrorHandler.setController(brightnessMirrorController);
- }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
index 8078b6c..5684429 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
@@ -42,12 +42,14 @@
import android.hardware.display.AmbientDisplayConfiguration;
import android.testing.AndroidTestingRunner;
import android.testing.UiThreadTest;
+import android.view.Display;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dock.DockManager;
import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.util.wakelock.WakeLockFake;
@@ -444,4 +446,20 @@
assertTrue(mServiceFake.requestedWakeup);
}
+
+ @Test
+ public void testDozePulsing_displayRequiresBlanking_screenState() {
+ DozeParameters dozeParameters = mock(DozeParameters.class);
+ when(dozeParameters.getDisplayNeedsBlanking()).thenReturn(true);
+
+ assertEquals(Display.STATE_OFF, DOZE_REQUEST_PULSE.screenState(dozeParameters));
+ }
+
+ @Test
+ public void testDozePulsing_displayDoesNotRequireBlanking_screenState() {
+ DozeParameters dozeParameters = mock(DozeParameters.class);
+ when(dozeParameters.getDisplayNeedsBlanking()).thenReturn(false);
+
+ assertEquals(Display.STATE_ON, DOZE_REQUEST_PULSE.screenState(dozeParameters));
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStateTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStateTest.java
index 3e19cc4..992a82b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStateTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStateTest.java
@@ -35,6 +35,7 @@
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Matchers.anyObject;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.verify;
@@ -306,4 +307,11 @@
// THEN the display screen state will change
assertEquals(Display.STATE_DOZE_SUSPEND, mServiceFake.screenState);
}
+
+ @Test
+ public void authCallbackRemovedOnDestroy() {
+ mScreen.destroy();
+
+ verify(mAuthController).removeCallback(anyObject());
+ }
}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt
index a3ffb2f..7565fe1c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt
@@ -22,6 +22,7 @@
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.test.filters.SmallTest
+import com.android.keyguard.KeyguardViewController
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.controls.controller.ControlsControllerImplTest.Companion.eq
@@ -31,7 +32,6 @@
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.phone.KeyguardBypassController
-import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.animation.UniqueObjectHostView
@@ -80,7 +80,7 @@
@Mock
private lateinit var wakefulnessLifecycle: WakefulnessLifecycle
@Mock
- private lateinit var statusBarKeyguardViewManager: StatusBarKeyguardViewManager
+ private lateinit var keyguardViewController: KeyguardViewController
@Mock
private lateinit var configurationController: ConfigurationController
@Mock
@@ -110,7 +110,7 @@
notificationLockscreenUserManager,
configurationController,
wakefulnessLifecycle,
- statusBarKeyguardViewManager)
+ keyguardViewController)
verify(wakefulnessLifecycle).addObserver(wakefullnessObserver.capture())
verify(statusBarStateController).addCallback(statusBarCallback.capture())
setupHost(lockHost, MediaHierarchyManager.LOCATION_LOCKSCREEN)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSBrightnessControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSBrightnessControllerTest.kt
deleted file mode 100644
index de1d86b..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSBrightnessControllerTest.kt
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.qs
-
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.settings.brightness.BrightnessController
-import com.android.systemui.statusbar.policy.BrightnessMirrorController
-import org.junit.Before
-import org.junit.Rule
-import org.junit.Test
-import org.mockito.Mock
-import org.mockito.Mockito.times
-import org.mockito.Mockito.verify
-import org.mockito.Mockito.never
-import org.mockito.Mockito.mock
-import org.mockito.junit.MockitoJUnit
-
-@SmallTest
-class QuickQSBrightnessControllerTest : SysuiTestCase() {
-
- @Mock
- lateinit var brightnessController: BrightnessController
- @get:Rule
- val mockito = MockitoJUnit.rule()
-
- lateinit var quickQSBrightnessController: QuickQSBrightnessController
-
- @Before
- fun setUp() {
- quickQSBrightnessController = QuickQSBrightnessController(
- brightnessControllerFactory = { brightnessController })
- }
-
- @Test
- fun testSliderIsShownWhenInitializedInSplitShade() {
- quickQSBrightnessController.init(shouldUseSplitNotificationShade = true)
-
- verify(brightnessController).showSlider()
- }
-
- @Test
- fun testSliderIsShownWhenRefreshedInSplitShade() {
- quickQSBrightnessController.refreshVisibility(shouldUseSplitNotificationShade = true)
-
- verify(brightnessController, times(1)).showSlider()
- }
-
- @Test
- fun testSliderIsHiddenWhenRefreshedInNonSplitShade() {
- // needs to be shown first
- quickQSBrightnessController.refreshVisibility(shouldUseSplitNotificationShade = true)
- quickQSBrightnessController.refreshVisibility(shouldUseSplitNotificationShade = false)
-
- verify(brightnessController).hideSlider()
- }
-
- @Test
- fun testSliderChangesVisibilityWhenRotating() {
- quickQSBrightnessController.refreshVisibility(shouldUseSplitNotificationShade = true)
- verify(brightnessController, times(1)).showSlider()
-
- quickQSBrightnessController.refreshVisibility(shouldUseSplitNotificationShade = false)
- verify(brightnessController, times(1)).hideSlider()
- }
-
- @Test
- fun testCallbacksAreRegisteredOnlyOnce() {
- // this flow simulates expanding shade in portrait...
- quickQSBrightnessController.setListening(true)
- quickQSBrightnessController.refreshVisibility(shouldUseSplitNotificationShade = false)
- // ... and rotating to landscape/split shade where slider is visible
- quickQSBrightnessController.refreshVisibility(shouldUseSplitNotificationShade = true)
-
- verify(brightnessController, times(1)).registerCallbacks()
- }
-
- @Test
- fun testCallbacksAreRegisteredOnlyOnceWhenRotatingPhone() {
- quickQSBrightnessController.setListening(true)
- quickQSBrightnessController.refreshVisibility(shouldUseSplitNotificationShade = true)
- quickQSBrightnessController.refreshVisibility(shouldUseSplitNotificationShade = false)
- quickQSBrightnessController.refreshVisibility(shouldUseSplitNotificationShade = true)
-
- verify(brightnessController, times(1)).registerCallbacks()
- }
-
- @Test
- fun testCallbacksAreNotRegisteredWhenSliderNotVisible() {
- quickQSBrightnessController.setListening(true)
- quickQSBrightnessController.refreshVisibility(shouldUseSplitNotificationShade = false)
-
- verify(brightnessController, never()).registerCallbacks()
- }
-
- @Test
- fun testMirrorIsSetWhenSliderIsShown() {
- val mirrorController = mock(BrightnessMirrorController::class.java)
- quickQSBrightnessController.setMirror(mirrorController)
- quickQSBrightnessController.refreshVisibility(shouldUseSplitNotificationShade = true)
-
- verify(brightnessController).setMirror(mirrorController)
- }
-}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt
index 59948d3..fb8a6e3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt
@@ -67,8 +67,6 @@
@Mock
private lateinit var tileView: QSTileView
@Mock
- private lateinit var quickQsBrightnessController: QuickQSBrightnessController
- @Mock
private lateinit var footerActionsController: FooterActionsController
@Captor
private lateinit var captor: ArgumentCaptor<QSPanel.OnConfigurationChangedListener>
@@ -95,7 +93,6 @@
uiEventLogger,
qsLogger,
dumpManager,
- quickQsBrightnessController,
footerActionsController
)
@@ -128,13 +125,11 @@
}
@Test
- fun testBrightnessAndFooterVisibilityRefreshedWhenConfigurationChanged() {
+ fun testFooterVisibilityRefreshedWhenConfigurationChanged() {
// times(2) because both controller and base controller are registering their listeners
verify(quickQSPanel, times(2)).addOnConfigurationChangedListener(captor.capture())
captor.allValues.forEach { it.onConfigurationChange(Configuration.EMPTY) }
-
- verify(quickQsBrightnessController).refreshVisibility(anyBoolean())
// times(2) because footer visibility is also refreshed on controller init
verify(footerActionsController, times(2)).refreshVisibility(anyBoolean())
}
diff --git a/services/Android.bp b/services/Android.bp
index 8947393..536dc5d 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -42,7 +42,9 @@
SYSTEM_OPTIMIZE_JAVA: {
optimize: {
enabled: true,
- optimize: true,
+ // TODO(b/210510433): Enable optimizations after improving
+ // retracing infra.
+ optimize: false,
shrink: true,
proguard_flags_files: ["proguard.flags"],
},
diff --git a/services/autofill/OWNERS b/services/autofill/OWNERS
index c52751d..edfb211 100644
--- a/services/autofill/OWNERS
+++ b/services/autofill/OWNERS
@@ -1 +1 @@
-include /core/java/android/service/autofill/OWNERS
+include /core/java/android/view/autofill/OWNERS
diff --git a/services/core/java/com/android/server/am/DataConnectionStats.java b/services/core/java/com/android/server/am/DataConnectionStats.java
index 6e39a4c..651e98c 100644
--- a/services/core/java/com/android/server/am/DataConnectionStats.java
+++ b/services/core/java/com/android/server/am/DataConnectionStats.java
@@ -73,7 +73,8 @@
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SIM_STATE_CHANGED);
- mContext.registerReceiver(this, filter, null /* broadcastPermission */, mListenerHandler);
+ mContext.registerReceiver(this, filter, null /* broadcastPermission */, mListenerHandler,
+ Context.RECEIVER_NOT_EXPORTED);
}
@Override
diff --git a/services/core/java/com/android/server/display/BrightnessTracker.java b/services/core/java/com/android/server/display/BrightnessTracker.java
index 2c2a2bf..17215e5 100644
--- a/services/core/java/com/android/server/display/BrightnessTracker.java
+++ b/services/core/java/com/android/server/display/BrightnessTracker.java
@@ -131,6 +131,7 @@
private static final int MSG_STOP_SENSOR_LISTENER = 2;
private static final int MSG_START_SENSOR_LISTENER = 3;
private static final int MSG_BRIGHTNESS_CONFIG_CHANGED = 4;
+ private static final int MSG_SENSOR_CHANGED = 5;
private static final SimpleDateFormat FORMAT = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
@@ -158,6 +159,7 @@
// These members should only be accessed on the mBgHandler thread.
private BroadcastReceiver mBroadcastReceiver;
private SensorListener mSensorListener;
+ private Sensor mLightSensor;
private SettingsObserver mSettingsObserver;
private DisplayListener mDisplayListener;
private boolean mSensorRegistered;
@@ -327,6 +329,14 @@
m.sendToTarget();
}
+ /**
+ * Updates the light sensor to use.
+ */
+ public void setLightSensor(Sensor lightSensor) {
+ mBgHandler.obtainMessage(MSG_SENSOR_CHANGED, 0 /*unused*/, 0/*unused*/, lightSensor)
+ .sendToTarget();
+ }
+
private void handleBrightnessChanged(float brightness, boolean userInitiated,
float powerBrightnessFactor, boolean isUserSetBrightness,
boolean isDefaultBrightnessConfig, long timestamp, String uniqueDisplayId) {
@@ -428,13 +438,28 @@
}
}
+ private void handleSensorChanged(Sensor lightSensor) {
+ if (mLightSensor != lightSensor) {
+ mLightSensor = lightSensor;
+ stopSensorListener();
+ synchronized (mDataCollectionLock) {
+ mLastSensorReadings.clear();
+ }
+ // Attempt to restart the sensor listener. It will check to see if it should be running
+ // so there is no need to also check here.
+ startSensorListener();
+ }
+ }
+
private void startSensorListener() {
if (!mSensorRegistered
+ && mLightSensor != null
+ && mAmbientBrightnessStatsTracker != null
&& mInjector.isInteractive(mContext)
&& mInjector.isBrightnessModeAutomatic(mContentResolver)) {
mAmbientBrightnessStatsTracker.start();
mSensorRegistered = true;
- mInjector.registerSensorListener(mContext, mSensorListener,
+ mInjector.registerSensorListener(mContext, mSensorListener, mLightSensor,
mInjector.getBackgroundHandler());
}
}
@@ -736,6 +761,7 @@
pw.println("BrightnessTracker state:");
synchronized (mDataCollectionLock) {
pw.println(" mStarted=" + mStarted);
+ pw.println(" mLightSensor=" + mLightSensor);
pw.println(" mLastBatteryLevel=" + mLastBatteryLevel);
pw.println(" mLastBrightness=" + mLastBrightness);
pw.println(" mLastSensorReadings.size=" + mLastSensorReadings.size());
@@ -1017,6 +1043,9 @@
disableColorSampling();
}
break;
+ case MSG_SENSOR_CHANGED:
+ handleSensorChanged((Sensor) msg.obj);
+ break;
}
}
@@ -1045,9 +1074,8 @@
@VisibleForTesting
static class Injector {
public void registerSensorListener(Context context,
- SensorEventListener sensorListener, Handler handler) {
+ SensorEventListener sensorListener, Sensor lightSensor, Handler handler) {
SensorManager sensorManager = context.getSystemService(SensorManager.class);
- Sensor lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
sensorManager.registerListener(sensorListener,
lightSensor, SensorManager.SENSOR_DELAY_NORMAL, handler);
}
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index e4cda38..77c1fc0 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -795,7 +795,6 @@
private void loadFromDisplayDeviceConfig(IBinder token, DisplayDeviceInfo info) {
// All properties that depend on the associated DisplayDevice and the DDC must be
// updated here.
- loadAmbientLightSensor();
loadBrightnessRampRates();
loadProximitySensor();
loadNitsRange(mContext.getResources());
@@ -925,6 +924,9 @@
}
loadAmbientLightSensor();
+ if (mBrightnessTracker != null) {
+ mBrightnessTracker.setLightSensor(mLightSensor);
+ }
if (mAutomaticBrightnessController != null) {
mAutomaticBrightnessController.stop();
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 211f8d6..f3562d6 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -658,7 +658,14 @@
return mBuffer.descendingIterator();
}
- public StatusBarNotification[] getArray(int count, boolean includeSnoozed) {
+ public StatusBarNotification[] getArray(UserManager um, int count, boolean includeSnoozed) {
+ ArrayList<Integer> currentUsers = new ArrayList<>();
+ currentUsers.add(UserHandle.USER_ALL);
+ Binder.withCleanCallingIdentity(() -> {
+ for (int user : um.getProfileIds(ActivityManager.getCurrentUser(), false)) {
+ currentUsers.add(user);
+ }
+ });
synchronized (mBufferLock) {
if (count == 0) count = mBufferSize;
List<StatusBarNotification> a = new ArrayList();
@@ -667,8 +674,10 @@
while (iter.hasNext() && i < count) {
Pair<StatusBarNotification, Integer> pair = iter.next();
if (pair.second != REASON_SNOOZED || includeSnoozed) {
- i++;
- a.add(pair.first);
+ if (currentUsers.contains(pair.first.getUserId())) {
+ i++;
+ a.add(pair.first);
+ }
}
}
return a.toArray(new StatusBarNotification[a.size()]);
@@ -4042,22 +4051,32 @@
android.Manifest.permission.ACCESS_NOTIFICATIONS,
"NotificationManagerService.getActiveNotifications");
- StatusBarNotification[] tmp = null;
+ ArrayList<StatusBarNotification> tmp = new ArrayList<>();
int uid = Binder.getCallingUid();
+ ArrayList<Integer> currentUsers = new ArrayList<>();
+ currentUsers.add(UserHandle.USER_ALL);
+ Binder.withCleanCallingIdentity(() -> {
+ for (int user : mUm.getProfileIds(ActivityManager.getCurrentUser(), false)) {
+ currentUsers.add(user);
+ }
+ });
+
// noteOp will check to make sure the callingPkg matches the uid
if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ACCESS_NOTIFICATIONS, uid, callingPkg,
callingAttributionTag, null)
== AppOpsManager.MODE_ALLOWED) {
synchronized (mNotificationLock) {
- tmp = new StatusBarNotification[mNotificationList.size()];
final int N = mNotificationList.size();
- for (int i=0; i<N; i++) {
- tmp[i] = mNotificationList.get(i).getSbn();
+ for (int i = 0; i < N; i++) {
+ final StatusBarNotification sbn = mNotificationList.get(i).getSbn();
+ if (currentUsers.contains(sbn.getUserId())) {
+ tmp.add(sbn);
+ }
}
}
}
- return tmp;
+ return tmp.toArray(new StatusBarNotification[tmp.size()]);
}
/**
@@ -4166,7 +4185,7 @@
callingAttributionTag, null)
== AppOpsManager.MODE_ALLOWED) {
synchronized (mArchive) {
- tmp = mArchive.getArray(count, includeSnoozed);
+ tmp = mArchive.getArray(mUm, count, includeSnoozed);
}
}
return tmp;
@@ -7695,7 +7714,9 @@
int index = mToastQueue.indexOf(record);
if (index >= 0) {
- mToastQueue.remove(index);
+ ToastRecord toast = mToastQueue.remove(index);
+ mWindowManagerInternal.removeWindowToken(
+ toast.windowToken, true /* removeWindows */, toast.displayId);
}
record = (mToastQueue.size() > 0) ? mToastQueue.get(0) : null;
}
diff --git a/services/core/java/com/android/server/notification/ZenModeFiltering.java b/services/core/java/com/android/server/notification/ZenModeFiltering.java
index 4d19855..acbe04b 100644
--- a/services/core/java/com/android/server/notification/ZenModeFiltering.java
+++ b/services/core/java/com/android/server/notification/ZenModeFiltering.java
@@ -24,11 +24,14 @@
import android.content.ComponentName;
import android.content.Context;
import android.media.AudioAttributes;
+import android.net.Uri;
import android.os.Bundle;
import android.os.UserHandle;
import android.provider.Settings.Global;
import android.service.notification.ZenModeConfig;
import android.telecom.TelecomManager;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.TelephonyManager;
import android.util.ArrayMap;
import android.util.Slog;
@@ -36,6 +39,8 @@
import com.android.internal.util.NotificationMessagingUtil;
import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
import java.util.Date;
public class ZenModeFiltering {
@@ -64,13 +69,22 @@
pw.print(prefix); pw.print("RepeatCallers.mThresholdMinutes=");
pw.println(REPEAT_CALLERS.mThresholdMinutes);
synchronized (REPEAT_CALLERS) {
- if (!REPEAT_CALLERS.mCalls.isEmpty()) {
- pw.print(prefix); pw.println("RepeatCallers.mCalls=");
- for (int i = 0; i < REPEAT_CALLERS.mCalls.size(); i++) {
+ if (!REPEAT_CALLERS.mTelCalls.isEmpty()) {
+ pw.print(prefix); pw.println("RepeatCallers.mTelCalls=");
+ for (int i = 0; i < REPEAT_CALLERS.mTelCalls.size(); i++) {
pw.print(prefix); pw.print(" ");
- pw.print(REPEAT_CALLERS.mCalls.keyAt(i));
+ pw.print(REPEAT_CALLERS.mTelCalls.keyAt(i));
pw.print(" at ");
- pw.println(ts(REPEAT_CALLERS.mCalls.valueAt(i)));
+ pw.println(ts(REPEAT_CALLERS.mTelCalls.valueAt(i)));
+ }
+ }
+ if (!REPEAT_CALLERS.mOtherCalls.isEmpty()) {
+ pw.print(prefix); pw.println("RepeatCallers.mOtherCalls=");
+ for (int i = 0; i < REPEAT_CALLERS.mOtherCalls.size(); i++) {
+ pw.print(prefix); pw.print(" ");
+ pw.print(REPEAT_CALLERS.mOtherCalls.keyAt(i));
+ pw.print(" at ");
+ pw.println(ts(REPEAT_CALLERS.mOtherCalls.valueAt(i)));
}
}
}
@@ -312,34 +326,39 @@
}
private static class RepeatCallers {
- // Person : time
- private final ArrayMap<String, Long> mCalls = new ArrayMap<>();
+ // We keep a separate map per uri scheme to do more generous number-matching
+ // handling on telephone numbers specifically. For other inputs, we
+ // simply match directly on the string.
+ private final ArrayMap<String, Long> mTelCalls = new ArrayMap<>();
+ private final ArrayMap<String, Long> mOtherCalls = new ArrayMap<>();
private int mThresholdMinutes;
private synchronized void recordCall(Context context, Bundle extras) {
setThresholdMinutes(context);
if (mThresholdMinutes <= 0 || extras == null) return;
- final String peopleString = peopleString(extras);
- if (peopleString == null) return;
+ final String[] extraPeople = ValidateNotificationPeople.getExtraPeople(extras);
+ if (extraPeople == null || extraPeople.length == 0) return;
final long now = System.currentTimeMillis();
- cleanUp(mCalls, now);
- mCalls.put(peopleString, now);
+ cleanUp(mTelCalls, now);
+ cleanUp(mOtherCalls, now);
+ recordCallers(extraPeople, now);
}
private synchronized boolean isRepeat(Context context, Bundle extras) {
setThresholdMinutes(context);
if (mThresholdMinutes <= 0 || extras == null) return false;
- final String peopleString = peopleString(extras);
- if (peopleString == null) return false;
+ final String[] extraPeople = ValidateNotificationPeople.getExtraPeople(extras);
+ if (extraPeople == null || extraPeople.length == 0) return false;
final long now = System.currentTimeMillis();
- cleanUp(mCalls, now);
- return mCalls.containsKey(peopleString);
+ cleanUp(mTelCalls, now);
+ cleanUp(mOtherCalls, now);
+ return checkCallers(context, extraPeople);
}
private synchronized void cleanUp(ArrayMap<String, Long> calls, long now) {
final int N = calls.size();
for (int i = N - 1; i >= 0; i--) {
- final long time = mCalls.valueAt(i);
+ final long time = calls.valueAt(i);
if (time > now || (now - time) > mThresholdMinutes * 1000 * 60) {
calls.removeAt(i);
}
@@ -353,21 +372,65 @@
}
}
- private static String peopleString(Bundle extras) {
- final String[] extraPeople = ValidateNotificationPeople.getExtraPeople(extras);
- if (extraPeople == null || extraPeople.length == 0) return null;
- final StringBuilder sb = new StringBuilder();
- for (int i = 0; i < extraPeople.length; i++) {
- String extraPerson = extraPeople[i];
- if (extraPerson == null) continue;
- extraPerson = extraPerson.trim();
- if (extraPerson.isEmpty()) continue;
- if (sb.length() > 0) {
- sb.append('|');
+ private synchronized void recordCallers(String[] people, long now) {
+ for (int i = 0; i < people.length; i++) {
+ String person = people[i];
+ if (person == null) continue;
+ final Uri uri = Uri.parse(person);
+ if ("tel".equals(uri.getScheme())) {
+ String tel = uri.getSchemeSpecificPart();
+ // while ideally we should not need to do this, sometimes we have seen tel
+ // numbers given in a url-encoded format
+ try {
+ tel = URLDecoder.decode(tel, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ // ignore, keep the original tel string
+ Slog.w(TAG, "unsupported encoding in tel: uri input");
+ }
+ mTelCalls.put(tel, now);
+ } else {
+ // for non-tel calls, store the entire string, uri-component and all
+ mOtherCalls.put(person, now);
}
- sb.append(extraPerson);
}
- return sb.length() == 0 ? null : sb.toString();
+ }
+
+ private synchronized boolean checkCallers(Context context, String[] people) {
+ // get the default country code for checking telephone numbers
+ final String defaultCountryCode =
+ context.getSystemService(TelephonyManager.class).getNetworkCountryIso();
+ for (int i = 0; i < people.length; i++) {
+ String person = people[i];
+ if (person == null) continue;
+ final Uri uri = Uri.parse(person);
+ if ("tel".equals(uri.getScheme())) {
+ String number = uri.getSchemeSpecificPart();
+ if (mTelCalls.containsKey(number)) {
+ // check directly via map first
+ return true;
+ } else {
+ // see if a number that matches via areSameNumber exists
+ String numberToCheck = number;
+ try {
+ numberToCheck = URLDecoder.decode(number, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ // ignore, continue to use the original string
+ Slog.w(TAG, "unsupported encoding in tel: uri input");
+ }
+ for (String prev : mTelCalls.keySet()) {
+ if (PhoneNumberUtils.areSamePhoneNumber(
+ numberToCheck, prev, defaultCountryCode)) {
+ return true;
+ }
+ }
+ }
+ } else {
+ if (mOtherCalls.containsKey(person)) {
+ return true;
+ }
+ }
+ }
+ return false;
}
}
diff --git a/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java b/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java
index a17e792..30e2617 100644
--- a/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java
+++ b/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java
@@ -146,7 +146,7 @@
filter.addAction(ACTION_CARRIER_CONFIG_CHANGED);
filter.addAction(ACTION_MULTI_SIM_CONFIG_CHANGED);
- mContext.registerReceiver(this, filter, null, mHandler);
+ mContext.registerReceiver(this, filter, null, mHandler, Context.RECEIVER_NOT_EXPORTED);
mSubscriptionManager.addOnSubscriptionsChangedListener(
executor, mSubscriptionChangedListener);
mTelephonyManager.registerTelephonyCallback(executor, mActiveDataSubIdListener);
diff --git a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
index 8b80b4a..597f7f2 100644
--- a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
+++ b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
@@ -78,6 +78,7 @@
import android.os.Process;
import android.os.SystemClock;
import android.provider.Settings;
+import android.telephony.TelephonyManager;
import android.util.ArraySet;
import android.util.Slog;
@@ -163,6 +164,14 @@
public class VcnGatewayConnection extends StateMachine {
private static final String TAG = VcnGatewayConnection.class.getSimpleName();
+ // Matches DataConnection.NETWORK_TYPE private constant, and magic string from
+ // ConnectivityManager#getNetworkTypeName()
+ @VisibleForTesting(visibility = Visibility.PRIVATE)
+ static final String NETWORK_INFO_NETWORK_TYPE_STRING = "MOBILE";
+
+ @VisibleForTesting(visibility = Visibility.PRIVATE)
+ static final String NETWORK_INFO_EXTRA_INFO = "VCN";
+
@VisibleForTesting(visibility = Visibility.PRIVATE)
static final InetAddress DUMMY_ADDR = InetAddresses.parseNumericAddress("192.0.2.0");
@@ -1631,6 +1640,12 @@
final NetworkAgentConfig nac =
new NetworkAgentConfig.Builder()
.setLegacyType(ConnectivityManager.TYPE_MOBILE)
+ .setLegacyTypeName(NETWORK_INFO_NETWORK_TYPE_STRING)
+ .setLegacySubType(TelephonyManager.NETWORK_TYPE_UNKNOWN)
+ .setLegacySubTypeName(
+ TelephonyManager.getNetworkTypeName(
+ TelephonyManager.NETWORK_TYPE_UNKNOWN))
+ .setLegacyExtraInfo(NETWORK_INFO_EXTRA_INFO)
.build();
final VcnNetworkAgent agent =
diff --git a/services/core/jni/BroadcastRadio/types.h b/services/core/jni/BroadcastRadio/types.h
index 910bb7c..4d286bf 100644
--- a/services/core/jni/BroadcastRadio/types.h
+++ b/services/core/jni/BroadcastRadio/types.h
@@ -30,13 +30,13 @@
// Keep in sync with STATUS_* constants from RadioManager.java.
enum class Status : jint {
OK = 0,
- ERROR = -0x80000000ll, // Integer.MIN_VALUE
+ ERROR = -0x80000000LL, // Integer.MIN_VALUE
PERMISSION_DENIED = -1, // -EPERM
- NO_INIT = -19, // -ENODEV
- BAD_VALUE = -22, // -EINVAL
- DEAD_OBJECT = -32, // -EPIPE
- INVALID_OPERATION = -38, // -ENOSYS
- TIMED_OUT = -110, // -ETIMEDOUT
+ NO_INIT = -19, // -ENODEV
+ BAD_VALUE = -22, // -EINVAL
+ DEAD_OBJECT = -32, // -EPIPE
+ INVALID_OPERATION = -38, // -ENOSYS
+ TIMED_OUT = -110, // -ETIMEDOUT
};
// Keep in sync with REGION_* constants from RadioManager.java.
diff --git a/services/core/jni/com_android_server_net_NetworkStatsService.cpp b/services/core/jni/com_android_server_net_NetworkStatsService.cpp
index f8a8168..39cbaf7 100644
--- a/services/core/jni/com_android_server_net_NetworkStatsService.cpp
+++ b/services/core/jni/com_android_server_net_NetworkStatsService.cpp
@@ -102,15 +102,10 @@
}
}
-static int deleteTagData(JNIEnv* /* env */, jclass /* clazz */, jint uid) {
- return qtaguid_deleteTagData(0, uid);
-}
-
static const JNINativeMethod gMethods[] = {
{"nativeGetTotalStat", "(I)J", (void*)getTotalStat},
{"nativeGetIfaceStat", "(Ljava/lang/String;I)J", (void*)getIfaceStat},
{"nativeGetUidStat", "(II)J", (void*)getUidStat},
- {"nativeDeleteTagData", "(I)I", (void*)deleteTagData},
};
int register_android_server_net_NetworkStatsService(JNIEnv* env) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 85e08eb..dabdff2 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -10768,7 +10768,7 @@
}
@Override
- public void resetNewUserDisclaimer() {
+ public void acknowledgeNewUserDisclaimer() {
CallerIdentity callerIdentity = getCallerIdentity();
canManageUsers(callerIdentity);
diff --git a/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
index bdf94f3..356600d 100644
--- a/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
@@ -33,6 +33,7 @@
import android.content.IntentFilter;
import android.content.pm.ParceledListSlice;
import android.database.ContentObserver;
+import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.display.AmbientBrightnessDayStats;
@@ -42,6 +43,7 @@
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayedContentSample;
import android.hardware.display.DisplayedContentSamplingAttributes;
+import android.hardware.input.InputSensorInfo;
import android.os.BatteryManager;
import android.os.Handler;
import android.os.HandlerThread;
@@ -63,6 +65,8 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -84,8 +88,11 @@
private static final String DEFAULT_DISPLAY_ID = "123";
private static final float FLOAT_DELTA = 0.01f;
+ @Mock private InputSensorInfo mInputSensorInfoMock;
+
private BrightnessTracker mTracker;
private TestInjector mInjector;
+ private Sensor mLightSensorFake;
private static Object sHandlerLock = new Object();
private static Handler sHandler;
@@ -108,9 +115,12 @@
@Before
public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
mInjector = new TestInjector(ensureHandler());
+ mLightSensorFake = new Sensor(mInputSensorInfoMock);
mTracker = new BrightnessTracker(InstrumentationRegistry.getContext(), mInjector);
+ mTracker.setLightSensor(mLightSensorFake);
mDefaultNightModeColorTemperature =
InstrumentationRegistry.getContext().getResources().getInteger(
R.integer.config_nightDisplayColorTemperatureDefault);
@@ -834,6 +844,47 @@
mTracker.stop();
}
+ @Test
+ public void testLightSensorChange() {
+ // verify the tracker started correctly and a listener registered
+ startTracker(mTracker);
+ assertNotNull(mInjector.mSensorListener);
+ assertEquals(mInjector.mLightSensor, mLightSensorFake);
+
+ // Setting the sensor to null should stop the registered listener.
+ mTracker.setLightSensor(null);
+ mInjector.waitForHandler();
+ assertNull(mInjector.mSensorListener);
+ assertNull(mInjector.mLightSensor);
+
+ // Resetting sensor should start listener again
+ mTracker.setLightSensor(mLightSensorFake);
+ mInjector.waitForHandler();
+ assertNotNull(mInjector.mSensorListener);
+ assertEquals(mInjector.mLightSensor, mLightSensorFake);
+
+ Sensor secondSensor = new Sensor(mInputSensorInfoMock);
+ // Setting a different listener should keep things working
+ mTracker.setLightSensor(secondSensor);
+ mInjector.waitForHandler();
+ assertNotNull(mInjector.mSensorListener);
+ assertEquals(mInjector.mLightSensor, secondSensor);
+ }
+
+ @Test
+ public void testSetLightSensorDoesntStartListener() {
+ mTracker.setLightSensor(mLightSensorFake);
+ assertNull(mInjector.mSensorListener);
+ }
+
+ @Test
+ public void testNullLightSensorWontRegister() {
+ mTracker.setLightSensor(null);
+ startTracker(mTracker);
+ assertNull(mInjector.mSensorListener);
+ assertNull(mInjector.mLightSensor);
+ }
+
private InputStream getInputStream(String data) {
return new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
}
@@ -924,6 +975,7 @@
private class TestInjector extends BrightnessTracker.Injector {
SensorEventListener mSensorListener;
+ Sensor mLightSensor;
BroadcastReceiver mBroadcastReceiver;
DisplayManager.DisplayListener mDisplayListener;
Map<String, Integer> mSecureIntSettings = new HashMap<>();
@@ -974,14 +1026,16 @@
@Override
public void registerSensorListener(Context context,
- SensorEventListener sensorListener, Handler handler) {
+ SensorEventListener sensorListener, Sensor lightSensor, Handler handler) {
mSensorListener = sensorListener;
+ mLightSensor = lightSensor;
}
@Override
public void unregisterSensorListener(Context context,
SensorEventListener sensorListener) {
mSensorListener = null;
+ mLightSensor = null;
}
@Override
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ArchiveTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ArchiveTest.java
index 1126e1e..4b6183d 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ArchiveTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ArchiveTest.java
@@ -15,16 +15,22 @@
*/
package com.android.server.notification;
+import static android.os.UserHandle.USER_ALL;
import static android.os.UserHandle.USER_CURRENT;
+import static android.os.UserHandle.USER_NULL;
import static android.os.UserHandle.USER_SYSTEM;
import static android.service.notification.NotificationListenerService.REASON_CANCEL;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.when;
import android.app.Notification;
import android.os.UserHandle;
+import android.os.UserManager;
import android.service.notification.StatusBarNotification;
import android.test.suitebuilder.annotation.SmallTest;
@@ -35,6 +41,7 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
@@ -51,6 +58,8 @@
private static final int SIZE = 5;
private NotificationManagerService.Archive mArchive;
+ @Mock
+ private UserManager mUm;
@Before
public void setUp() {
@@ -59,6 +68,9 @@
mArchive = new NotificationManagerService.Archive(SIZE);
mArchive.updateHistoryEnabled(USER_SYSTEM, true);
mArchive.updateHistoryEnabled(USER_CURRENT, true);
+
+ when(mUm.getProfileIds(anyInt(), anyBoolean())).thenReturn(
+ new int[] {USER_CURRENT, USER_SYSTEM});
}
private StatusBarNotification getNotification(String pkg, int id, UserHandle user) {
@@ -70,7 +82,6 @@
pkg, pkg, id, null, 0, 0, n, user, null, System.currentTimeMillis());
}
-
@Test
public void testRecordAndRead() {
List<String> expected = new ArrayList<>();
@@ -81,7 +92,7 @@
mArchive.record(sbn, REASON_CANCEL);
}
- List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(SIZE, true));
+ List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(mUm, SIZE, true));
assertThat(actual).hasSize(expected.size());
for (StatusBarNotification sbn : actual) {
assertThat(expected).contains(sbn.getKey());
@@ -89,6 +100,22 @@
}
@Test
+ public void testCrossUser() {
+ mArchive.record(getNotification("pkg", 1, UserHandle.of(USER_SYSTEM)), REASON_CANCEL);
+ mArchive.record(getNotification("pkg", 2, UserHandle.of(USER_CURRENT)), REASON_CANCEL);
+ mArchive.record(getNotification("pkg", 3, UserHandle.of(USER_ALL)), REASON_CANCEL);
+ mArchive.record(getNotification("pkg", 4, UserHandle.of(USER_NULL)), REASON_CANCEL);
+
+ List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(mUm, SIZE, true));
+ assertThat(actual).hasSize(3);
+ for (StatusBarNotification sbn : actual) {
+ if (sbn.getUserId() == USER_NULL) {
+ fail("leaked notification from wrong user");
+ }
+ }
+ }
+
+ @Test
public void testRecordAndRead_overLimit() {
List<String> expected = new ArrayList<>();
for (int i = 0; i < (SIZE * 2); i++) {
@@ -99,7 +126,8 @@
}
}
- List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray((SIZE * 2), true));
+ List<StatusBarNotification> actual = Arrays.asList(
+ mArchive.getArray(mUm, (SIZE * 2), true));
assertThat(actual).hasSize(expected.size());
for (StatusBarNotification sbn : actual) {
assertThat(expected).contains(sbn.getKey());
@@ -119,7 +147,7 @@
}
}
- List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(SIZE, true));
+ List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(mUm, SIZE, true));
assertThat(actual).hasSize(expected.size());
for (StatusBarNotification sbn : actual) {
assertThat(expected).contains(sbn.getKey());
@@ -140,7 +168,7 @@
}
mArchive.updateHistoryEnabled(USER_CURRENT, false);
- List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(SIZE, true));
+ List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(mUm, SIZE, true));
assertThat(actual).hasSize(expected.size());
for (StatusBarNotification sbn : actual) {
assertThat(expected).contains(sbn.getKey());
@@ -165,7 +193,7 @@
}
mArchive.removeChannelNotifications("pkg", USER_CURRENT, "test0");
mArchive.removeChannelNotifications("pkg", USER_CURRENT, "test" + (SIZE - 2));
- List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(SIZE, true));
+ List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(mUm, SIZE, true));
assertThat(actual).hasSize(expected.size());
for (StatusBarNotification sbn : actual) {
assertThat(expected).contains(sbn.getKey());
@@ -215,7 +243,7 @@
fail("Concurrent modification exception");
}
- List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(SIZE, true));
+ List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(mUm, SIZE, true));
assertThat(actual).hasSize(expected.size());
for (StatusBarNotification sbn : actual) {
assertThat(expected).contains(sbn.getKey());
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index e98d077..b98401e 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -60,6 +60,7 @@
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ONGOING;
import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL;
+import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
import static com.google.common.truth.Truth.assertThat;
@@ -475,6 +476,7 @@
when(mPackageManager.getPackagesForUid(mUid)).thenReturn(new String[]{PKG});
when(mPackageManagerClient.getPackagesForUid(anyInt())).thenReturn(new String[]{PKG});
mContext.addMockSystemService(AppOpsManager.class, mock(AppOpsManager.class));
+ when(mUm.getProfileIds(0, false)).thenReturn(new int[]{0});
// write to a test file; the system file isn't readable from tests
mFile = new File(mContext.getCacheDir(), "test.xml");
@@ -5572,6 +5574,39 @@
}
@Test
+ public void testRateLimitedToasts_windowsRemoved() throws Exception {
+ final String testPackage = "testPackageName";
+ assertEquals(0, mService.mToastQueue.size());
+ mService.isSystemUid = false;
+ setToastRateIsWithinQuota(false); // rate limit reached
+ setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false);
+ setAppInForegroundForToasts(mUid, false);
+
+ // package is not suspended
+ when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
+ .thenReturn(false);
+
+ Binder token = new Binder();
+ INotificationManager nmService = (INotificationManager) mService.mService;
+
+ nmService.enqueueTextToast(testPackage, token, "Text", 2000, 0, null);
+
+ // window token was added when enqueued
+ ArgumentCaptor<Binder> binderCaptor =
+ ArgumentCaptor.forClass(Binder.class);
+ verify(mWindowManagerInternal).addWindowToken(binderCaptor.capture(),
+ eq(TYPE_TOAST), anyInt(), eq(null));
+
+ // but never shown
+ verify(mStatusBar, times(0))
+ .showToast(anyInt(), any(), any(), any(), any(), anyInt(), any());
+
+ // and removed when rate limited
+ verify(mWindowManagerInternal)
+ .removeWindowToken(eq(binderCaptor.getValue()), eq(true), anyInt());
+ }
+
+ @Test
public void backgroundSystemCustomToast_callsSetProcessImportantAsForegroundForToast() throws
Exception {
final String testPackage = "testPackageName";
@@ -6970,8 +7005,9 @@
waitForIdle();
// A notification exists for the given record
- StatusBarNotification[] notifsBefore = mBinderService.getActiveNotifications(PKG);
- assertEquals(1, notifsBefore.length);
+ List<StatusBarNotification> notifsBefore =
+ mBinderService.getAppActiveNotifications(PKG, nr.getSbn().getUserId()).getList();
+ assertEquals(1, notifsBefore.size());
reset(mPackageManager);
@@ -8289,4 +8325,33 @@
assertTrue(captor.getValue().isPackageAllowed(new VersionedPackage("apples", 1001)));
assertFalse(captor.getValue().isPackageAllowed(new VersionedPackage("test", 1002)));
}
+
+ @Test
+ public void testGetActiveNotification_filtersUsers() throws Exception {
+ when(mUm.getProfileIds(0, false)).thenReturn(new int[]{0, 10});
+
+ NotificationRecord nr0 =
+ generateNotificationRecord(mTestNotificationChannel, 0);
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag0",
+ nr0.getSbn().getId(), nr0.getSbn().getNotification(), nr0.getSbn().getUserId());
+
+ NotificationRecord nr10 =
+ generateNotificationRecord(mTestNotificationChannel, 10);
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag10",
+ nr10.getSbn().getId(), nr10.getSbn().getNotification(), nr10.getSbn().getUserId());
+
+ NotificationRecord nr11 =
+ generateNotificationRecord(mTestNotificationChannel, 11);
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag11",
+ nr11.getSbn().getId(), nr11.getSbn().getNotification(), nr11.getSbn().getUserId());
+ waitForIdle();
+
+ StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
+ assertEquals(2, notifs.length);
+ for (StatusBarNotification sbn : notifs) {
+ if (sbn.getUserId() == 11) {
+ fail("leaked data across users");
+ }
+ }
+ }
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java
index fb15088..0f18cc6 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java
@@ -17,7 +17,6 @@
package com.android.server.notification;
import static android.app.Notification.CATEGORY_CALL;
-import static android.app.Notification.CATEGORY_MESSAGE;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_ANYONE;
import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT;
@@ -25,6 +24,7 @@
import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CALLS;
import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CONVERSATIONS;
import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES;
+import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_REPEAT_CALLERS;
import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_ANY;
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR;
import static android.provider.Settings.Global.ZEN_MODE_ALARMS;
@@ -43,8 +43,10 @@
import android.app.NotificationChannel;
import android.app.NotificationManager.Policy;
import android.media.AudioAttributes;
+import android.os.Bundle;
import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
+import android.telephony.TelephonyManager;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -68,10 +70,15 @@
private NotificationMessagingUtil mMessagingUtil;
private ZenModeFiltering mZenModeFiltering;
+ @Mock private TelephonyManager mTelephonyManager;
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mZenModeFiltering = new ZenModeFiltering(mContext, mMessagingUtil);
+
+ // for repeat callers / matchesCallFilter
+ mContext.addMockSystemService(TelephonyManager.class, mTelephonyManager);
}
private NotificationRecord getNotificationRecord() {
@@ -95,6 +102,23 @@
return r;
}
+ private Bundle makeExtrasBundleWithPeople(String[] people) {
+ Bundle extras = new Bundle();
+ extras.putObject(Notification.EXTRA_PEOPLE_LIST, people);
+ return extras;
+ }
+
+ private NotificationRecord getNotificationRecordWithPeople(String[] people) {
+ // set up notification record
+ NotificationRecord r = mock(NotificationRecord.class);
+ StatusBarNotification sbn = mock(StatusBarNotification.class);
+ Notification notification = mock(Notification.class);
+ notification.extras = makeExtrasBundleWithPeople(people);
+ when(sbn.getNotification()).thenReturn(notification);
+ when(r.getSbn()).thenReturn(sbn);
+ return r;
+ }
+
@Test
public void testIsMessage() {
NotificationRecord r = getNotificationRecord();
@@ -309,4 +333,111 @@
assertFalse(mZenModeFiltering.shouldIntercept(ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r));
}
+
+ @Test
+ public void testMatchesCallFilter_repeatCallers_directMatch() {
+ // after calls given an email with an exact string match, make sure that
+ // matchesCallFilter returns the right thing
+ String[] mailSource = new String[]{"mailto:hello.world"};
+ mZenModeFiltering.recordCall(getNotificationRecordWithPeople(mailSource));
+
+ // set up policy to only allow repeat callers
+ Policy policy = new Policy(
+ PRIORITY_CATEGORY_REPEAT_CALLERS, 0, 0, 0, CONVERSATION_SENDERS_NONE);
+
+ // check whether matchesCallFilter returns the right thing
+ Bundle inputMatches = makeExtrasBundleWithPeople(new String[]{"mailto:hello.world"});
+ Bundle inputWrong = makeExtrasBundleWithPeople(new String[]{"mailto:nope"});
+ assertTrue(ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
+ policy, UserHandle.SYSTEM,
+ inputMatches, null, 0, 0));
+ assertFalse(ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
+ policy, UserHandle.SYSTEM,
+ inputWrong, null, 0, 0));
+ }
+
+ @Test
+ public void testMatchesCallFilter_repeatCallers_telephoneVariants() {
+ // set up telephony manager behavior
+ when(mTelephonyManager.getNetworkCountryIso()).thenReturn("us");
+
+ String[] telSource = new String[]{"tel:+1-617-555-1212"};
+ mZenModeFiltering.recordCall(getNotificationRecordWithPeople(telSource));
+
+ // set up policy to only allow repeat callers
+ Policy policy = new Policy(
+ PRIORITY_CATEGORY_REPEAT_CALLERS, 0, 0, 0, CONVERSATION_SENDERS_NONE);
+
+ // cases to test:
+ // - identical number
+ // - same number, different formatting
+ // - different number
+ // - garbage
+ Bundle identical = makeExtrasBundleWithPeople(new String[]{"tel:+1-617-555-1212"});
+ Bundle same = makeExtrasBundleWithPeople(new String[]{"tel:16175551212"});
+ Bundle different = makeExtrasBundleWithPeople(new String[]{"tel:123-456-7890"});
+ Bundle garbage = makeExtrasBundleWithPeople(new String[]{"asdfghjkl;"});
+
+ assertTrue("identical numbers should match",
+ ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
+ policy, UserHandle.SYSTEM,
+ identical, null, 0, 0));
+ assertTrue("equivalent but non-identical numbers should match",
+ ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
+ policy, UserHandle.SYSTEM,
+ same, null, 0, 0));
+ assertFalse("non-equivalent numbers should not match",
+ ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
+ policy, UserHandle.SYSTEM,
+ different, null, 0, 0));
+ assertFalse("non-tel strings should not match",
+ ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
+ policy, UserHandle.SYSTEM,
+ garbage, null, 0, 0));
+ }
+
+ @Test
+ public void testMatchesCallFilter_repeatCallers_urlEncodedTels() {
+ // this is not intended to be a supported case but is one that we have seen
+ // sometimes in the wild, so make sure we handle url-encoded telephone numbers correctly
+ // when somebody provides one.
+
+ // set up telephony manager behavior
+ when(mTelephonyManager.getNetworkCountryIso()).thenReturn("us");
+
+ String[] telSource = new String[]{"tel:%2B16175551212"};
+ mZenModeFiltering.recordCall(getNotificationRecordWithPeople(telSource));
+
+ // set up policy to only allow repeat callers
+ Policy policy = new Policy(
+ PRIORITY_CATEGORY_REPEAT_CALLERS, 0, 0, 0, CONVERSATION_SENDERS_NONE);
+
+ // test cases for various forms of the same phone number and different ones
+ Bundle same1 = makeExtrasBundleWithPeople(new String[]{"tel:+1-617-555-1212"});
+ Bundle same2 = makeExtrasBundleWithPeople(new String[]{"tel:%2B1-617-555-1212"});
+ Bundle same3 = makeExtrasBundleWithPeople(new String[]{"tel:6175551212"});
+ Bundle different1 = makeExtrasBundleWithPeople(new String[]{"tel:%2B16175553434"});
+ Bundle different2 = makeExtrasBundleWithPeople(new String[]{"tel:+16175553434"});
+
+ assertTrue("same number should match",
+ ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
+ policy, UserHandle.SYSTEM,
+ same1, null, 0, 0));
+ assertTrue("same number should match",
+ ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
+ policy, UserHandle.SYSTEM,
+ same2, null, 0, 0));
+ assertTrue("same number should match",
+ ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
+ policy, UserHandle.SYSTEM,
+ same3, null, 0, 0));
+ assertFalse("different number should not match",
+ ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
+ policy, UserHandle.SYSTEM,
+ different1, null, 0, 0));
+ assertFalse("different number should not match",
+ ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
+ policy, UserHandle.SYSTEM,
+ different2, null, 0, 0));
+ }
}
diff --git a/services/translation/OWNERS b/services/translation/OWNERS
index a1e663a..440f9a8 100644
--- a/services/translation/OWNERS
+++ b/services/translation/OWNERS
@@ -1,8 +1,3 @@
# Bug component: 994311
-adamhe@google.com
-augale@google.com
-joannechung@google.com
-lpeter@google.com
-svetoslavganov@google.com
-tymtsai@google.com
+include /core/java/android/view/translation/OWNERS
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 3882acf..5ada2a4 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -489,6 +489,7 @@
// current USB state
private boolean mHostConnected;
+ private boolean mUsbAccessoryConnected;
private boolean mSourcePower;
private boolean mSinkPower;
private boolean mConfigured;
@@ -958,10 +959,10 @@
break;
case MSG_UPDATE_HOST_STATE:
Iterator devices = (Iterator) msg.obj;
- boolean connected = (msg.arg1 == 1);
+ mUsbAccessoryConnected = (msg.arg1 == 1);
if (DEBUG) {
- Slog.i(TAG, "HOST_STATE connected:" + connected);
+ Slog.i(TAG, "HOST_STATE connected:" + mUsbAccessoryConnected);
}
mHideUsbNotification = false;
@@ -1215,7 +1216,7 @@
} else if (mSourcePower) {
titleRes = com.android.internal.R.string.usb_supplying_notification_title;
id = SystemMessage.NOTE_USB_SUPPLYING;
- } else if (mHostConnected && mSinkPower && mUsbCharging) {
+ } else if (mHostConnected && mSinkPower && (mUsbCharging || mUsbAccessoryConnected)) {
titleRes = com.android.internal.R.string.usb_charging_notification_title;
id = SystemMessage.NOTE_USB_CHARGING;
}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index ab8867f..ef847b6 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -4619,6 +4619,15 @@
KEY_PREFIX + "enable_presence_group_subscribe_bool";
/**
+ * Flag indicating whether or not to use SIP URI when send a presence subscribe.
+ * When {@code true}, the device sets the To and Contact header to be SIP URI using
+ * the TelephonyManager#getIsimDomain" API.
+ * If {@code false}, the device uses a TEL URI.
+ */
+ public static final String KEY_USE_SIP_URI_FOR_PRESENCE_SUBSCRIBE_BOOL =
+ KEY_PREFIX + "use_sip_uri_for_presence_subscribe_bool";
+
+ /**
* An integer key associated with the period of time in seconds the non-rcs capability
* information of each contact is cached on the device.
* <p>
@@ -4800,6 +4809,7 @@
defaults.putBoolean(KEY_ENABLE_PRESENCE_CAPABILITY_EXCHANGE_BOOL, false);
defaults.putBoolean(KEY_RCS_BULK_CAPABILITY_EXCHANGE_BOOL, false);
defaults.putBoolean(KEY_ENABLE_PRESENCE_GROUP_SUBSCRIBE_BOOL, false);
+ defaults.putBoolean(KEY_USE_SIP_URI_FOR_PRESENCE_SUBSCRIBE_BOOL, false);
defaults.putInt(KEY_NON_RCS_CAPABILITIES_CACHE_EXPIRATION_SEC_INT, 30 * 24 * 60 * 60);
defaults.putBoolean(KEY_RCS_REQUEST_FORBIDDEN_BY_SIP_489_BOOL, false);
defaults.putLong(KEY_RCS_REQUEST_RETRY_INTERVAL_MILLIS_LONG, 20 * 60 * 1000);
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 846e6f3..9fd2ae4 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -19,6 +19,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
@@ -767,6 +768,10 @@
*
* @return long name of operator, null if unregistered or unknown
*/
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.ACCESS_FINE_LOCATION,
+ android.Manifest.permission.ACCESS_COARSE_LOCATION
+ })
public String getOperatorAlphaLong() {
return mOperatorAlphaLong;
}
@@ -782,6 +787,10 @@
* @return long name of operator
* @hide
*/
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.ACCESS_FINE_LOCATION,
+ android.Manifest.permission.ACCESS_COARSE_LOCATION
+ })
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q,
publicAlternatives = "Use {@link #getOperatorAlphaLong} instead.")
public String getVoiceOperatorAlphaLong() {
@@ -800,6 +809,10 @@
*
* @return short name of operator, null if unregistered or unknown
*/
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.ACCESS_FINE_LOCATION,
+ android.Manifest.permission.ACCESS_COARSE_LOCATION
+ })
public String getOperatorAlphaShort() {
return mOperatorAlphaShort;
}
@@ -815,6 +828,10 @@
* @return short name of operator, null if unregistered or unknown
* @hide
*/
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.ACCESS_FINE_LOCATION,
+ android.Manifest.permission.ACCESS_COARSE_LOCATION
+ })
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q,
publicAlternatives = "Use {@link #getOperatorAlphaShort} instead.")
public String getVoiceOperatorAlphaShort() {
@@ -832,6 +849,10 @@
* @return short name of operator, null if unregistered or unknown
* @hide
*/
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.ACCESS_FINE_LOCATION,
+ android.Manifest.permission.ACCESS_COARSE_LOCATION
+ })
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q,
publicAlternatives = "Use {@link #getOperatorAlphaShort} instead.")
public String getDataOperatorAlphaShort() {
@@ -853,6 +874,10 @@
* @return name of operator, null if unregistered or unknown
* @hide
*/
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.ACCESS_FINE_LOCATION,
+ android.Manifest.permission.ACCESS_COARSE_LOCATION
+ })
public String getOperatorAlpha() {
if (TextUtils.isEmpty(mOperatorAlphaLong)) {
return mOperatorAlphaShort;
@@ -878,6 +903,10 @@
* The country code can be decoded using
* {@link com.android.internal.telephony.MccTable#countryCodeForMcc(int)}.
*/
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.ACCESS_FINE_LOCATION,
+ android.Manifest.permission.ACCESS_COARSE_LOCATION
+ })
public String getOperatorNumeric() {
return mOperatorNumeric;
}
@@ -893,6 +922,10 @@
* @return numeric format of operator, null if unregistered or unknown
* @hide
*/
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.ACCESS_FINE_LOCATION,
+ android.Manifest.permission.ACCESS_COARSE_LOCATION
+ })
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
public String getVoiceOperatorNumeric() {
return mOperatorNumeric;
@@ -909,6 +942,10 @@
* @return numeric format of operator, null if unregistered or unknown
* @hide
*/
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.ACCESS_FINE_LOCATION,
+ android.Manifest.permission.ACCESS_COARSE_LOCATION
+ })
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q,
publicAlternatives = "Use {@link #getOperatorNumeric} instead.")
public String getDataOperatorNumeric() {
@@ -1758,8 +1795,17 @@
/**
* Get the CDMA NID (Network Identification Number), a number uniquely identifying a network
* within a wireless system. (Defined in 3GPP2 C.S0023 3.4.8)
+ *
+ * <p>Require at least {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or
+ * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}. Otherwise return
+ * {@link #UNKNOWN_ID}.
+ *
* @return The CDMA NID or {@link #UNKNOWN_ID} if not available.
*/
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.ACCESS_FINE_LOCATION,
+ android.Manifest.permission.ACCESS_COARSE_LOCATION
+ })
public int getCdmaNetworkId() {
return this.mNetworkId;
}
@@ -1767,8 +1813,17 @@
/**
* Get the CDMA SID (System Identification Number), a number uniquely identifying a wireless
* system. (Defined in 3GPP2 C.S0023 3.4.8)
+ *
+ * <p>Require at least {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or
+ * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}. Otherwise return
+ * {@link #UNKNOWN_ID}.
+ *
* @return The CDMA SID or {@link #UNKNOWN_ID} if not available.
*/
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.ACCESS_FINE_LOCATION,
+ android.Manifest.permission.ACCESS_COARSE_LOCATION
+ })
public int getCdmaSystemId() {
return this.mSystemId;
}
@@ -2069,6 +2124,8 @@
state.mOperatorAlphaLong = null;
state.mOperatorAlphaShort = null;
state.mOperatorNumeric = null;
+ state.mSystemId = UNKNOWN_ID;
+ state.mNetworkId = UNKNOWN_ID;
return state;
}
diff --git a/telephony/java/android/telephony/ims/RcsContactUceCapability.java b/telephony/java/android/telephony/ims/RcsContactUceCapability.java
index 9112118..9c36db8 100644
--- a/telephony/java/android/telephony/ims/RcsContactUceCapability.java
+++ b/telephony/java/android/telephony/ims/RcsContactUceCapability.java
@@ -221,6 +221,15 @@
}
/**
+ * Set the entity URI related to the contact whose capabilities were requested.
+ * @param entityUri the 'pres' URL of the PRESENTITY publishing presence document.
+ */
+ public @NonNull PresenceBuilder setEntityUri(@NonNull Uri entityUri) {
+ mCapabilities.mEntityUri = entityUri;
+ return this;
+ }
+
+ /**
* @return the RcsContactUceCapability instance.
*/
public @NonNull RcsContactUceCapability build() {
@@ -232,6 +241,7 @@
private @SourceType int mSourceType;
private @CapabilityMechanism int mCapabilityMechanism;
private @RequestResult int mRequestResult;
+ private Uri mEntityUri;
private final Set<String> mFeatureTags = new HashSet<>();
private final List<RcsContactPresenceTuple> mPresenceTuples = new ArrayList<>();
@@ -248,6 +258,7 @@
mCapabilityMechanism = in.readInt();
mSourceType = in.readInt();
mRequestResult = in.readInt();
+ mEntityUri = in.readParcelable(Uri.class.getClassLoader(), android.net.Uri.class);
List<String> featureTagList = new ArrayList<>();
in.readStringList(featureTagList);
mFeatureTags.addAll(featureTagList);
@@ -260,6 +271,7 @@
out.writeInt(mCapabilityMechanism);
out.writeInt(mSourceType);
out.writeInt(mRequestResult);
+ out.writeParcelable(mEntityUri, flags);
out.writeStringList(new ArrayList<>(mFeatureTags));
out.writeParcelableList(mPresenceTuples, flags);
}
@@ -361,6 +373,15 @@
return mContactUri;
}
+ /**
+ * Retrieve the entity URI of the contact whose presence information is being requested for.
+ * @return the URI representing the 'pres' URL of the PRESENTITY publishing presence document
+ * or {@code null} if the entity uri does not exist in the presence document.
+ */
+ public @Nullable Uri getEntityUri() {
+ return mEntityUri;
+ }
+
@Override
public String toString() {
StringBuilder builder = new StringBuilder("RcsContactUceCapability");
@@ -382,6 +403,13 @@
builder.append(mSourceType);
builder.append(", requestResult=");
builder.append(mRequestResult);
+ if (Build.IS_ENG) {
+ builder.append("entity uri=");
+ builder.append(mEntityUri != null ? mEntityUri : "null");
+ } else {
+ builder.append("entity uri (isNull)=");
+ builder.append(mEntityUri != null ? "XXX" : "null");
+ }
if (mCapabilityMechanism == CAPABILITY_MECHANISM_PRESENCE) {
builder.append(", presenceTuples={");
diff --git a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
index 978bf3e..7b1f7a5 100644
--- a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
+++ b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
@@ -174,7 +174,7 @@
private IntentFilter getIntentFilter() {
final ArgumentCaptor<IntentFilter> captor = ArgumentCaptor.forClass(IntentFilter.class);
- verify(mContext).registerReceiver(any(), captor.capture(), any(), any());
+ verify(mContext).registerReceiver(any(), captor.capture(), any(), any(), anyInt());
return captor.getValue();
}
@@ -258,7 +258,8 @@
eq(mTelephonySubscriptionTracker),
any(IntentFilter.class),
any(),
- eq(mHandler));
+ eq(mHandler),
+ eq(Context.RECEIVER_NOT_EXPORTED));
final IntentFilter filter = getIntentFilter();
assertEquals(2, filter.countActions());
assertTrue(filter.hasAction(ACTION_CARRIER_CONFIG_CHANGED));
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
index e547400..4cfa93b 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
@@ -307,7 +307,10 @@
ncCaptor.capture(),
lpCaptor.capture(),
any(),
- argThat(nac -> nac.getLegacyType() == ConnectivityManager.TYPE_MOBILE),
+ // Subtype integer/name and extras do not have getters; cannot be tested.
+ argThat(nac -> nac.getLegacyType() == ConnectivityManager.TYPE_MOBILE
+ && nac.getLegacyTypeName().equals(
+ VcnGatewayConnection.NETWORK_INFO_NETWORK_TYPE_STRING)),
any(),
any(),
any());