Merge "Add more files as dexopt related files." into tm-dev
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobStore.java b/apex/jobscheduler/service/java/com/android/server/job/JobStore.java
index a8dd752..dfa1442 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobStore.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobStore.java
@@ -548,7 +548,7 @@
out.attribute(null, "sourceUserId", String.valueOf(jobStatus.getSourceUserId()));
out.attribute(null, "uid", Integer.toString(jobStatus.getUid()));
out.attribute(null, "bias", String.valueOf(jobStatus.getBias()));
- out.attribute(null, "priority", String.valueOf(jobStatus.getEffectivePriority()));
+ out.attribute(null, "priority", String.valueOf(jobStatus.getJob().getPriority()));
out.attribute(null, "flags", String.valueOf(jobStatus.getFlags()));
if (jobStatus.getInternalFlags() != 0) {
out.attribute(null, "internalFlags", String.valueOf(jobStatus.getInternalFlags()));
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
index 849354b..04f96de 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
@@ -78,6 +78,7 @@
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
+import android.content.pm.ResolveInfo;
import android.database.ContentObserver;
import android.hardware.display.DisplayManager;
import android.net.NetworkScoreManager;
@@ -219,7 +220,8 @@
private static final int HEADLESS_APP_CHECK_FLAGS =
PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
- | PackageManager.GET_ACTIVITIES | PackageManager.MATCH_DISABLED_COMPONENTS;
+ | PackageManager.MATCH_DISABLED_COMPONENTS
+ | PackageManager.MATCH_SYSTEM_ONLY;
// To name the lock for stack traces
static class Lock {}
@@ -253,7 +255,7 @@
private final SparseArray<Set<String>> mActiveAdminApps = new SparseArray<>();
/**
- * Set of system apps that are headless (don't have any declared activities, enabled or
+ * Set of system apps that are headless (don't have any "front door" activities, enabled or
* disabled). Presence in this map indicates that the app is a headless system app.
*/
@GuardedBy("mHeadlessSystemApps")
@@ -1942,7 +1944,7 @@
try {
PackageInfo pi = mPackageManager.getPackageInfoAsUser(
packageName, HEADLESS_APP_CHECK_FLAGS, userId);
- evaluateSystemAppException(pi);
+ maybeUpdateHeadlessSystemAppCache(pi);
} catch (PackageManager.NameNotFoundException e) {
synchronized (mHeadlessSystemApps) {
mHeadlessSystemApps.remove(packageName);
@@ -1950,19 +1952,31 @@
}
}
- /** Returns true if the exception status changed. */
- private boolean evaluateSystemAppException(@Nullable PackageInfo pkgInfo) {
+ /**
+ * Update the "headless system app" cache.
+ *
+ * @return true if the cache is updated.
+ */
+ private boolean maybeUpdateHeadlessSystemAppCache(@Nullable PackageInfo pkgInfo) {
if (pkgInfo == null || pkgInfo.applicationInfo == null
|| (!pkgInfo.applicationInfo.isSystemApp()
&& !pkgInfo.applicationInfo.isUpdatedSystemApp())) {
return false;
}
+ final Intent frontDoorActivityIntent = new Intent(Intent.ACTION_MAIN)
+ .addCategory(Intent.CATEGORY_LAUNCHER)
+ .setPackage(pkgInfo.packageName);
+ List<ResolveInfo> res = mPackageManager.queryIntentActivitiesAsUser(frontDoorActivityIntent,
+ HEADLESS_APP_CHECK_FLAGS, UserHandle.USER_SYSTEM);
+ return updateHeadlessSystemAppCache(pkgInfo.packageName, ArrayUtils.isEmpty(res));
+ }
+
+ private boolean updateHeadlessSystemAppCache(String packageName, boolean add) {
synchronized (mHeadlessSystemApps) {
- if (pkgInfo.activities == null || pkgInfo.activities.length == 0) {
- // Headless system app.
- return mHeadlessSystemApps.add(pkgInfo.packageName);
+ if (add) {
+ return mHeadlessSystemApps.add(packageName);
} else {
- return mHeadlessSystemApps.remove(pkgInfo.packageName);
+ return mHeadlessSystemApps.remove(packageName);
}
}
}
@@ -1999,20 +2013,45 @@
}
}
+ /** Returns the packages that have launcher icons. */
+ private Set<String> getSystemPackagesWithLauncherActivities() {
+ final Intent intent = new Intent(Intent.ACTION_MAIN)
+ .addCategory(Intent.CATEGORY_LAUNCHER);
+ List<ResolveInfo> activities = mPackageManager.queryIntentActivitiesAsUser(intent,
+ HEADLESS_APP_CHECK_FLAGS, UserHandle.USER_SYSTEM);
+ final ArraySet<String> ret = new ArraySet<>();
+ for (ResolveInfo ri : activities) {
+ ret.add(ri.activityInfo.packageName);
+ }
+ return ret;
+ }
+
/** Call on system boot to get the initial set of headless system apps. */
private void loadHeadlessSystemAppCache() {
- Slog.d(TAG, "Loading headless system app cache. appIdleEnabled=" + mAppIdleEnabled);
+ final long start = SystemClock.uptimeMillis();
final List<PackageInfo> packages = mPackageManager.getInstalledPackagesAsUser(
HEADLESS_APP_CHECK_FLAGS, UserHandle.USER_SYSTEM);
+
+ final Set<String> systemLauncherActivities = getSystemPackagesWithLauncherActivities();
+
final int packageCount = packages.size();
for (int i = 0; i < packageCount; i++) {
- PackageInfo pkgInfo = packages.get(i);
- if (pkgInfo != null && evaluateSystemAppException(pkgInfo)) {
+ final PackageInfo pkgInfo = packages.get(i);
+ if (pkgInfo == null) {
+ continue;
+ }
+ final String pkg = pkgInfo.packageName;
+ final boolean isHeadLess = !systemLauncherActivities.contains(pkg);
+
+ if (updateHeadlessSystemAppCache(pkg, isHeadLess)) {
mHandler.obtainMessage(MSG_CHECK_PACKAGE_IDLE_STATE,
- UserHandle.USER_SYSTEM, -1, pkgInfo.packageName)
+ UserHandle.USER_SYSTEM, -1, pkg)
.sendToTarget();
}
}
+ final long end = SystemClock.uptimeMillis();
+ Slog.d(TAG, "Loaded headless system app cache in " + (end - start) + " ms:"
+ + " appIdleEnabled=" + mAppIdleEnabled);
}
@Override
diff --git a/boot/hiddenapi/hiddenapi-max-target-o.txt b/boot/hiddenapi/hiddenapi-max-target-o.txt
index d3b5be9..3c16915 100644
--- a/boot/hiddenapi/hiddenapi-max-target-o.txt
+++ b/boot/hiddenapi/hiddenapi-max-target-o.txt
@@ -32472,14 +32472,6 @@
Landroid/net/DhcpResults;->setServerAddress(Ljava/lang/String;)Z
Landroid/net/DhcpResults;->setVendorInfo(Ljava/lang/String;)V
Landroid/net/DhcpResults;->TAG:Ljava/lang/String;
-Landroid/net/EthernetManager;-><init>(Landroid/content/Context;Landroid/net/IEthernetManager;)V
-Landroid/net/EthernetManager;->mContext:Landroid/content/Context;
-Landroid/net/EthernetManager;->mHandler:Landroid/os/Handler;
-Landroid/net/EthernetManager;->mListeners:Ljava/util/ArrayList;
-Landroid/net/EthernetManager;->mService:Landroid/net/IEthernetManager;
-Landroid/net/EthernetManager;->mServiceListener:Landroid/net/IEthernetServiceListener$Stub;
-Landroid/net/EthernetManager;->MSG_AVAILABILITY_CHANGED:I
-Landroid/net/EthernetManager;->TAG:Ljava/lang/String;
Landroid/net/EventLogTags;-><init>()V
Landroid/net/EventLogTags;->NTP_FAILURE:I
Landroid/net/EventLogTags;->NTP_SUCCESS:I
@@ -32513,39 +32505,6 @@
Landroid/net/http/X509TrustManagerExtensions;->mDelegate:Lcom/android/org/conscrypt/TrustManagerImpl;
Landroid/net/http/X509TrustManagerExtensions;->mIsSameTrustConfiguration:Ljava/lang/reflect/Method;
Landroid/net/http/X509TrustManagerExtensions;->mTrustManager:Ljavax/net/ssl/X509TrustManager;
-Landroid/net/IEthernetManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/net/IEthernetManager$Stub$Proxy;->addListener(Landroid/net/IEthernetServiceListener;)V
-Landroid/net/IEthernetManager$Stub$Proxy;->getAvailableInterfaces()[Ljava/lang/String;
-Landroid/net/IEthernetManager$Stub$Proxy;->getConfiguration(Ljava/lang/String;)Landroid/net/IpConfiguration;
-Landroid/net/IEthernetManager$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/net/IEthernetManager$Stub$Proxy;->isAvailable(Ljava/lang/String;)Z
-Landroid/net/IEthernetManager$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/net/IEthernetManager$Stub$Proxy;->removeListener(Landroid/net/IEthernetServiceListener;)V
-Landroid/net/IEthernetManager$Stub$Proxy;->setConfiguration(Ljava/lang/String;Landroid/net/IpConfiguration;)V
-Landroid/net/IEthernetManager$Stub;-><init>()V
-Landroid/net/IEthernetManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/IEthernetManager;
-Landroid/net/IEthernetManager$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/net/IEthernetManager$Stub;->TRANSACTION_addListener:I
-Landroid/net/IEthernetManager$Stub;->TRANSACTION_getAvailableInterfaces:I
-Landroid/net/IEthernetManager$Stub;->TRANSACTION_getConfiguration:I
-Landroid/net/IEthernetManager$Stub;->TRANSACTION_isAvailable:I
-Landroid/net/IEthernetManager$Stub;->TRANSACTION_removeListener:I
-Landroid/net/IEthernetManager$Stub;->TRANSACTION_setConfiguration:I
-Landroid/net/IEthernetManager;->addListener(Landroid/net/IEthernetServiceListener;)V
-Landroid/net/IEthernetManager;->getAvailableInterfaces()[Ljava/lang/String;
-Landroid/net/IEthernetManager;->getConfiguration(Ljava/lang/String;)Landroid/net/IpConfiguration;
-Landroid/net/IEthernetManager;->isAvailable(Ljava/lang/String;)Z
-Landroid/net/IEthernetManager;->removeListener(Landroid/net/IEthernetServiceListener;)V
-Landroid/net/IEthernetManager;->setConfiguration(Ljava/lang/String;Landroid/net/IpConfiguration;)V
-Landroid/net/IEthernetServiceListener$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/net/IEthernetServiceListener$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/net/IEthernetServiceListener$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/net/IEthernetServiceListener$Stub$Proxy;->onAvailabilityChanged(Ljava/lang/String;Z)V
-Landroid/net/IEthernetServiceListener$Stub;-><init>()V
-Landroid/net/IEthernetServiceListener$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/IEthernetServiceListener;
-Landroid/net/IEthernetServiceListener$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/net/IEthernetServiceListener$Stub;->TRANSACTION_onAvailabilityChanged:I
-Landroid/net/IEthernetServiceListener;->onAvailabilityChanged(Ljava/lang/String;Z)V
Landroid/net/IIpConnectivityMetrics$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/net/IIpConnectivityMetrics$Stub$Proxy;->addNetdEventCallback(ILandroid/net/INetdEventCallback;)Z
Landroid/net/IIpConnectivityMetrics$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
diff --git a/core/api/current.txt b/core/api/current.txt
index c80c4cb..1391408a 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -142,7 +142,7 @@
field @Deprecated public static final String READ_INPUT_STATE = "android.permission.READ_INPUT_STATE";
field public static final String READ_LOGS = "android.permission.READ_LOGS";
field public static final String READ_MEDIA_AUDIO = "android.permission.READ_MEDIA_AUDIO";
- field public static final String READ_MEDIA_IMAGE = "android.permission.READ_MEDIA_IMAGE";
+ field public static final String READ_MEDIA_IMAGES = "android.permission.READ_MEDIA_IMAGES";
field public static final String READ_MEDIA_VIDEO = "android.permission.READ_MEDIA_VIDEO";
field public static final String READ_NEARBY_STREAMING_POLICY = "android.permission.READ_NEARBY_STREAMING_POLICY";
field public static final String READ_PHONE_NUMBERS = "android.permission.READ_PHONE_NUMBERS";
@@ -18820,6 +18820,7 @@
method public void onStartInput(android.view.inputmethod.EditorInfo, boolean);
method public void onStartInputView(android.view.inputmethod.EditorInfo, boolean);
method public boolean onStartStylusHandwriting();
+ method public void onStylusHandwritingMotionEvent(@NonNull android.view.MotionEvent);
method public void onUnbindInput();
method @Deprecated public void onUpdateCursor(android.graphics.Rect);
method public void onUpdateCursorAnchorInfo(android.view.inputmethod.CursorAnchorInfo);
@@ -26087,7 +26088,7 @@
method @NonNull public java.util.List<android.media.tv.interactive.TvInteractiveAppInfo> getTvInteractiveAppServiceList();
method public void prepare(@NonNull String, int);
method public void registerAppLinkInfo(@NonNull String, @NonNull android.media.tv.interactive.AppLinkInfo);
- method public void registerCallback(@NonNull android.media.tv.interactive.TvInteractiveAppManager.TvInteractiveAppCallback, @NonNull java.util.concurrent.Executor);
+ method public void registerCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.tv.interactive.TvInteractiveAppManager.TvInteractiveAppCallback);
method public void sendAppLinkCommand(@NonNull String, @NonNull android.os.Bundle);
method public void unregisterAppLinkInfo(@NonNull String, @NonNull android.media.tv.interactive.AppLinkInfo);
method public void unregisterCallback(@NonNull android.media.tv.interactive.TvInteractiveAppManager.TvInteractiveAppCallback);
@@ -26157,10 +26158,10 @@
public abstract static class TvInteractiveAppService.Session implements android.view.KeyEvent.Callback {
ctor public TvInteractiveAppService.Session(@NonNull android.content.Context);
- method public void layoutSurface(int, int, int, int);
- method public final void notifyBiInteractiveAppCreated(@NonNull android.net.Uri, @Nullable String);
- method public void notifySessionStateChanged(int, int);
- method public final void notifyTeletextAppStateChanged(int);
+ method @CallSuper public void layoutSurface(int, int, int, int);
+ method @CallSuper public final void notifyBiInteractiveAppCreated(@NonNull android.net.Uri, @Nullable String);
+ method @CallSuper public void notifySessionStateChanged(int, int);
+ method @CallSuper public final void notifyTeletextAppStateChanged(int);
method public void onAdResponse(@NonNull android.media.tv.AdResponse);
method public void onBroadcastInfoResponse(@NonNull android.media.tv.BroadcastInfoResponse);
method public void onContentAllowed();
@@ -26194,17 +26195,17 @@
method public void onTuned(@NonNull android.net.Uri);
method public void onVideoAvailable();
method public void onVideoUnavailable(int);
- method public void removeBroadcastInfo(int);
- method public void requestAd(@NonNull android.media.tv.AdRequest);
- method public void requestBroadcastInfo(@NonNull android.media.tv.BroadcastInfoRequest);
- method public void requestCurrentChannelLcn();
- method public void requestCurrentChannelUri();
- method public void requestCurrentTvInputId();
- method public void requestStreamVolume();
- method public void requestTrackInfoList();
- method public void sendPlaybackCommandRequest(@NonNull String, @Nullable android.os.Bundle);
- method public void setMediaViewEnabled(boolean);
- method public void setVideoBounds(@NonNull android.graphics.Rect);
+ method @CallSuper public void removeBroadcastInfo(int);
+ method @CallSuper public void requestAd(@NonNull android.media.tv.AdRequest);
+ method @CallSuper public void requestBroadcastInfo(@NonNull android.media.tv.BroadcastInfoRequest);
+ method @CallSuper public void requestCurrentChannelLcn();
+ method @CallSuper public void requestCurrentChannelUri();
+ method @CallSuper public void requestCurrentTvInputId();
+ method @CallSuper public void requestStreamVolume();
+ method @CallSuper public void requestTrackInfoList();
+ method @CallSuper public void sendPlaybackCommandRequest(@NonNull String, @Nullable android.os.Bundle);
+ method @CallSuper public void setMediaViewEnabled(boolean);
+ method @CallSuper public void setVideoBounds(@NonNull android.graphics.Rect);
}
public class TvInteractiveAppView extends android.view.ViewGroup {
@@ -26507,14 +26508,6 @@
method public int getUid();
}
- public final class EthernetNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
- ctor public EthernetNetworkSpecifier(@NonNull String);
- method public int describeContents();
- method @Nullable public String getInterfaceName();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.EthernetNetworkSpecifier> CREATOR;
- }
-
public final class Ikev2VpnProfile extends android.net.PlatformVpnProfile {
method @NonNull public java.util.List<java.lang.String> getAllowedAlgorithms();
method public int getMaxMtu();
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 7aef9a6..a32ebe4 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -232,22 +232,6 @@
package android.net {
- public class EthernetManager {
- method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void addInterfaceStateListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.EthernetManager.InterfaceStateListener);
- method public void removeInterfaceStateListener(@NonNull android.net.EthernetManager.InterfaceStateListener);
- method public void setIncludeTestInterfaces(boolean);
- field public static final int ROLE_CLIENT = 1; // 0x1
- field public static final int ROLE_NONE = 0; // 0x0
- field public static final int ROLE_SERVER = 2; // 0x2
- field public static final int STATE_ABSENT = 0; // 0x0
- field public static final int STATE_LINK_DOWN = 1; // 0x1
- field public static final int STATE_LINK_UP = 2; // 0x2
- }
-
- public static interface EthernetManager.InterfaceStateListener {
- method public void onInterfaceStateChanged(@NonNull String, int, int, @Nullable android.net.IpConfiguration);
- }
-
public class LocalSocket implements java.io.Closeable {
ctor public LocalSocket(@NonNull java.io.FileDescriptor);
}
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 5f2dcb3..09d1114 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -34,6 +34,7 @@
field public static final String ALLOCATE_AGGRESSIVE = "android.permission.ALLOCATE_AGGRESSIVE";
field public static final String ALLOW_ANY_CODEC_FOR_PLAYBACK = "android.permission.ALLOW_ANY_CODEC_FOR_PLAYBACK";
field public static final String ALLOW_PLACE_IN_MULTI_PANE_SETTINGS = "android.permission.ALLOW_PLACE_IN_MULTI_PANE_SETTINGS";
+ field public static final String ALLOW_SLIPPERY_TOUCHES = "android.permission.ALLOW_SLIPPERY_TOUCHES";
field public static final String AMBIENT_WALLPAPER = "android.permission.AMBIENT_WALLPAPER";
field public static final String APPROVE_INCIDENT_REPORTS = "android.permission.APPROVE_INCIDENT_REPORTS";
field public static final String ASSOCIATE_COMPANION_DEVICES = "android.permission.ASSOCIATE_COMPANION_DEVICES";
@@ -1700,20 +1701,22 @@
method @NonNull public String getTitle();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.app.cloudsearch.SearchResult> CREATOR;
+ field public static final String EXTRAINFO_ACTION_APP_CARD = "android.app.cloudsearch.ACTION_APP_CARD";
field public static final String EXTRAINFO_ACTION_BUTTON_IMAGE_PREREGISTERING = "android.app.cloudsearch.ACTION_BUTTON_IMAGE";
field public static final String EXTRAINFO_ACTION_BUTTON_TEXT_PREREGISTERING = "android.app.cloudsearch.ACTION_BUTTON_TEXT";
+ field public static final String EXTRAINFO_ACTION_INSTALL_BUTTON = "android.app.cloudsearch.ACTION_INSTALL_BUTTON";
field public static final String EXTRAINFO_APP_BADGES = "android.app.cloudsearch.APP_BADGES";
- field public static final String EXTRAINFO_APP_CARD_ACTION = "android.app.cloudsearch.APP_CARD_ACTION";
field public static final String EXTRAINFO_APP_CONTAINS_ADS_DISCLAIMER = "android.app.cloudsearch.APP_CONTAINS_ADS_DISCLAIMER";
field public static final String EXTRAINFO_APP_CONTAINS_IAP_DISCLAIMER = "android.app.cloudsearch.APP_CONTAINS_IAP_DISCLAIMER";
field public static final String EXTRAINFO_APP_DEVELOPER_NAME = "android.app.cloudsearch.APP_DEVELOPER_NAME";
field public static final String EXTRAINFO_APP_DOMAIN_URL = "android.app.cloudsearch.APP_DOMAIN_URL";
field public static final String EXTRAINFO_APP_IARC = "android.app.cloudsearch.APP_IARC";
field public static final String EXTRAINFO_APP_ICON = "android.app.cloudsearch.APP_ICON";
+ field public static final String EXTRAINFO_APP_INSTALL_COUNT = "android.app.cloudsearch.APP_INSTALL_COUNT";
+ field public static final String EXTRAINFO_APP_PACKAGE_NAME = "android.app.cloudsearch.APP_PACKAGE_NAME";
field public static final String EXTRAINFO_APP_REVIEW_COUNT = "android.app.cloudsearch.APP_REVIEW_COUNT";
field public static final String EXTRAINFO_APP_SIZE_BYTES = "android.app.cloudsearch.APP_SIZE_BYTES";
field public static final String EXTRAINFO_APP_STAR_RATING = "android.app.cloudsearch.APP_STAR_RATING";
- field public static final String EXTRAINFO_INSTALL_BUTTON_ACTION = "android.app.cloudsearch.INSTALL_BUTTON_ACTION";
field public static final String EXTRAINFO_LONG_DESCRIPTION = "android.app.cloudsearch.LONG_DESCRIPTION";
field public static final String EXTRAINFO_SCREENSHOTS = "android.app.cloudsearch.SCREENSHOTS";
field public static final String EXTRAINFO_SHORT_DESCRIPTION = "android.app.cloudsearch.SHORT_DESCRIPTION";
@@ -8523,45 +8526,6 @@
package android.net {
- public class EthernetManager {
- method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}) public void connectNetwork(@NonNull String, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.BiConsumer<android.net.Network,android.net.EthernetNetworkManagementException>);
- method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}) public void disconnectNetwork(@NonNull String, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.BiConsumer<android.net.Network,android.net.EthernetNetworkManagementException>);
- method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public android.net.EthernetManager.TetheredInterfaceRequest requestTetheredInterface(@NonNull java.util.concurrent.Executor, @NonNull android.net.EthernetManager.TetheredInterfaceCallback);
- method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}) public void updateConfiguration(@NonNull String, @NonNull android.net.EthernetNetworkUpdateRequest, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.BiConsumer<android.net.Network,android.net.EthernetNetworkManagementException>);
- }
-
- public static interface EthernetManager.TetheredInterfaceCallback {
- method public void onAvailable(@NonNull String);
- method public void onUnavailable();
- }
-
- public static class EthernetManager.TetheredInterfaceRequest {
- method public void release();
- }
-
- public final class EthernetNetworkManagementException extends java.lang.RuntimeException implements android.os.Parcelable {
- ctor public EthernetNetworkManagementException(@NonNull String);
- method public int describeContents();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.EthernetNetworkManagementException> CREATOR;
- }
-
- public final class EthernetNetworkUpdateRequest implements android.os.Parcelable {
- method public int describeContents();
- method @NonNull public android.net.IpConfiguration getIpConfiguration();
- method @Nullable public android.net.NetworkCapabilities getNetworkCapabilities();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.EthernetNetworkUpdateRequest> CREATOR;
- }
-
- public static final class EthernetNetworkUpdateRequest.Builder {
- ctor public EthernetNetworkUpdateRequest.Builder();
- ctor public EthernetNetworkUpdateRequest.Builder(@NonNull android.net.EthernetNetworkUpdateRequest);
- method @NonNull public android.net.EthernetNetworkUpdateRequest build();
- method @NonNull public android.net.EthernetNetworkUpdateRequest.Builder setIpConfiguration(@NonNull android.net.IpConfiguration);
- method @NonNull public android.net.EthernetNetworkUpdateRequest.Builder setNetworkCapabilities(@Nullable android.net.NetworkCapabilities);
- }
-
public final class MatchAllNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
ctor public MatchAllNetworkSpecifier();
method public int describeContents();
@@ -9032,7 +8996,7 @@
method public void enableVerboseLogging(boolean);
method @NonNull public int[] getChannelsMhzForBand(int);
method @Nullable public android.net.wifi.nl80211.DeviceWiphyCapabilities getDeviceWiphyCapabilities(@NonNull String);
- method public int getMaxNumScanSsids(@NonNull String);
+ method public int getMaxSsidsPerScan(@NonNull String);
method @NonNull public java.util.List<android.net.wifi.nl80211.NativeScanResult> getScanResults(@NonNull String, int);
method @Nullable public android.net.wifi.nl80211.WifiNl80211Manager.TxPacketCounters getTxPacketCounters(@NonNull String);
method public void notifyCountryCodeChanged(@Nullable String);
@@ -10334,6 +10298,7 @@
field public static final String NAMESPACE_MEDIA_NATIVE = "media_native";
field public static final String NAMESPACE_NETD_NATIVE = "netd_native";
field public static final String NAMESPACE_NNAPI_NATIVE = "nnapi_native";
+ field public static final String NAMESPACE_ON_DEVICE_PERSONALIZATION = "on_device_personalization";
field public static final String NAMESPACE_OTA = "ota";
field public static final String NAMESPACE_PACKAGE_MANAGER_SERVICE = "package_manager_service";
field public static final String NAMESPACE_PERMISSIONS = "permissions";
@@ -13376,7 +13341,7 @@
}
public class TelephonyManager {
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void addCarrierPrivilegesListener(int, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CarrierPrivilegesListener);
+ method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void addCarrierPrivilegesListener(int, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CarrierPrivilegesListener);
method @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION}) @WorkerThread public void bootstrapAuthenticationRequest(int, @NonNull android.net.Uri, @NonNull android.telephony.gba.UaSecurityProtocolIdentifier, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.BootstrapAuthenticationCallback);
method @Deprecated @RequiresPermission(android.Manifest.permission.CALL_PHONE) public void call(String, String);
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.PinResult changeIccLockPin(@NonNull String, @NonNull String);
@@ -13476,7 +13441,8 @@
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void notifyOtaEmergencyNumberDbInstalled();
method @RequiresPermission(android.Manifest.permission.REBOOT) public int prepareForUnattendedReboot();
method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean rebootRadio();
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void removeCarrierPrivilegesListener(@NonNull android.telephony.TelephonyManager.CarrierPrivilegesListener);
+ method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerCarrierPrivilegesCallback(int, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CarrierPrivilegesCallback);
+ method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void removeCarrierPrivilegesListener(@NonNull android.telephony.TelephonyManager.CarrierPrivilegesListener);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void reportDefaultNetworkStatus(boolean);
method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.MODIFY_PHONE_STATE}) public void requestCellInfoUpdate(@NonNull android.os.WorkSource, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void requestModemActivityInfo(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.telephony.ModemActivityInfo,android.telephony.TelephonyManager.ModemActivityInfoException>);
@@ -13526,6 +13492,7 @@
method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int[] supplyPukReportResult(String, String);
method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean switchSlots(int[]);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void toggleRadioOnOff();
+ method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterCarrierPrivilegesCallback(@NonNull android.telephony.TelephonyManager.CarrierPrivilegesCallback);
method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void updateOtaEmergencyNumberDbFilePath(@NonNull android.os.ParcelFileDescriptor);
method public void updateServiceLocation();
field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final String ACTION_ANOMALY_REPORTED = "android.telephony.action.ANOMALY_REPORTED";
@@ -13631,8 +13598,13 @@
field public static final int RESULT_SUCCESS = 0; // 0x0
}
- public static interface TelephonyManager.CarrierPrivilegesListener {
- method public void onCarrierPrivilegesChanged(@NonNull java.util.List<java.lang.String>, @NonNull int[]);
+ public static interface TelephonyManager.CarrierPrivilegesCallback {
+ method public void onCarrierPrivilegesChanged(@NonNull java.util.Set<java.lang.String>, @NonNull java.util.Set<java.lang.Integer>);
+ method public default void onCarrierServiceChanged(@Nullable String, int);
+ }
+
+ @Deprecated public static interface TelephonyManager.CarrierPrivilegesListener {
+ method @Deprecated public void onCarrierPrivilegesChanged(@NonNull java.util.List<java.lang.String>, @NonNull int[]);
}
public static class TelephonyManager.ModemActivityInfoException extends java.lang.Exception {
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index b1a4e41..3d0ed20 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -868,6 +868,7 @@
String processName;
@UnsupportedAppUsage
ApplicationInfo appInfo;
+ String sdkSandboxClientAppPackage;
@UnsupportedAppUsage
List<ProviderInfo> providers;
ComponentName instrumentationName;
@@ -1113,9 +1114,9 @@
@Override
public final void bindApplication(String processName, ApplicationInfo appInfo,
- ProviderInfoList providerList, ComponentName instrumentationName,
- ProfilerInfo profilerInfo, Bundle instrumentationArgs,
- IInstrumentationWatcher instrumentationWatcher,
+ String sdkSandboxClientAppPackage, ProviderInfoList providerList,
+ ComponentName instrumentationName, ProfilerInfo profilerInfo,
+ Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection, int debugMode,
boolean enableBinderTracking, boolean trackAllocation,
boolean isRestrictedBackupMode, boolean persistent, Configuration config,
@@ -1155,6 +1156,7 @@
AppBindData data = new AppBindData();
data.processName = processName;
data.appInfo = appInfo;
+ data.sdkSandboxClientAppPackage = sdkSandboxClientAppPackage;
data.providers = providerList.getList();
data.instrumentationName = instrumentationName;
data.instrumentationArgs = instrumentationArgs;
@@ -6536,6 +6538,9 @@
}
data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
+ if (data.sdkSandboxClientAppPackage != null) {
+ data.info.setSdkSandboxStorage(data.sdkSandboxClientAppPackage);
+ }
if (agent != null) {
handleAttachAgent(agent, data.info);
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 7c7c7ef..4829dc0 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -2367,7 +2367,7 @@
null, // no permission for OP_WRITE_MEDIA_AUDIO
Manifest.permission.READ_MEDIA_VIDEO,
null, // no permission for OP_WRITE_MEDIA_VIDEO
- Manifest.permission.READ_MEDIA_IMAGE,
+ Manifest.permission.READ_MEDIA_IMAGES,
null, // no permission for OP_WRITE_MEDIA_IMAGES
null, // no permission for OP_LEGACY_STORAGE
null, // no permission for OP_ACCESS_ACCESSIBILITY
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index a3dd705a..f5eb1f6 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1998,7 +1998,7 @@
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
String instanceName, Handler handler, Executor executor, UserHandle user) {
// Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser and
- // ActivityManagerLocal.bindSupplementalProcessService
+ // ActivityManagerLocal.bindSdkSandboxService
IServiceConnection sd;
if (conn == null) {
throw new IllegalArgumentException("connection is null");
diff --git a/core/java/android/app/IApplicationThread.aidl b/core/java/android/app/IApplicationThread.aidl
index 77657d5..f4fbcce 100644
--- a/core/java/android/app/IApplicationThread.aidl
+++ b/core/java/android/app/IApplicationThread.aidl
@@ -72,6 +72,7 @@
@UnsupportedAppUsage
void scheduleStopService(IBinder token);
void bindApplication(in String packageName, in ApplicationInfo info,
+ in String sdkSandboxClientAppPackage,
in ProviderInfoList providerList, in ComponentName testName,
in ProfilerInfo profilerInfo, in Bundle testArguments,
IInstrumentationWatcher testWatcher, IUiAutomationConnection uiAutomationConnection,
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index d35c5be..deefea8 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -37,6 +37,7 @@
import android.content.res.Resources;
import android.os.Build;
import android.os.Bundle;
+import android.os.Environment;
import android.os.FileUtils;
import android.os.GraphicsEnvironment;
import android.os.Handler;
@@ -411,6 +412,26 @@
}
}
+ /** @hide */
+ void setSdkSandboxStorage(String sdkSandboxClientAppPackage) {
+ int userId = UserHandle.myUserId();
+ mDeviceProtectedDataDirFile = Environment
+ .getDataMiscDeSharedSdkSandboxDirectory(userId, sdkSandboxClientAppPackage)
+ .getAbsoluteFile();
+ mCredentialProtectedDataDirFile = Environment
+ .getDataMiscCeSharedSdkSandboxDirectory(userId, sdkSandboxClientAppPackage)
+ .getAbsoluteFile();
+
+ if ((mApplicationInfo.privateFlags
+ & ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) != 0
+ && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
+ mDataDirFile = mDeviceProtectedDataDirFile;
+ } else {
+ mDataDirFile = mCredentialProtectedDataDirFile;
+ }
+ mDataDir = mDataDirFile.getAbsolutePath();
+ }
+
public static void makePaths(ActivityThread activityThread,
ApplicationInfo aInfo,
List<String> outZipPaths) {
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index c6e36a3..89854bb 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -844,6 +844,24 @@
}
/**
+ * Sets an active {@link android.service.quicksettings.TileService} to listening state
+ *
+ * The {@code componentName}'s package must match the calling package.
+ *
+ * @param componentName the tile to set into listening state
+ * @see android.service.quicksettings.TileService#requestListeningState
+ * @hide
+ */
+ public void requestTileServiceListeningState(@NonNull ComponentName componentName) {
+ Objects.requireNonNull(componentName);
+ try {
+ getService().requestTileServiceListeningState(componentName, mContext.getUserId());
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Request to the user to add a {@link android.service.quicksettings.TileService}
* to the set of current QS tiles.
* <p>
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 58db93c..bf6f634 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -138,8 +138,6 @@
import android.nearby.NearbyFrameworkInitializer;
import android.net.ConnectivityFrameworkInitializer;
import android.net.ConnectivityFrameworkInitializerTiramisu;
-import android.net.EthernetManager;
-import android.net.IEthernetManager;
import android.net.INetworkPolicyManager;
import android.net.IPacProxyManager;
import android.net.IVpnManager;
@@ -789,15 +787,6 @@
return new LowpanManager(ctx.getOuterContext(), service);
}});
- registerService(Context.ETHERNET_SERVICE, EthernetManager.class,
- new CachedServiceFetcher<EthernetManager>() {
- @Override
- public EthernetManager createService(ContextImpl ctx) throws ServiceNotFoundException {
- IBinder b = ServiceManager.getServiceOrThrow(Context.ETHERNET_SERVICE);
- IEthernetManager service = IEthernetManager.Stub.asInterface(b);
- return new EthernetManager(ctx.getOuterContext(), service);
- }});
-
registerService(Context.WIFI_NL80211_SERVICE, WifiNl80211Manager.class,
new CachedServiceFetcher<WifiNl80211Manager>() {
@Override
diff --git a/core/java/android/app/cloudsearch/SearchResult.java b/core/java/android/app/cloudsearch/SearchResult.java
index 1ca01d4..c6583b6 100644
--- a/core/java/android/app/cloudsearch/SearchResult.java
+++ b/core/java/android/app/cloudsearch/SearchResult.java
@@ -71,8 +71,10 @@
EXTRAINFO_APP_BADGES,
EXTRAINFO_ACTION_BUTTON_TEXT_PREREGISTERING,
EXTRAINFO_ACTION_BUTTON_IMAGE_PREREGISTERING,
- EXTRAINFO_APP_CARD_ACTION,
- EXTRAINFO_INSTALL_BUTTON_ACTION,
+ EXTRAINFO_ACTION_APP_CARD,
+ EXTRAINFO_ACTION_INSTALL_BUTTON,
+ EXTRAINFO_APP_PACKAGE_NAME,
+ EXTRAINFO_APP_INSTALL_COUNT,
EXTRAINFO_WEB_URL,
EXTRAINFO_WEB_ICON})
public @interface SearchResultExtraInfoKey {}
@@ -123,12 +125,18 @@
"android.app.cloudsearch.ACTION_BUTTON_IMAGE";
/** Intent for tapping the app card, PendingIntent expected. */
@SuppressLint("IntentName")
- public static final String EXTRAINFO_APP_CARD_ACTION =
- "android.app.cloudsearch.APP_CARD_ACTION";
+ public static final String EXTRAINFO_ACTION_APP_CARD =
+ "android.app.cloudsearch.ACTION_APP_CARD";
/** Intent for tapping the install button, PendingIntent expected. */
@SuppressLint("IntentName")
- public static final String EXTRAINFO_INSTALL_BUTTON_ACTION =
- "android.app.cloudsearch.INSTALL_BUTTON_ACTION";
+ public static final String EXTRAINFO_ACTION_INSTALL_BUTTON =
+ "android.app.cloudsearch.ACTION_INSTALL_BUTTON";
+ /** App's package name, String value expected. */
+ public static final String EXTRAINFO_APP_PACKAGE_NAME =
+ "android.app.cloudsearch.APP_PACKAGE_NAME";
+ /** App's install count, double value expected. */
+ public static final String EXTRAINFO_APP_INSTALL_COUNT =
+ "android.app.cloudsearch.APP_INSTALL_COUNT";
/** Web content's URL, String value expected. */
public static final String EXTRAINFO_WEB_URL = "android.app.cloudsearch.WEB_URL";
/** Web content's domain icon, android.graphics.drawable.Icon expected. */
diff --git a/core/java/android/content/pm/Signature.java b/core/java/android/content/pm/Signature.java
index 3f5c5d2..d94b0d8 100644
--- a/core/java/android/content/pm/Signature.java
+++ b/core/java/android/content/pm/Signature.java
@@ -312,7 +312,7 @@
* @hide
*/
public static boolean areExactMatch(Signature[] a, Signature[] b) {
- return (a.length == b.length) && ArrayUtils.containsAll(a, b)
+ return (ArrayUtils.size(a) == ArrayUtils.size(b)) && ArrayUtils.containsAll(a, b)
&& ArrayUtils.containsAll(b, a);
}
@@ -387,4 +387,4 @@
return sPrime;
}
-}
\ No newline at end of file
+}
diff --git a/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java b/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java
index 8b86a16..a65b681 100644
--- a/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java
+++ b/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java
@@ -379,6 +379,30 @@
}
/**
+ * Computes the maxSdkVersion. If the package is not compatible with this platform, populates
+ * {@code outError[0]} with an error message.
+ * <p>
+ * {@code maxVers} is compared against {@code platformSdkVersion}. If {@code maxVers} is less
+ * than the {@code platformSdkVersion} then populates {@code outError[0]} with an error message.
+ * Otherwise, it returns {@code maxVers} unmodified.
+ *
+ * @param maxVers maxSdkVersion number, if specified in the application manifest, or {@code
+ * Integer.MAX_VALUE} otherwise
+ * @param platformSdkVersion platform SDK version number, typically Build.VERSION.SDK_INT
+ * @return the maxSdkVersion that was recognised or an error if the condition is not satisfied
+ */
+ public static ParseResult<Integer> computeMaxSdkVersion(@IntRange(from = 0) int maxVers,
+ @IntRange(from = 1) int platformSdkVersion, @NonNull ParseInput input) {
+ if (platformSdkVersion > maxVers) {
+ return input.error(PackageManager.INSTALL_FAILED_NEWER_SDK,
+ "Requires max SDK version " + maxVers + " but is "
+ + platformSdkVersion);
+ } else {
+ return input.success(maxVers);
+ }
+ }
+
+ /**
* Matches a given {@code targetCode} against a set of release codeNames. Target codes can
* either be of the form {@code [codename]}" (e.g {@code "Q"}) or of the form {@code
* [codename].[fingerprint]} (e.g {@code "Q.cafebc561"}).
diff --git a/core/java/android/inputmethodservice/InkWindow.java b/core/java/android/inputmethodservice/InkWindow.java
index 499634a..8289c26 100644
--- a/core/java/android/inputmethodservice/InkWindow.java
+++ b/core/java/android/inputmethodservice/InkWindow.java
@@ -27,6 +27,8 @@
import android.os.IBinder;
import android.util.Slog;
import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
import android.view.WindowManager;
import com.android.internal.policy.PhoneWindow;
@@ -40,6 +42,9 @@
private final WindowManager mWindowManager;
private boolean mIsViewAdded;
+ private View mInkView;
+ private InkVisibilityListener mInkViewVisibilityListener;
+ private ViewTreeObserver.OnGlobalLayoutListener mGlobalLayoutListener;
public InkWindow(@NonNull Context context) {
super(context);
@@ -102,4 +107,77 @@
lp.token = token;
setAttributes(lp);
}
+
+ @Override
+ public void addContentView(View view, ViewGroup.LayoutParams params) {
+ if (mInkView == null) {
+ mInkView = view;
+ } else if (mInkView != view) {
+ throw new IllegalStateException("Only one Child Inking view is permitted.");
+ }
+ super.addContentView(view, params);
+ initInkViewVisibilityListener();
+ }
+
+ @Override
+ public void setContentView(View view, ViewGroup.LayoutParams params) {
+ mInkView = view;
+ super.setContentView(view, params);
+ initInkViewVisibilityListener();
+ }
+
+ @Override
+ public void setContentView(View view) {
+ mInkView = view;
+ super.setContentView(view);
+ initInkViewVisibilityListener();
+ }
+
+ @Override
+ public void clearContentView() {
+ if (mGlobalLayoutListener != null && mInkView != null) {
+ mInkView.getViewTreeObserver().removeOnGlobalLayoutListener(mGlobalLayoutListener);
+ }
+ mGlobalLayoutListener = null;
+ mInkView = null;
+ super.clearContentView();
+ }
+
+ /**
+ * Listener used by InkWindow to time the dispatching of {@link MotionEvent}s to Ink view, once
+ * it is visible to user.
+ */
+ interface InkVisibilityListener {
+ void onInkViewVisible();
+ }
+
+ void setInkViewVisibilityListener(InkVisibilityListener listener) {
+ mInkViewVisibilityListener = listener;
+ initInkViewVisibilityListener();
+ }
+
+ void initInkViewVisibilityListener() {
+ if (mInkView == null || mInkViewVisibilityListener == null
+ || mGlobalLayoutListener != null) {
+ return;
+ }
+ mGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
+ @Override
+ public void onGlobalLayout() {
+ if (mInkView.isVisibleToUser()) {
+ if (mInkViewVisibilityListener != null) {
+ mInkViewVisibilityListener.onInkViewVisible();
+ }
+ mInkView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+ mGlobalLayoutListener = null;
+ }
+ }
+ };
+ mInkView.getViewTreeObserver().addOnGlobalLayoutListener(mGlobalLayoutListener);
+ }
+
+ boolean isInkViewVisible() {
+ return getDecorView().getVisibility() == View.VISIBLE
+ && mInkView != null && mInkView.isVisibleToUser();
+ }
}
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 656aea1..b46bb32 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -143,6 +143,7 @@
import com.android.internal.inputmethod.InputMethodNavButtonFlags;
import com.android.internal.inputmethod.InputMethodPrivilegedOperations;
import com.android.internal.inputmethod.InputMethodPrivilegedOperationsRegistry;
+import com.android.internal.util.RingBuffer;
import com.android.internal.view.IInlineSuggestionsRequestCallback;
import com.android.internal.view.IInputContext;
import com.android.internal.view.InlineSuggestionsRequestInfo;
@@ -334,6 +335,17 @@
"persist.sys.ime.can_render_gestural_nav_buttons";
/**
+ * Number of {@link MotionEvent} to buffer if IME is not ready with Ink view.
+ * This number may be configured eventually based on device's touch sampling frequency.
+ */
+ private static final int MAX_EVENTS_BUFFER = 500;
+
+ /**
+ * A circular buffer of size MAX_EVENTS_BUFFER in case IME is taking too long to add ink view.
+ **/
+ private RingBuffer<MotionEvent> mPendingEvents;
+
+ /**
* Returns whether {@link InputMethodService} is responsible for rendering the back button and
* the IME switcher button or not when the gestural navigation is enabled.
*
@@ -954,7 +966,8 @@
mInkWindow.show();
// deliver previous @param stylusEvents
- stylusEvents.forEach(mInkWindow.getDecorView()::dispatchTouchEvent);
+ stylusEvents.forEach(InputMethodService.this::onStylusHandwritingMotionEvent);
+
// create receiver for channel
mHandwritingEventReceiver = new SimpleBatchedInputEventReceiver(
channel,
@@ -963,11 +976,11 @@
if (!(event instanceof MotionEvent)) {
return false;
}
- return mInkWindow.getDecorView().dispatchTouchEvent((MotionEvent) event);
+ onStylusHandwritingMotionEvent((MotionEvent) event);
+ return true;
});
}
-
/**
* {@inheritDoc}
* @hide
@@ -2357,7 +2370,8 @@
*
* If the IME supports handwriting for the current input, it should return {@code true},
* ensure its inking views are attached to the {@link #getStylusHandwritingWindow()}, and handle
- * stylus input received on the ink window via {@link #getCurrentInputConnection()}.
+ * stylus input received from {@link #onStylusHandwritingMotionEvent(MotionEvent)} on the
+ * {@link #getStylusHandwritingWindow()} via {@link #getCurrentInputConnection()}.
* @return {@code true} if IME can honor the request, {@code false} if IME cannot at this time.
*/
public boolean onStartStylusHandwriting() {
@@ -2366,6 +2380,33 @@
}
/**
+ * Called after {@link #onStartStylusHandwriting()} returns {@code true} for every Stylus
+ * {@link MotionEvent}.
+ * By default, this method forwards all {@link MotionEvent}s to the
+ * {@link #getStylusHandwritingWindow()} once its visible, however IME can override it to
+ * receive them sooner.
+ * @param motionEvent {@link MotionEvent} from stylus.
+ */
+ public void onStylusHandwritingMotionEvent(@NonNull MotionEvent motionEvent) {
+ if (mInkWindow.isInkViewVisible()) {
+ mInkWindow.getDecorView().dispatchTouchEvent(motionEvent);
+ } else {
+ if (mPendingEvents == null) {
+ mPendingEvents = new RingBuffer(MotionEvent.class, MAX_EVENTS_BUFFER);
+ }
+ mPendingEvents.append(motionEvent);
+ mInkWindow.setInkViewVisibilityListener(() -> {
+ if (mPendingEvents != null && !mPendingEvents.isEmpty()) {
+ for (MotionEvent event : mPendingEvents.toArray()) {
+ mInkWindow.getDecorView().dispatchTouchEvent(event);
+ }
+ mPendingEvents.clear();
+ }
+ });
+ }
+ }
+
+ /**
* Called when the current stylus handwriting session was finished (either by the system or
* via {@link #finishStylusHandwriting()}.
*
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index de1dc80..5f9fdbf 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -5655,6 +5655,7 @@
.setMaxStatsAgeMs(0)
.includePowerModels()
.includeProcessStateData()
+ .includeVirtualUids()
.build());
stats.dump(pw, prefix);
diff --git a/core/java/android/os/BatteryUsageStatsQuery.java b/core/java/android/os/BatteryUsageStatsQuery.java
index 37bd51b..b3f4d98 100644
--- a/core/java/android/os/BatteryUsageStatsQuery.java
+++ b/core/java/android/os/BatteryUsageStatsQuery.java
@@ -42,6 +42,7 @@
FLAG_BATTERY_USAGE_STATS_POWER_PROFILE_MODEL,
FLAG_BATTERY_USAGE_STATS_INCLUDE_HISTORY,
FLAG_BATTERY_USAGE_STATS_INCLUDE_PROCESS_STATE_DATA,
+ FLAG_BATTERY_USAGE_STATS_INCLUDE_VIRTUAL_UIDS,
})
@Retention(RetentionPolicy.SOURCE)
public @interface BatteryUsageStatsFlags {}
@@ -69,6 +70,8 @@
public static final int FLAG_BATTERY_USAGE_STATS_INCLUDE_PROCESS_STATE_DATA = 0x0008;
+ public static final int FLAG_BATTERY_USAGE_STATS_INCLUDE_VIRTUAL_UIDS = 0x0010;
+
private static final long DEFAULT_MAX_STATS_AGE_MS = 5 * 60 * 1000;
private final int mFlags;
@@ -271,6 +274,15 @@
}
/**
+ * Requests to return attribution data for virtual UIDs such as
+ * {@link Process#SDK_SANDBOX_VIRTUAL_UID}.
+ */
+ public Builder includeVirtualUids() {
+ mFlags |= BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_VIRTUAL_UIDS;
+ return this;
+ }
+
+ /**
* Requests to aggregate stored snapshots between the two supplied timestamps
* @param fromTimestamp Exclusive starting timestamp, as per System.currentTimeMillis()
* @param toTimestamp Inclusive ending timestamp, as per System.currentTimeMillis()
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 0a7a407..ecdc803 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -478,10 +478,20 @@
}
/** {@hide} */
+ public static File getDataMiscCeSharedSdkSandboxDirectory(int userId, String packageName) {
+ return buildPath(getDataMiscCeDirectory(userId), "sdksandbox", packageName, "shared");
+ }
+
+ /** {@hide} */
public static File getDataMiscDeDirectory(int userId) {
return buildPath(getDataDirectory(), "misc_de", String.valueOf(userId));
}
+ /** {@hide} */
+ public static File getDataMiscDeSharedSdkSandboxDirectory(int userId, String packageName) {
+ return buildPath(getDataMiscDeDirectory(userId), "sdksandbox", packageName, "shared");
+ }
+
private static File getDataProfilesDeDirectory(int userId) {
return buildPath(getDataDirectory(), "misc", "profiles", "cur", String.valueOf(userId));
}
diff --git a/core/java/android/os/UidBatteryConsumer.java b/core/java/android/os/UidBatteryConsumer.java
index a1ff923..77d1498 100644
--- a/core/java/android/os/UidBatteryConsumer.java
+++ b/core/java/android/os/UidBatteryConsumer.java
@@ -202,20 +202,24 @@
private static final String PACKAGE_NAME_UNINITIALIZED = "";
private final BatteryStats.Uid mBatteryStatsUid;
private final int mUid;
+ private final boolean mIsVirtualUid;
private String mPackageWithHighestDrain = PACKAGE_NAME_UNINITIALIZED;
private boolean mExcludeFromBatteryUsageStats;
public Builder(BatteryConsumerData data, @NonNull BatteryStats.Uid batteryStatsUid) {
- super(data, CONSUMER_TYPE_UID);
- mBatteryStatsUid = batteryStatsUid;
- mUid = batteryStatsUid.getUid();
- data.putLong(COLUMN_INDEX_UID, mUid);
+ this(data, batteryStatsUid, batteryStatsUid.getUid());
}
public Builder(BatteryConsumerData data, int uid) {
+ this(data, null, uid);
+ }
+
+ private Builder(BatteryConsumerData data, @Nullable BatteryStats.Uid batteryStatsUid,
+ int uid) {
super(data, CONSUMER_TYPE_UID);
- mBatteryStatsUid = null;
+ mBatteryStatsUid = batteryStatsUid;
mUid = uid;
+ mIsVirtualUid = mUid == Process.SDK_SANDBOX_VIRTUAL_UID;
data.putLong(COLUMN_INDEX_UID, mUid);
}
@@ -232,6 +236,10 @@
return mUid;
}
+ public boolean isVirtualUid() {
+ return mIsVirtualUid;
+ }
+
/**
* Sets the name of the package owned by this UID that consumed the highest amount
* of power since BatteryStats reset.
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 052e4d0..6982b3a 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -322,6 +322,13 @@
public static final String NAMESPACE_NNAPI_NATIVE = "nnapi_native";
/**
+ * Namespace for all OnDevicePersonalization related feature.
+ * @hide
+ */
+ @SystemApi
+ public static final String NAMESPACE_ON_DEVICE_PERSONALIZATION = "on_device_personalization";
+
+ /**
* Namespace for features related to the Package Manager Service.
*
* @hide
diff --git a/core/java/android/service/quicksettings/TileService.java b/core/java/android/service/quicksettings/TileService.java
index b507328..0829d28 100644
--- a/core/java/android/service/quicksettings/TileService.java
+++ b/core/java/android/service/quicksettings/TileService.java
@@ -15,18 +15,19 @@
*/
package android.service.quicksettings;
-import android.Manifest;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.app.Dialog;
import android.app.Service;
+import android.app.StatusBarManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.drawable.Icon;
+import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -147,13 +148,6 @@
"android.service.quicksettings.TOGGLEABLE_TILE";
/**
- * Used to notify SysUI that Listening has be requested.
- * @hide
- */
- public static final String ACTION_REQUEST_LISTENING =
- "android.service.quicksettings.action.REQUEST_LISTENING";
-
- /**
* @hide
*/
public static final String EXTRA_SERVICE = "service";
@@ -482,14 +476,24 @@
*
* This method is only applicable to tiles that have {@link #META_DATA_ACTIVE_TILE} defined
* as true on their TileService Manifest declaration, and will do nothing otherwise.
+ *
+ * For apps targeting {@link Build.VERSION_CODES#TIRAMISU} or later, this call may throw
+ * the following exceptions if the request is not valid:
+ * <ul>
+ * <li> {@link NullPointerException} if {@code component} is {@code null}.</li>
+ * <li> {@link SecurityException} if the package of {@code component} does not match
+ * the calling package or if the calling user cannot act on behalf of the user from the
+ * {@code context}.</li>
+ * <li> {@link IllegalArgumentException} if the user of the {@code context} is not the
+ * current user.</li>
+ * </ul>
*/
public static final void requestListeningState(Context context, ComponentName component) {
- final ComponentName sysuiComponent = ComponentName.unflattenFromString(
- context.getResources().getString(
- com.android.internal.R.string.config_systemUIServiceComponent));
- Intent intent = new Intent(ACTION_REQUEST_LISTENING);
- intent.putExtra(Intent.EXTRA_COMPONENT_NAME, component);
- intent.setPackage(sysuiComponent.getPackageName());
- context.sendBroadcast(intent, Manifest.permission.BIND_QUICK_SETTINGS_TILE);
+ StatusBarManager sbm = context.getSystemService(StatusBarManager.class);
+ if (sbm == null) {
+ Log.e(TAG, "No StatusBarManager service found");
+ return;
+ }
+ sbm.requestTileServiceListeningState(component);
}
}
diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java
index c1fcd66..f844592 100644
--- a/core/java/android/telephony/TelephonyRegistryManager.java
+++ b/core/java/android/telephony/TelephonyRegistryManager.java
@@ -27,6 +27,7 @@
import android.os.Build;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.service.carrier.CarrierService;
import android.telephony.Annotation.CallState;
import android.telephony.Annotation.DataActivityType;
import android.telephony.Annotation.DisconnectCauses;
@@ -36,6 +37,7 @@
import android.telephony.Annotation.RadioPowerState;
import android.telephony.Annotation.SimActivationState;
import android.telephony.Annotation.SrvccState;
+import android.telephony.TelephonyManager.CarrierPrivilegesCallback;
import android.telephony.TelephonyManager.CarrierPrivilegesListener;
import android.telephony.emergency.EmergencyNumber;
import android.telephony.ims.ImsReasonInfo;
@@ -44,17 +46,19 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.listeners.ListenerExecutor;
-import com.android.internal.telephony.ICarrierPrivilegesListener;
+import com.android.internal.telephony.ICarrierPrivilegesCallback;
import com.android.internal.telephony.IOnSubscriptionsChangedListener;
import com.android.internal.telephony.ITelephonyRegistry;
import java.lang.ref.WeakReference;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.concurrent.Executor;
+import java.util.stream.Collectors;
/**
* A centralized place to notify telephony related status changes, e.g, {@link ServiceState} update
@@ -1260,34 +1264,78 @@
pkgName, attributionTag, callback, new int[0], notifyNow);
}
- private static class CarrierPrivilegesListenerWrapper extends ICarrierPrivilegesListener.Stub
+ // TODO(b/216549778): Remove listener logic once all clients switch to CarrierPrivilegesCallback
+ private static class CarrierPrivilegesCallbackWrapper extends ICarrierPrivilegesCallback.Stub
implements ListenerExecutor {
- private final WeakReference<CarrierPrivilegesListener> mListener;
- private final Executor mExecutor;
+ // Either mListener or mCallback may be null, never both
+ @Nullable private final WeakReference<CarrierPrivilegesListener> mListener;
+ @Nullable private final WeakReference<CarrierPrivilegesCallback> mCallback;
+ @NonNull private final Executor mExecutor;
- CarrierPrivilegesListenerWrapper(CarrierPrivilegesListener listener, Executor executor) {
+ CarrierPrivilegesCallbackWrapper(
+ @NonNull CarrierPrivilegesCallback callback, @NonNull Executor executor) {
+ mListener = null;
+ mCallback = new WeakReference<>(callback);
+ mExecutor = executor;
+ }
+
+ CarrierPrivilegesCallbackWrapper(
+ @NonNull CarrierPrivilegesListener listener, @NonNull Executor executor) {
mListener = new WeakReference<>(listener);
+ mCallback = null;
mExecutor = executor;
}
@Override
public void onCarrierPrivilegesChanged(
- List<String> privilegedPackageNames, int[] privilegedUids) {
- Binder.withCleanCallingIdentity(
- () ->
- executeSafely(
- mExecutor,
- mListener::get,
- cpl ->
- cpl.onCarrierPrivilegesChanged(
- privilegedPackageNames, privilegedUids)));
+ @NonNull List<String> privilegedPackageNames, @NonNull int[] privilegedUids) {
+ if (mListener != null) {
+ Binder.withCleanCallingIdentity(
+ () ->
+ executeSafely(
+ mExecutor,
+ mListener::get,
+ cpl ->
+ cpl.onCarrierPrivilegesChanged(
+ privilegedPackageNames, privilegedUids)));
+ }
+
+ if (mCallback != null) {
+ // AIDL interface does not support Set, keep the List/Array and translate them here
+ Set<String> privilegedPkgNamesSet = Set.copyOf(privilegedPackageNames);
+ Set<Integer> privilegedUidsSet = Arrays.stream(privilegedUids).boxed().collect(
+ Collectors.toSet());
+ Binder.withCleanCallingIdentity(
+ () ->
+ executeSafely(
+ mExecutor,
+ mCallback::get,
+ cpc ->
+ cpc.onCarrierPrivilegesChanged(
+ privilegedPkgNamesSet, privilegedUidsSet)));
+ }
+ }
+
+ @Override
+ public void onCarrierServiceChanged(@Nullable String packageName, int uid) {
+ if (mCallback != null) {
+ Binder.withCleanCallingIdentity(
+ () ->
+ executeSafely(
+ mExecutor,
+ mCallback::get,
+ cpc -> cpc.onCarrierServiceChanged(packageName, uid)));
+ }
}
}
- @GuardedBy("sCarrierPrivilegeListeners")
- private static final WeakHashMap<
- CarrierPrivilegesListener, WeakReference<CarrierPrivilegesListenerWrapper>>
- sCarrierPrivilegeListeners = new WeakHashMap<>();
+ // TODO(b/216549778): Change the map key to CarrierPrivilegesCallback once all clients switch to
+ // CarrierPrivilegesCallback. Before that, the key is either CarrierPrivilegesCallback or
+ // CarrierPrivilegesListener, no logic actually depends on the type.
+ @NonNull
+ @GuardedBy("sCarrierPrivilegeCallbacks")
+ private static final WeakHashMap<Object, WeakReference<CarrierPrivilegesCallbackWrapper>>
+ sCarrierPrivilegeCallbacks = new WeakHashMap<>();
/**
* Registers a {@link CarrierPrivilegesListener} on the given {@code logicalSlotIndex} to
@@ -1297,7 +1345,11 @@
* @param logicalSlotIndex The SIM slot to listen on
* @param executor The executor where {@code listener} will be invoked
* @param listener The callback to register
+ *
+ * @deprecated Use {@link #addCarrierPrivilegesCallback} instead. This API will be removed
+ * prior to API finalization.
*/
+ @Deprecated
public void addCarrierPrivilegesListener(
int logicalSlotIndex,
@NonNull @CallbackExecutor Executor executor,
@@ -1305,18 +1357,18 @@
if (listener == null || executor == null) {
throw new IllegalArgumentException("listener and executor must be non-null");
}
- synchronized (sCarrierPrivilegeListeners) {
- WeakReference<CarrierPrivilegesListenerWrapper> existing =
- sCarrierPrivilegeListeners.get(listener);
+ synchronized (sCarrierPrivilegeCallbacks) {
+ WeakReference<CarrierPrivilegesCallbackWrapper> existing =
+ sCarrierPrivilegeCallbacks.get(listener);
if (existing != null && existing.get() != null) {
Log.d(TAG, "addCarrierPrivilegesListener: listener already registered");
return;
}
- CarrierPrivilegesListenerWrapper wrapper =
- new CarrierPrivilegesListenerWrapper(listener, executor);
- sCarrierPrivilegeListeners.put(listener, new WeakReference<>(wrapper));
+ CarrierPrivilegesCallbackWrapper wrapper =
+ new CarrierPrivilegesCallbackWrapper(listener, executor);
+ sCarrierPrivilegeCallbacks.put(listener, new WeakReference<>(wrapper));
try {
- sRegistry.addCarrierPrivilegesListener(
+ sRegistry.addCarrierPrivilegesCallback(
logicalSlotIndex,
wrapper,
mContext.getOpPackageName(),
@@ -1331,19 +1383,84 @@
* Unregisters a {@link CarrierPrivilegesListener}.
*
* @param listener The callback to unregister
+ *
+ * @deprecated Use {@link #removeCarrierPrivilegesCallback} instead. The callback will prior
+ * to API finalization.
*/
+ @Deprecated
public void removeCarrierPrivilegesListener(@NonNull CarrierPrivilegesListener listener) {
if (listener == null) {
throw new IllegalArgumentException("listener must be non-null");
}
- synchronized (sCarrierPrivilegeListeners) {
- WeakReference<CarrierPrivilegesListenerWrapper> ref =
- sCarrierPrivilegeListeners.remove(listener);
+ synchronized (sCarrierPrivilegeCallbacks) {
+ WeakReference<CarrierPrivilegesCallbackWrapper> ref =
+ sCarrierPrivilegeCallbacks.remove(listener);
if (ref == null) return;
- CarrierPrivilegesListenerWrapper wrapper = ref.get();
+ CarrierPrivilegesCallbackWrapper wrapper = ref.get();
if (wrapper == null) return;
try {
- sRegistry.removeCarrierPrivilegesListener(wrapper, mContext.getOpPackageName());
+ sRegistry.removeCarrierPrivilegesCallback(wrapper, mContext.getOpPackageName());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ }
+
+ /**
+ * Registers a {@link CarrierPrivilegesCallback} on the given {@code logicalSlotIndex} to
+ * receive callbacks when the set of packages with carrier privileges changes. The callback will
+ * immediately be called with the latest state.
+ *
+ * @param logicalSlotIndex The SIM slot to listen on
+ * @param executor The executor where {@code listener} will be invoked
+ * @param callback The callback to register
+ */
+ public void addCarrierPrivilegesCallback(
+ int logicalSlotIndex,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull CarrierPrivilegesCallback callback) {
+ if (callback == null || executor == null) {
+ throw new IllegalArgumentException("callback and executor must be non-null");
+ }
+ synchronized (sCarrierPrivilegeCallbacks) {
+ WeakReference<CarrierPrivilegesCallbackWrapper> existing =
+ sCarrierPrivilegeCallbacks.get(callback);
+ if (existing != null && existing.get() != null) {
+ Log.d(TAG, "addCarrierPrivilegesCallback: callback already registered");
+ return;
+ }
+ CarrierPrivilegesCallbackWrapper wrapper =
+ new CarrierPrivilegesCallbackWrapper(callback, executor);
+ sCarrierPrivilegeCallbacks.put(callback, new WeakReference<>(wrapper));
+ try {
+ sRegistry.addCarrierPrivilegesCallback(
+ logicalSlotIndex,
+ wrapper,
+ mContext.getOpPackageName(),
+ mContext.getAttributionTag());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ }
+
+ /**
+ * Unregisters a {@link CarrierPrivilegesCallback}.
+ *
+ * @param callback The callback to unregister
+ */
+ public void removeCarrierPrivilegesCallback(@NonNull CarrierPrivilegesCallback callback) {
+ if (callback == null) {
+ throw new IllegalArgumentException("listener must be non-null");
+ }
+ synchronized (sCarrierPrivilegeCallbacks) {
+ WeakReference<CarrierPrivilegesCallbackWrapper> ref =
+ sCarrierPrivilegeCallbacks.remove(callback);
+ if (ref == null) return;
+ CarrierPrivilegesCallbackWrapper wrapper = ref.get();
+ if (wrapper == null) return;
+ try {
+ sRegistry.removeCarrierPrivilegesCallback(wrapper, mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1359,15 +1476,33 @@
*/
public void notifyCarrierPrivilegesChanged(
int logicalSlotIndex,
- @NonNull List<String> privilegedPackageNames,
- @NonNull int[] privilegedUids) {
+ @NonNull Set<String> privilegedPackageNames,
+ @NonNull Set<Integer> privilegedUids) {
if (privilegedPackageNames == null || privilegedUids == null) {
throw new IllegalArgumentException(
"privilegedPackageNames and privilegedUids must be non-null");
}
try {
- sRegistry.notifyCarrierPrivilegesChanged(
- logicalSlotIndex, privilegedPackageNames, privilegedUids);
+ // AIDL doesn't support Set yet. Convert Set to List/Array
+ List<String> pkgList = List.copyOf(privilegedPackageNames);
+ int[] uids = privilegedUids.stream().mapToInt(Number::intValue).toArray();
+ sRegistry.notifyCarrierPrivilegesChanged(logicalSlotIndex, pkgList, uids);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Notify listeners that the {@link CarrierService} for current user has changed.
+ *
+ * @param logicalSlotIndex the SIM slot the change occurred on
+ * @param packageName the package name of the changed {@link CarrierService}
+ * @param uid the UID of the changed {@link CarrierService}
+ */
+ public void notifyCarrierServiceChanged(int logicalSlotIndex, @Nullable String packageName,
+ int uid) {
+ try {
+ sRegistry.notifyCarrierServiceChanged(logicalSlotIndex, packageName, uid);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 18e65c9..e79bdce 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -873,6 +873,7 @@
mDensity = context.getResources().getDisplayMetrics().densityDpi;
mNoncompatDensity = context.getResources().getDisplayMetrics().noncompatDensityDpi;
mFallbackEventHandler = new PhoneFallbackEventHandler(context);
+ // TODO(b/222696368): remove getSfInstance usage and use vsyncId for transactions
mChoreographer = useSfChoreographer
? Choreographer.getSfInstance() : Choreographer.getInstance();
mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
@@ -1777,6 +1778,7 @@
updateInternalDisplay(displayId, mView.getResources());
mImeFocusController.onMovedToDisplay();
mAttachInfo.mDisplayState = mDisplay.getState();
+ mDisplayInstallOrientation = mDisplay.getInstallOrientation();
// Internal state updated, now notify the view hierarchy.
mView.dispatchMovedToDisplay(mDisplay, config);
}
@@ -3448,6 +3450,12 @@
mReportNextDraw = false;
pendingDrawFinished();
}
+
+ // Make sure the consumer is not waiting if the view root was just made invisible.
+ if (mBLASTDrawConsumer != null) {
+ mBLASTDrawConsumer.accept(null);
+ mBLASTDrawConsumer = null;
+ }
}
}
diff --git a/core/java/com/android/internal/graphics/SfVsyncFrameCallbackProvider.java b/core/java/com/android/internal/graphics/SfVsyncFrameCallbackProvider.java
index 45555bf..dbbe4b9 100644
--- a/core/java/com/android/internal/graphics/SfVsyncFrameCallbackProvider.java
+++ b/core/java/com/android/internal/graphics/SfVsyncFrameCallbackProvider.java
@@ -24,6 +24,7 @@
*
* @hide
*/
+// TODO(b/222698397): remove getSfInstance/this class usage and use vsyncId for transactions
public final class SfVsyncFrameCallbackProvider implements AnimationFrameCallbackProvider {
private final Choreographer mChoreographer;
diff --git a/core/java/com/android/internal/os/AudioPowerCalculator.java b/core/java/com/android/internal/os/AudioPowerCalculator.java
index f9310b0..ebf0ca2 100644
--- a/core/java/com/android/internal/os/AudioPowerCalculator.java
+++ b/core/java/com/android/internal/os/AudioPowerCalculator.java
@@ -78,7 +78,9 @@
final double powerMah = mPowerEstimator.calculatePower(durationMs);
app.setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_AUDIO, durationMs)
.setConsumedPower(BatteryConsumer.POWER_COMPONENT_AUDIO, powerMah);
- total.durationMs += durationMs;
- total.powerMah += powerMah;
+ if (!app.isVirtualUid()) {
+ total.durationMs += durationMs;
+ total.powerMah += powerMah;
+ }
}
}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 70b9639..5253956 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -546,9 +546,9 @@
final LongArrayMultiStateCounter onBatteryScreenOffCounter =
u.getProcStateScreenOffTimeCounter().getCounter();
- if (uid == parentUid) {
- mKernelSingleUidTimeReader.addDelta(uid, onBatteryCounter, timestampMs);
- mKernelSingleUidTimeReader.addDelta(uid, onBatteryScreenOffCounter,
+ if (uid == parentUid || Process.isSdkSandboxUid(uid)) {
+ mKernelSingleUidTimeReader.addDelta(parentUid, onBatteryCounter, timestampMs);
+ mKernelSingleUidTimeReader.addDelta(parentUid, onBatteryScreenOffCounter,
timestampMs);
} else {
Uid.ChildUid childUid = u.getChildUid(uid);
@@ -4560,7 +4560,10 @@
mIsolatedUidRefCounts.put(uid, refCount + 1);
}
- public int mapUid(int uid) {
+ private int mapUid(int uid) {
+ if (Process.isSdkSandboxUid(uid)) {
+ return Process.getAppUidForSdkSandboxUid(uid);
+ }
int isolated = mIsolatedUids.get(uid, -1);
return isolated > 0 ? isolated : uid;
}
@@ -4656,16 +4659,18 @@
long elapsedRealtimeMs, long uptimeMs) {
int parentUid = mapUid(uid);
if (uid != parentUid) {
- // Isolated UIDs process state is already rolled up into parent, so no need to track
- // Otherwise the parent's process state will get downgraded incorrectly
- return;
+ if (Process.isIsolated(uid)) {
+ // Isolated UIDs process state is already rolled up into parent, so no need to track
+ // Otherwise the parent's process state will get downgraded incorrectly
+ return;
+ }
}
// TODO(b/155216561): It is possible for isolated uids to be in a higher
// state than its parent uid. We should track the highest state within the union of host
// and isolated uids rather than only the parent uid.
FrameworkStatsLog.write(FrameworkStatsLog.UID_PROCESS_STATE_CHANGED, uid,
ActivityManager.processStateAmToProto(state));
- getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ getUidStatsLocked(parentUid, elapsedRealtimeMs, uptimeMs)
.updateUidProcessStateLocked(state, elapsedRealtimeMs, uptimeMs);
}
@@ -15970,6 +15975,9 @@
public Uid getUidStatsLocked(int uid, long elapsedRealtimeMs, long uptimeMs) {
Uid u = mUidStats.get(uid);
if (u == null) {
+ if (Process.isSdkSandboxUid(uid)) {
+ Log.wtf(TAG, "Tracking an SDK Sandbox UID");
+ }
u = new Uid(this, uid, elapsedRealtimeMs, uptimeMs);
mUidStats.put(uid, u);
}
diff --git a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
index a1c1917..81c6ee7 100644
--- a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
+++ b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
@@ -22,6 +22,7 @@
import android.os.BatteryUsageStats;
import android.os.BatteryUsageStatsQuery;
import android.os.Parcel;
+import android.os.Process;
import android.os.SystemClock;
import android.os.UidBatteryConsumer;
import android.util.Log;
@@ -162,6 +163,8 @@
final boolean includeProcessStateData = ((query.getFlags()
& BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_PROCESS_STATE_DATA) != 0)
&& mStats.isProcessStateDataAvailable();
+ final boolean includeVirtualUids = ((query.getFlags()
+ & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_VIRTUAL_UIDS) != 0);
final BatteryUsageStats.Builder batteryUsageStatsBuilder = new BatteryUsageStats.Builder(
mStats.getCustomEnergyConsumerNames(), includePowerModels,
@@ -174,6 +177,10 @@
SparseArray<? extends BatteryStats.Uid> uidStats = mStats.getUidStats();
for (int i = uidStats.size() - 1; i >= 0; i--) {
final BatteryStats.Uid uid = uidStats.valueAt(i);
+ if (!includeVirtualUids && uid.getUid() == Process.SDK_SANDBOX_VIRTUAL_UID) {
+ continue;
+ }
+
batteryUsageStatsBuilder.getOrCreateUidBatteryConsumerBuilder(uid)
.setTimeInStateMs(UidBatteryConsumer.STATE_BACKGROUND,
getProcessBackgroundTimeMs(uid, realtimeUs))
diff --git a/core/java/com/android/internal/os/BluetoothPowerCalculator.java b/core/java/com/android/internal/os/BluetoothPowerCalculator.java
index 2ebf689..e52c8a3 100644
--- a/core/java/com/android/internal/os/BluetoothPowerCalculator.java
+++ b/core/java/com/android/internal/os/BluetoothPowerCalculator.java
@@ -139,8 +139,10 @@
BatteryConsumer.POWER_COMPONENT_BLUETOOTH, powerAndDuration.powerMah,
powerModel);
- powerAndDuration.totalDurationMs += powerAndDuration.durationMs;
- powerAndDuration.totalPowerMah += powerAndDuration.powerMah;
+ if (!app.isVirtualUid()) {
+ powerAndDuration.totalDurationMs += powerAndDuration.durationMs;
+ powerAndDuration.totalPowerMah += powerAndDuration.powerMah;
+ }
if (query.isProcessStateDataNeeded() && powerAndDuration.keys != null) {
for (int j = 0; j < powerAndDuration.keys.length; j++) {
diff --git a/core/java/com/android/internal/os/CpuPowerCalculator.java b/core/java/com/android/internal/os/CpuPowerCalculator.java
index 1fc2baf..8704e93 100644
--- a/core/java/com/android/internal/os/CpuPowerCalculator.java
+++ b/core/java/com/android/internal/os/CpuPowerCalculator.java
@@ -117,7 +117,9 @@
}
}
calculateApp(app, app.getBatteryStatsUid(), query, result, keys);
- totalPowerMah += result.powerMah;
+ if (!app.isVirtualUid()) {
+ totalPowerMah += result.powerMah;
+ }
}
final long consumptionUC = batteryStats.getCpuMeasuredBatteryConsumptionUC();
diff --git a/core/java/com/android/internal/os/CustomMeasuredPowerCalculator.java b/core/java/com/android/internal/os/CustomMeasuredPowerCalculator.java
index cbbb526..0853bd8 100644
--- a/core/java/com/android/internal/os/CustomMeasuredPowerCalculator.java
+++ b/core/java/com/android/internal/os/CustomMeasuredPowerCalculator.java
@@ -96,7 +96,9 @@
app.setConsumedPowerForCustomComponent(
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + i,
customMeasuredPowerMah[i]);
- newTotalPowerMah[i] += customMeasuredPowerMah[i];
+ if (!app.isVirtualUid()) {
+ newTotalPowerMah[i] += customMeasuredPowerMah[i];
+ }
}
}
return newTotalPowerMah;
diff --git a/core/java/com/android/internal/os/GnssPowerCalculator.java b/core/java/com/android/internal/os/GnssPowerCalculator.java
index 0f78306..070783a 100644
--- a/core/java/com/android/internal/os/GnssPowerCalculator.java
+++ b/core/java/com/android/internal/os/GnssPowerCalculator.java
@@ -58,8 +58,11 @@
final long consumptionUC =
app.getBatteryStatsUid().getGnssMeasuredBatteryConsumptionUC();
final int powerModel = getPowerModel(consumptionUC, query);
- appsPowerMah += calculateApp(app, app.getBatteryStatsUid(), powerModel,
+ final double powerMah = calculateApp(app, app.getBatteryStatsUid(), powerModel,
rawRealtimeUs, averageGnssPowerMa, consumptionUC);
+ if (!app.isVirtualUid()) {
+ appsPowerMah += powerMah;
+ }
}
final long consumptionUC = batteryStats.getGnssMeasuredBatteryConsumptionUC();
diff --git a/core/java/com/android/internal/os/MobileRadioPowerCalculator.java b/core/java/com/android/internal/os/MobileRadioPowerCalculator.java
index f4624de..d0df45c 100644
--- a/core/java/com/android/internal/os/MobileRadioPowerCalculator.java
+++ b/core/java/com/android/internal/os/MobileRadioPowerCalculator.java
@@ -136,12 +136,14 @@
PowerAndDuration total,
BatteryUsageStatsQuery query, BatteryConsumer.Key[] keys) {
final long radioActiveDurationMs = calculateDuration(u, BatteryStats.STATS_SINCE_CHARGED);
- total.totalAppDurationMs += radioActiveDurationMs;
-
final long consumptionUC = u.getMobileRadioMeasuredBatteryConsumptionUC();
final int powerModel = getPowerModel(consumptionUC, query);
final double powerMah = calculatePower(u, powerModel, radioActiveDurationMs, consumptionUC);
- total.totalAppPowerMah += powerMah;
+
+ if (!app.isVirtualUid()) {
+ total.totalAppDurationMs += radioActiveDurationMs;
+ total.totalAppPowerMah += powerMah;
+ }
app.setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO,
radioActiveDurationMs)
diff --git a/core/java/com/android/internal/os/ScreenPowerCalculator.java b/core/java/com/android/internal/os/ScreenPowerCalculator.java
index 67d3d6e..5ca1a85 100644
--- a/core/java/com/android/internal/os/ScreenPowerCalculator.java
+++ b/core/java/com/android/internal/os/ScreenPowerCalculator.java
@@ -96,8 +96,10 @@
appPowerAndDuration.durationMs)
.setConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN,
appPowerAndDuration.powerMah, powerModel);
- totalAppPower += appPowerAndDuration.powerMah;
- totalAppDuration += appPowerAndDuration.durationMs;
+ if (!app.isVirtualUid()) {
+ totalAppPower += appPowerAndDuration.powerMah;
+ totalAppDuration += appPowerAndDuration.durationMs;
+ }
}
break;
case BatteryConsumer.POWER_MODEL_POWER_PROFILE:
@@ -192,10 +194,13 @@
long totalActivityTimeMs = 0;
final SparseLongArray activityTimeArray = new SparseLongArray();
for (int i = uidBatteryConsumerBuilders.size() - 1; i >= 0; i--) {
- final BatteryStats.Uid uid = uidBatteryConsumerBuilders.valueAt(i).getBatteryStatsUid();
+ final UidBatteryConsumer.Builder app = uidBatteryConsumerBuilders.valueAt(i);
+ final BatteryStats.Uid uid = app.getBatteryStatsUid();
final long timeMs = getProcessForegroundTimeMs(uid, rawRealtimeUs);
activityTimeArray.put(uid.getUid(), timeMs);
- totalActivityTimeMs += timeMs;
+ if (!app.isVirtualUid()) {
+ totalActivityTimeMs += timeMs;
+ }
}
if (totalActivityTimeMs >= MIN_ACTIVE_TIME_FOR_SMEARING) {
diff --git a/core/java/com/android/internal/os/SensorPowerCalculator.java b/core/java/com/android/internal/os/SensorPowerCalculator.java
index 4a9c91d..573692e 100644
--- a/core/java/com/android/internal/os/SensorPowerCalculator.java
+++ b/core/java/com/android/internal/os/SensorPowerCalculator.java
@@ -51,7 +51,9 @@
builder.getUidBatteryConsumerBuilders();
for (int i = uidBatteryConsumerBuilders.size() - 1; i >= 0; i--) {
final UidBatteryConsumer.Builder app = uidBatteryConsumerBuilders.valueAt(i);
- appsPowerMah += calculateApp(app, app.getBatteryStatsUid(), rawRealtimeUs);
+ if (!app.isVirtualUid()) {
+ appsPowerMah += calculateApp(app, app.getBatteryStatsUid(), rawRealtimeUs);
+ }
}
builder.getAggregateBatteryConsumerBuilder(
diff --git a/core/java/com/android/internal/os/UserPowerCalculator.java b/core/java/com/android/internal/os/UserPowerCalculator.java
index 22cff6e..79e3a19 100644
--- a/core/java/com/android/internal/os/UserPowerCalculator.java
+++ b/core/java/com/android/internal/os/UserPowerCalculator.java
@@ -49,7 +49,11 @@
builder.getUidBatteryConsumerBuilders();
for (int i = uidBatteryConsumerBuilders.size() - 1; i >= 0; i--) {
- UidBatteryConsumer.Builder uidBuilder = uidBatteryConsumerBuilders.valueAt(i);
+ final UidBatteryConsumer.Builder uidBuilder = uidBatteryConsumerBuilders.valueAt(i);
+ if (uidBuilder.isVirtualUid()) {
+ continue;
+ }
+
final int uid = uidBuilder.getUid();
if (UserHandle.getAppId(uid) < Process.FIRST_APPLICATION_UID) {
continue;
diff --git a/core/java/com/android/internal/os/VideoPowerCalculator.java b/core/java/com/android/internal/os/VideoPowerCalculator.java
index a222bcb..2daf15e 100644
--- a/core/java/com/android/internal/os/VideoPowerCalculator.java
+++ b/core/java/com/android/internal/os/VideoPowerCalculator.java
@@ -75,7 +75,9 @@
final double powerMah = mPowerEstimator.calculatePower(durationMs);
app.setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_VIDEO, durationMs)
.setConsumedPower(BatteryConsumer.POWER_COMPONENT_VIDEO, powerMah);
- total.durationMs += durationMs;
- total.powerMah += powerMah;
+ if (!app.isVirtualUid()) {
+ total.durationMs += durationMs;
+ total.powerMah += powerMah;
+ }
}
}
diff --git a/core/java/com/android/internal/os/WakelockPowerCalculator.java b/core/java/com/android/internal/os/WakelockPowerCalculator.java
index 0251e1c..3ae7113 100644
--- a/core/java/com/android/internal/os/WakelockPowerCalculator.java
+++ b/core/java/com/android/internal/os/WakelockPowerCalculator.java
@@ -62,8 +62,10 @@
BatteryStats.STATS_SINCE_CHARGED);
app.setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_WAKELOCK, result.durationMs)
.setConsumedPower(BatteryConsumer.POWER_COMPONENT_WAKELOCK, result.powerMah);
- totalAppDurationMs += result.durationMs;
- appPowerMah += result.powerMah;
+ if (!app.isVirtualUid()) {
+ totalAppDurationMs += result.durationMs;
+ appPowerMah += result.powerMah;
+ }
if (app.getUid() == Process.ROOT_UID) {
osBatteryConsumer = app;
diff --git a/core/java/com/android/internal/os/WifiPowerCalculator.java b/core/java/com/android/internal/os/WifiPowerCalculator.java
index 8c3fb86..2181821 100644
--- a/core/java/com/android/internal/os/WifiPowerCalculator.java
+++ b/core/java/com/android/internal/os/WifiPowerCalculator.java
@@ -111,9 +111,10 @@
calculateApp(powerDurationAndTraffic, app.getBatteryStatsUid(), powerModel,
rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED,
batteryStats.hasWifiActivityReporting(), consumptionUC);
-
- totalAppDurationMs += powerDurationAndTraffic.durationMs;
- totalAppPowerMah += powerDurationAndTraffic.powerMah;
+ if (!app.isVirtualUid()) {
+ totalAppDurationMs += powerDurationAndTraffic.durationMs;
+ totalAppPowerMah += powerDurationAndTraffic.powerMah;
+ }
app.setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_WIFI,
powerDurationAndTraffic.durationMs);
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index d629d66..089179d 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -297,6 +297,11 @@
*/
void runGcForTest();
+ /**
+ * Send a request to SystemUI to put a given active tile in listening state
+ */
+ void requestTileServiceListeningState(in ComponentName componentName);
+
void requestAddTile(in ComponentName componentName, in CharSequence appName, in CharSequence label, in Icon icon, in IAddTileResultCallback callback);
void cancelRequestAddTile(in String packageName);
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 1d60c50..2ee5e79 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -91,7 +91,7 @@
void onBubbleNotificationSuppressionChanged(String key, boolean isNotifSuppressed, boolean isBubbleSuppressed);
void hideCurrentInputMethodForBubbles();
void grantInlineReplyUriPermission(String key, in Uri uri, in UserHandle user, String packageName);
- void clearInlineReplyUriPermissions(String key);
+ oneway void clearInlineReplyUriPermissions(String key);
void onNotificationFeedbackReceived(String key, in Bundle feedback);
void onGlobalActionsShown();
@@ -171,6 +171,11 @@
*/
void suppressAmbientDisplay(boolean suppress);
+ /**
+ * Send a request to SystemUI to put a given active tile in listening state
+ */
+ void requestTileServiceListeningState(in ComponentName componentName, int userId);
+
void requestAddTile(in ComponentName componentName, in CharSequence label, in Icon icon, int userId, in IAddTileResultCallback callback);
void cancelRequestAddTile(in String packageName);
diff --git a/core/java/com/android/internal/telephony/ICarrierPrivilegesListener.aidl b/core/java/com/android/internal/telephony/ICarrierPrivilegesCallback.aidl
similarity index 84%
rename from core/java/com/android/internal/telephony/ICarrierPrivilegesListener.aidl
rename to core/java/com/android/internal/telephony/ICarrierPrivilegesCallback.aidl
index 6ca8cec..0c8e73f 100644
--- a/core/java/com/android/internal/telephony/ICarrierPrivilegesListener.aidl
+++ b/core/java/com/android/internal/telephony/ICarrierPrivilegesCallback.aidl
@@ -16,7 +16,8 @@
package com.android.internal.telephony;
-oneway interface ICarrierPrivilegesListener {
+oneway interface ICarrierPrivilegesCallback {
void onCarrierPrivilegesChanged(
in List<String> privilegedPackageNames, in int[] privilegedUids);
+ void onCarrierServiceChanged(in String carrierServicePackageName, in int carrierServiceUid);
}
diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index 9712d7e..c7fa757 100644
--- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -32,7 +32,7 @@
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.emergency.EmergencyNumber;
-import com.android.internal.telephony.ICarrierPrivilegesListener;
+import com.android.internal.telephony.ICarrierPrivilegesCallback;
import com.android.internal.telephony.IPhoneStateListener;
import com.android.internal.telephony.IOnSubscriptionsChangedListener;
@@ -102,9 +102,11 @@
void notifyLinkCapacityEstimateChanged(in int phoneId, in int subId,
in List<LinkCapacityEstimate> linkCapacityEstimateList);
- void addCarrierPrivilegesListener(
- int phoneId, ICarrierPrivilegesListener callback, String pkg, String featureId);
- void removeCarrierPrivilegesListener(ICarrierPrivilegesListener callback, String pkg);
+ void addCarrierPrivilegesCallback(
+ int phoneId, ICarrierPrivilegesCallback callback, String pkg, String featureId);
+ void removeCarrierPrivilegesCallback(ICarrierPrivilegesCallback callback, String pkg);
void notifyCarrierPrivilegesChanged(
int phoneId, in List<String> privilegedPackageNames, in int[] privilegedUids);
+ void notifyCarrierServiceChanged(int phoneId, in String packageName, int uid);
+
}
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index f835792..521b2f6 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -1135,7 +1135,7 @@
public List<ComponentName> getEnabledTrustAgents(int userId) {
String serialized = getString(ENABLED_TRUST_AGENTS, userId);
if (TextUtils.isEmpty(serialized)) {
- return null;
+ return new ArrayList<ComponentName>();
}
String[] split = serialized.split(",");
ArrayList<ComponentName> activeTrustAgents = new ArrayList<ComponentName>(split.length);
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index eedf7fa..eba6cca 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -1567,6 +1567,7 @@
REG_JNI(register_android_graphics_classes),
REG_JNI(register_android_graphics_BLASTBufferQueue),
REG_JNI(register_android_graphics_GraphicBuffer),
+ REG_JNI(register_android_graphics_GraphicsStatsService),
REG_JNI(register_android_graphics_SurfaceTexture),
REG_JNI(register_android_database_CursorWindow),
REG_JNI(register_android_database_SQLiteConnection),
diff --git a/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp b/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp
index 0c05da5..679a4f0 100644
--- a/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp
+++ b/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp
@@ -34,6 +34,7 @@
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/system_properties.h>
#include <vector>
namespace android {
@@ -43,10 +44,10 @@
using android::zygote::ZygoteFailure;
// WARNING: Knows a little about the wire protocol used to communicate with Zygote.
-// TODO: Fix error handling.
+// Commands and nice names have large arbitrary size limits to avoid dynamic memory allocation.
constexpr size_t MAX_COMMAND_BYTES = 32768;
-constexpr size_t NICE_NAME_BYTES = 50;
+constexpr size_t NICE_NAME_BYTES = 128;
// A buffer optionally bundled with a file descriptor from which we can fill it.
// Does not own the file descriptor; destroying a NativeCommandBuffer does not
@@ -190,6 +191,9 @@
size_t copy_len = std::min(name_len, NICE_NAME_BYTES - 1);
memcpy(mNiceName, arg_start + NN_LENGTH, copy_len);
mNiceName[copy_len] = '\0';
+ if (haveWrapProperty()) {
+ return false;
+ }
continue;
}
if (arg_end - arg_start == IW_LENGTH
@@ -222,6 +226,8 @@
}
saw_setgid = true;
}
+ // ro.debuggable can be handled entirely in the child unless --invoke-with is also specified.
+ // Thus we do not need to check it here.
}
return saw_runtime_args && saw_setuid && saw_setgid;
}
@@ -249,6 +255,14 @@
}
private:
+ bool haveWrapProperty() {
+ static const char* WRAP = "wrap.";
+ static const size_t WRAP_LENGTH = strlen(WRAP);
+ char propNameBuf[WRAP_LENGTH + NICE_NAME_BYTES];
+ strcpy(propNameBuf, WRAP);
+ strlcpy(propNameBuf + WRAP_LENGTH, mNiceName, NICE_NAME_BYTES);
+ return __system_property_find(propNameBuf) != nullptr;
+ }
// Picky version of atoi(). No sign or unexpected characters allowed. Return -1 on failure.
static int digitsVal(char* start, char* end) {
int result = 0;
@@ -269,7 +283,7 @@
uint32_t mNext; // Index of first character past last line returned by readLine.
int32_t mLinesLeft; // Lines in current command that haven't yet been read.
int mFd; // Open file descriptor from which we can read more. -1 if none.
- char mNiceName[NICE_NAME_BYTES];
+ char mNiceName[NICE_NAME_BYTES]; // Always null terminated.
char mBuffer[MAX_COMMAND_BYTES];
};
@@ -372,6 +386,7 @@
jint minUid,
jstring managed_nice_name) {
+ ALOGI("Entering forkRepeatedly native zygote loop");
NativeCommandBuffer* n_buffer = reinterpret_cast<NativeCommandBuffer*>(j_buffer);
int session_socket = n_buffer->getFd();
std::vector<int> session_socket_fds {session_socket};
@@ -400,7 +415,8 @@
socklen_t cred_size = sizeof credentials;
if (getsockopt(n_buffer->getFd(), SOL_SOCKET, SO_PEERCRED, &credentials, &cred_size) == -1
|| cred_size != sizeof credentials) {
- fail_fn_1(CREATE_ERROR("ForkMany failed to get initial credentials, %s", strerror(errno)));
+ fail_fn_1(CREATE_ERROR("ForkRepeatedly failed to get initial credentials, %s",
+ strerror(errno)));
}
bool first_time = true;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index becac7f..ddc37ee 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1030,10 +1030,10 @@
targetSdkVersion}</a> of {@link android.os.Build.VERSION_CODES#S} or lower, this permission
must not be used and the READ_EXTERNAL_STORAGE permission must be used instead.
<p>Protection level: dangerous -->
- <permission android:name="android.permission.READ_MEDIA_IMAGE"
+ <permission android:name="android.permission.READ_MEDIA_IMAGES"
android:permissionGroup="android.permission-group.UNDEFINED"
- android:label="@string/permlab_readMediaImage"
- android:description="@string/permdesc_readMediaImage"
+ android:label="@string/permlab_readMediaImages"
+ android:description="@string/permdesc_readMediaImages"
android:protectionLevel="dangerous" />
<!-- Allows an application to write to external storage.
@@ -6160,10 +6160,10 @@
<!-- Allows input events to be monitored. Very dangerous! @hide -->
<permission android:name="android.permission.MONITOR_INPUT"
android:protectionLevel="signature|recents" />
- <!-- Allows the use of FLAG_SLIPPERY, which permits touch events to slip from the current
- window to the window where the touch currently is on top of. @hide -->
+ <!-- @SystemApi Allows the use of FLAG_SLIPPERY, which permits touch events to slip from the
+ current window to the window where the touch currently is on top of. @hide -->
<permission android:name="android.permission.ALLOW_SLIPPERY_TOUCHES"
- android:protectionLevel="signature|recents" />
+ android:protectionLevel="signature|privileged|recents|role" />
<!-- Allows the caller to change the associations between input devices and displays.
Very dangerous! @hide -->
<permission android:name="android.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY"
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 0a572be..269aa1b 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2723,7 +2723,7 @@
<string name="config_bandwidthEstimateSource">bandwidth_estimator</string>
<!-- Whether force to enable telephony new data stack or not -->
- <bool name="config_force_enable_telephony_new_data_stack">true</bool>
+ <bool name="config_force_enable_telephony_new_data_stack">false</bool>
<!-- Whether WiFi display is supported by this device.
There are many prerequisites for this feature to work correctly.
@@ -2988,6 +2988,12 @@
</string-array>
+ <!-- When migrating notification settings into the permission framework, whether all existing
+ apps should be marked as 'user-set' (true) or whether only the apps that have explicitly
+ modified notification settings should be marked as 'user-set' (false). Users will not see
+ system generated permission prompts for 'user-set' apps. -->
+ <bool name="config_notificationForceUserSetOnUpgrade">true</bool>
+
<!-- Default Gravity setting for the system Toast view. Equivalent to: Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM -->
<integer name="config_toastDefaultGravity">0x00000051</integer>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 5de8fec..04a70cb 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1918,9 +1918,9 @@
<string name="permdesc_readMediaVideo">Allows the app to read video files from your shared storage.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. "shared storage" refers to a storage space on the device that all apps with this permission can read from. [CHAR LIMIT=none] -->
- <string name="permlab_readMediaImage">read image files from shared storage</string>
+ <string name="permlab_readMediaImages">read image files from shared storage</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. "shared storage" refers to a storage space on the device that all apps with this permission can read from. [CHAR LIMIT=none] -->
- <string name="permdesc_readMediaImage">Allows the app to read image files from your shared storage.</string>
+ <string name="permdesc_readMediaImages">Allows the app to read image files from your shared storage.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. "shared storage" refers to a storage space on the device that all apps with this permission can write to. [CHAR LIMIT=none] -->
<string name="permlab_sdcardWrite">modify or delete the contents of your shared storage</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 6f34b3f..1f0b22b 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -4770,5 +4770,6 @@
<java-symbol type="integer" name="config_bg_current_drain_exempted_types" />
<java-symbol type="bool" name="config_bg_current_drain_high_threshold_by_bg_location" />
<java-symbol type="drawable" name="ic_swap_horiz" />
+ <java-symbol type="bool" name="config_notificationForceUserSetOnUpgrade" />
</resources>
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
index 5c9044c..beadc446 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
@@ -424,6 +424,7 @@
@Override
public void bindApplication(String s, ApplicationInfo applicationInfo,
+ String sdkSandboxClientAppPackage,
ProviderInfoList list, ComponentName componentName, ProfilerInfo profilerInfo,
Bundle bundle, IInstrumentationWatcher iInstrumentationWatcher,
IUiAutomationConnection iUiAutomationConnection, int i, boolean b, boolean b1,
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsSensorTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsSensorTest.java
index 0e394c1..bfb3449 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsSensorTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsSensorTest.java
@@ -30,6 +30,7 @@
public class BatteryStatsSensorTest extends TestCase {
private static final int UID = 10500;
+ private static final int UID_2 = 10501; // second uid for testing pool usage
private static final int SENSOR_ID = -10000;
@SmallTest
@@ -239,7 +240,6 @@
@SmallTest
public void testPooledBackgroundUsage() throws Exception {
- final int UID_2 = 20000; // second uid for testing pool usage
final MockClock clocks = new MockClock();
MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
bi.mForceOnBattery = true;
diff --git a/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java b/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java
index b659f37..940ca96 100644
--- a/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java
+++ b/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java
@@ -19,14 +19,20 @@
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_MANAGED;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.content.ComponentName;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.pm.UserInfo;
@@ -50,6 +56,7 @@
import org.mockito.Mockito;
import java.nio.charset.StandardCharsets;
+import java.util.List;
@RunWith(AndroidJUnit4.class)
@SmallTest
@@ -164,6 +171,16 @@
verify(ils).isWeakEscrowTokenValid(eq(testHandle), eq(testToken), eq(testUserId));
}
+ @Test
+ public void testGetEnabledTrustAgentsNotNull() throws RemoteException {
+ int testUserId = 10;
+ ILockSettings ils = createTestLockSettings();
+ when(ils.getString(anyString(), any(), anyInt())).thenReturn("");
+ List<ComponentName> trustAgents = mLockPatternUtils.getEnabledTrustAgents(testUserId);
+ assertNotNull(trustAgents);
+ assertEquals(0, trustAgents.size());
+ }
+
private ILockSettings createTestLockSettings() {
final Context context = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
mLockPatternUtils = spy(new LockPatternUtils(context));
diff --git a/data/etc/com.android.launcher3.xml b/data/etc/com.android.launcher3.xml
index 598d202..36a5134 100644
--- a/data/etc/com.android.launcher3.xml
+++ b/data/etc/com.android.launcher3.xml
@@ -16,6 +16,7 @@
-->
<permissions>
<privapp-permissions package="com.android.launcher3">
+ <permission name="android.permission.ALLOW_SLIPPERY_TOUCHES"/>
<permission name="android.permission.BIND_APPWIDGET"/>
<permission name="android.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS"/>
<permission name="android.permission.GET_ACCOUNTS_PRIVILEGED"/>
diff --git a/data/etc/com.android.systemui.xml b/data/etc/com.android.systemui.xml
index ae350ec..d1873a0 100644
--- a/data/etc/com.android.systemui.xml
+++ b/data/etc/com.android.systemui.xml
@@ -17,6 +17,7 @@
<permissions>
<privapp-permissions package="com.android.systemui">
<permission name="android.permission.CAPTURE_AUDIO_OUTPUT"/>
+ <permission name="android.permission.ALLOW_SLIPPERY_TOUCHES"/>
<permission name="android.permission.BATTERY_STATS"/>
<permission name="android.permission.BIND_APPWIDGET"/>
<permission name="android.permission.BLUETOOTH_PRIVILEGED"/>
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 88920c8..a829339 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -241,7 +241,7 @@
</split-permission>
<split-permission name="android.permission.READ_EXTERNAL_STORAGE"
targetSdk="33">
- <new-permission name="android.permission.READ_MEDIA_IMAGE" />
+ <new-permission name="android.permission.READ_MEDIA_IMAGES" />
</split-permission>
<split-permission name="android.permission.BLUETOOTH"
targetSdk="31">
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index ffaa4ea..c1addbf 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -1098,19 +1098,16 @@
}
// Draw the appropriate mask anchored to (0,0).
+ final int saveCount = mMaskCanvas.save();
final int left = bounds.left;
final int top = bounds.top;
- if (mState.mRippleStyle == STYLE_SOLID) {
- mMaskCanvas.translate(-left, -top);
- }
+ mMaskCanvas.translate(-left, -top);
if (maskType == MASK_EXPLICIT) {
drawMask(mMaskCanvas);
} else if (maskType == MASK_CONTENT) {
drawContent(mMaskCanvas);
}
- if (mState.mRippleStyle == STYLE_SOLID) {
- mMaskCanvas.translate(left, top);
- }
+ mMaskCanvas.restoreToCount(saveCount);
if (mState.mRippleStyle == STYLE_PATTERNED) {
for (int i = 0; i < mRunningAnimations.size(); i++) {
mRunningAnimations.get(i).getProperties().getShader().setShader(mMaskShader);
@@ -1210,9 +1207,13 @@
updateMaskShaderIfNeeded();
// Position the shader to account for canvas translation.
- if (mMaskShader != null && mState.mRippleStyle == STYLE_SOLID) {
+ if (mMaskShader != null) {
final Rect bounds = getBounds();
- mMaskMatrix.setTranslate(bounds.left - x, bounds.top - y);
+ if (mState.mRippleStyle == STYLE_PATTERNED) {
+ mMaskMatrix.setTranslate(bounds.left, bounds.top);
+ } else {
+ mMaskMatrix.setTranslate(bounds.left - x, bounds.top - y);
+ }
mMaskShader.setLocalMatrix(mMaskMatrix);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipInputConsumer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipInputConsumer.java
index e57abc2..0f3ff36 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipInputConsumer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipInputConsumer.java
@@ -148,6 +148,7 @@
mMainExecutor.execute(() -> {
// Choreographer.getSfInstance() must be called on the thread that the input event
// receiver should be receiving events
+ // TODO(b/222697646): remove getSfInstance usage and use vsyncId for transactions
mInputEventReceiver = new InputEventReceiver(inputChannel,
Looper.myLooper(), Choreographer.getSfInstance());
if (mRegistrationListener != null) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
index f3789fd..fa0f092 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
@@ -95,6 +95,8 @@
final FrameCallbackScheduler scheduler = new FrameCallbackScheduler() {
@Override
public void postFrameCallback(@androidx.annotation.NonNull Runnable runnable) {
+ // TODO(b/222697646): remove getSfInstance usage and use vsyncId for
+ // transactions
Choreographer.getSfInstance().postFrameCallback(t -> runnable.run());
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
index c816f18..abf1a95 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
@@ -625,6 +625,7 @@
class PipResizeInputEventReceiver extends BatchedInputEventReceiver {
PipResizeInputEventReceiver(InputChannel channel, Looper looper) {
+ // TODO(b/222697646): remove getSfInstance usage and use vsyncId for transactions
super(channel, looper, Choreographer.getSfInstance());
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java
index 72b93480..d6dacd1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java
@@ -30,17 +30,18 @@
import android.graphics.Rect;
import android.os.SystemClock;
import android.util.ArraySet;
-import android.util.Log;
import android.util.Size;
import android.view.Gravity;
import androidx.annotation.NonNull;
+import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.pip.PipBoundsAlgorithm;
import com.android.wm.shell.pip.PipSnapAlgorithm;
import com.android.wm.shell.pip.tv.TvPipKeepClearAlgorithm.Placement;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
import java.util.Set;
@@ -90,7 +91,10 @@
/** Returns the destination bounds to place the PIP window on entry. */
@Override
public Rect getEntryDestinationBounds() {
- if (DEBUG) Log.d(TAG, "getEntryDestinationBounds()");
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: getEntryDestinationBounds()", TAG);
+ }
if (mTvPipBoundsState.isTvExpandedPipSupported()
&& mTvPipBoundsState.getDesiredTvExpandedAspectRatio() != 0
&& !mTvPipBoundsState.isTvPipManuallyCollapsed()) {
@@ -104,7 +108,10 @@
/** Returns the current bounds adjusted to the new aspect ratio, if valid. */
@Override
public Rect getAdjustedDestinationBounds(Rect currentBounds, float newAspectRatio) {
- if (DEBUG) Log.d(TAG, "getAdjustedDestinationBounds: " + newAspectRatio);
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: getAdjustedDestinationBounds: %f", TAG, newAspectRatio);
+ }
return getTvPipBounds().getBounds();
}
@@ -122,7 +129,11 @@
Set<Rect> unrestrictedKeepClearAreas = mTvPipBoundsState.getUnrestrictedKeepClearAreas();
if (mTvPipBoundsState.isImeShowing()) {
- if (DEBUG) Log.d(TAG, "IME showing, height: " + mTvPipBoundsState.getImeHeight());
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: IME showing, height: %d",
+ TAG, mTvPipBoundsState.getImeHeight());
+ }
final Rect imeBounds = new Rect(
0,
@@ -145,15 +156,22 @@
unrestrictedKeepClearAreas);
if (DEBUG) {
- Log.d(TAG, "pipSize: " + pipSize);
- Log.d(TAG, "screenSize: " + screenSize);
- Log.d(TAG, "stashOffset: " + mTvPipBoundsState.getStashOffset());
- Log.d(TAG, "insetBounds: " + insetBounds.toShortString());
- Log.d(TAG, "pipSize: " + pipSize);
- Log.d(TAG, "gravity: " + Gravity.toString(mTvPipBoundsState.getTvPipGravity()));
- Log.d(TAG, "restrictedKeepClearAreas: " + restrictedKeepClearAreas);
- Log.d(TAG, "unrestrictedKeepClearAreas: " + unrestrictedKeepClearAreas);
- Log.d(TAG, "placement: " + placement);
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: screenSize: %s", TAG, screenSize);
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: stashOffset: %d", TAG, mTvPipBoundsState.getStashOffset());
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: insetBounds: %s", TAG, insetBounds.toShortString());
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: pipSize: %s", TAG, pipSize);
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: gravity: %s", TAG, Gravity.toString(mTvPipBoundsState.getTvPipGravity()));
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: restrictedKeepClearAreas: %s", TAG, restrictedKeepClearAreas);
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: unrestrictedKeepClearAreas: %s", TAG, unrestrictedKeepClearAreas);
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: placement: %s", TAG, placement);
}
return placement;
@@ -164,9 +182,11 @@
*/
int updateGravityOnExpandToggled(int previousGravity, boolean expanding) {
if (DEBUG) {
- Log.d(TAG, "updateGravityOnExpandToggled(), expanding: " + expanding
- + ", mOrientation: " + mTvPipBoundsState.getTvFixedPipOrientation()
- + ", previous gravity: " + Gravity.toString(previousGravity));
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: updateGravityOnExpandToggled(), expanding: %b"
+ + ", mOrientation: %d, previous gravity: %s",
+ TAG, expanding, mTvPipBoundsState.getTvFixedPipOrientation(),
+ Gravity.toString(previousGravity));
}
if (!mTvPipBoundsState.isTvExpandedPipSupported()) {
@@ -218,7 +238,10 @@
}
}
mTvPipBoundsState.setTvPipGravity(updatedGravity);
- if (DEBUG) Log.d(TAG, "new gravity: " + Gravity.toString(updatedGravity));
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: new gravity: %s", TAG, Gravity.toString(updatedGravity));
+ }
return gravityToSave;
}
@@ -227,7 +250,10 @@
* @return true if gravity changed
*/
boolean updateGravity(int keycode) {
- if (DEBUG) Log.d(TAG, "updateGravity, keycode: " + keycode);
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: updateGravity, keycode: %d", TAG, keycode);
+ }
// Check if position change is valid
if (mTvPipBoundsState.isTvPipExpanded()) {
@@ -284,7 +310,10 @@
if (updatedGravity != currentGravity) {
mTvPipBoundsState.setTvPipGravity(updatedGravity);
- if (DEBUG) Log.d(TAG, "new gravity: " + Gravity.toString(updatedGravity));
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: new gravity: %s", TAG, Gravity.toString(updatedGravity));
+ }
return true;
}
return false;
@@ -313,7 +342,9 @@
final Size expandedSize;
if (expandedRatio == 0) {
- Log.d(TAG, "updateExpandedPipSize(): Expanded mode aspect ratio of 0 not supported");
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: updateExpandedPipSize(): Expanded mode aspect ratio"
+ + " of 0 not supported", TAG);
return;
} else if (expandedRatio < 1) {
// vertical
@@ -324,10 +355,16 @@
float aspectRatioHeight = mFixedExpandedWidthInPx / expandedRatio;
if (maxHeight > aspectRatioHeight) {
- if (DEBUG) Log.d(TAG, "Accommodate aspect ratio");
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Accommodate aspect ratio", TAG);
+ }
expandedSize = new Size(mFixedExpandedWidthInPx, (int) aspectRatioHeight);
} else {
- if (DEBUG) Log.d(TAG, "Aspect ratio is too extreme, use max size");
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Aspect ratio is too extreme, use max size", TAG);
+ }
expandedSize = new Size(mFixedExpandedWidthInPx, maxHeight);
}
}
@@ -339,10 +376,16 @@
int maxWidth = displayLayout.width() - (2 * mScreenEdgeInsets.x);
float aspectRatioWidth = mFixedExpandedHeightInPx * expandedRatio;
if (maxWidth > aspectRatioWidth) {
- if (DEBUG) Log.d(TAG, "Accommodate aspect ratio");
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Accommodate aspect ratio", TAG);
+ }
expandedSize = new Size((int) aspectRatioWidth, mFixedExpandedHeightInPx);
} else {
- if (DEBUG) Log.d(TAG, "Aspect ratio is too extreme, use max size");
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Aspect ratio is too extreme, use max size", TAG);
+ }
expandedSize = new Size(maxWidth, mFixedExpandedHeightInPx);
}
}
@@ -350,8 +393,9 @@
mTvPipBoundsState.setTvExpandedSize(expandedSize);
if (DEBUG) {
- Log.d(TAG, "updateExpandedPipSize(): expanded size, width=" + expandedSize.getWidth()
- + ", height=" + expandedSize.getHeight());
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: updateExpandedPipSize(): expanded size, width: %d, height: %d",
+ TAG, expandedSize.getWidth(), expandedSize.getHeight());
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java
index 03c5e98..f397ac0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java
@@ -32,9 +32,9 @@
import android.graphics.Rect;
import android.os.Handler;
import android.os.RemoteException;
-import android.util.Log;
import android.view.Gravity;
+import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.WindowManagerShellWrapper;
import com.android.wm.shell.common.DisplayController;
@@ -50,6 +50,7 @@
import com.android.wm.shell.pip.PipTaskOrganizer;
import com.android.wm.shell.pip.PipTransitionController;
import com.android.wm.shell.pip.tv.TvPipKeepClearAlgorithm.Placement;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -182,10 +183,16 @@
}
private void onConfigurationChanged(Configuration newConfig) {
- if (DEBUG) Log.d(TAG, "onConfigurationChanged(), state=" + stateToName(mState));
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: onConfigurationChanged(), state=%s", TAG, stateToName(mState));
+ }
if (isPipShown()) {
- if (DEBUG) Log.d(TAG, " > closing Pip.");
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: > closing Pip.", TAG);
+ }
closePip();
}
@@ -208,10 +215,16 @@
*/
@Override
public void showPictureInPictureMenu() {
- if (DEBUG) Log.d(TAG, "showPictureInPictureMenu(), state=" + stateToName(mState));
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: showPictureInPictureMenu(), state=%s", TAG, stateToName(mState));
+ }
if (mState == STATE_NO_PIP) {
- if (DEBUG) Log.d(TAG, " > cannot open Menu from the current state.");
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: > cannot open Menu from the current state.", TAG);
+ }
return;
}
@@ -221,7 +234,10 @@
@Override
public void closeMenu() {
- if (DEBUG) Log.d(TAG, "closeMenu(), state before=" + stateToName(mState));
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: closeMenu(), state before=%s", TAG, stateToName(mState));
+ }
setState(STATE_PIP);
mTvPipBoundsAlgorithm.keepUnstashedForCurrentKeepClearAreas();
updatePinnedStackBounds();
@@ -237,7 +253,10 @@
*/
@Override
public void movePipToFullscreen() {
- if (DEBUG) Log.d(TAG, "movePipToFullscreen(), state=" + stateToName(mState));
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: movePipToFullscreen(), state=%s", TAG, stateToName(mState));
+ }
mPipTaskOrganizer.exitPip(mResizeAnimationDuration, false /* requestEnterSplit */);
onPipDisappeared();
@@ -245,7 +264,10 @@
@Override
public void togglePipExpansion() {
- if (DEBUG) Log.d(TAG, "togglePipExpansion()");
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: togglePipExpansion()", TAG);
+ }
boolean expanding = !mTvPipBoundsState.isTvPipExpanded();
int saveGravity = mTvPipBoundsAlgorithm
.updateGravityOnExpandToggled(mPreviousGravity, expanding);
@@ -264,7 +286,10 @@
mPreviousGravity = Gravity.NO_GRAVITY;
updatePinnedStackBounds();
} else {
- if (DEBUG) Log.d(TAG, "Position hasn't changed");
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Position hasn't changed", TAG);
+ }
}
}
@@ -323,10 +348,16 @@
/** Animates the PiP to the given bounds. */
private void movePinnedStackTo(Rect bounds) {
- if (DEBUG) Log.d(TAG, "movePinnedStackTo() - new pip bounds: " + bounds.toShortString());
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: movePinnedStack() - new pip bounds: %s", TAG, bounds.toShortString());
+ }
mPipTaskOrganizer.scheduleAnimateResizePip(bounds,
mResizeAnimationDuration, rect -> {
- if (DEBUG) Log.d(TAG, "movePinnedStack() animation done");
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: movePinnedStack() animation done", TAG);
+ }
mTvPipMenuController.updateExpansionState();
});
}
@@ -336,7 +367,10 @@
*/
@Override
public void closePip() {
- if (DEBUG) Log.d(TAG, "closePip(), state=" + stateToName(mState));
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: closePip(), state=%s", TAG, stateToName(mState));
+ }
removeTask(mPinnedTaskId);
onPipDisappeared();
@@ -348,7 +382,10 @@
private void checkIfPinnedTaskAppeared() {
final TaskInfo pinnedTask = getPinnedTaskInfo();
- if (DEBUG) Log.d(TAG, "checkIfPinnedTaskAppeared(), task=" + pinnedTask);
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: checkIfPinnedTaskAppeared(), task=%s", TAG, pinnedTask);
+ }
if (pinnedTask == null || pinnedTask.topActivity == null) return;
mPinnedTaskId = pinnedTask.taskId;
@@ -357,16 +394,23 @@
}
private void checkIfPinnedTaskIsGone() {
- if (DEBUG) Log.d(TAG, "onTaskStackChanged()");
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: onTaskStackChanged()", TAG);
+ }
if (isPipShown() && getPinnedTaskInfo() == null) {
- Log.w(TAG, "Pinned task is gone.");
+ ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Pinned task is gone.", TAG);
onPipDisappeared();
}
}
private void onPipDisappeared() {
- if (DEBUG) Log.d(TAG, "onPipDisappeared() state=" + stateToName(mState));
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: onPipDisappeared() state=%s", TAG, stateToName(mState));
+ }
mPipNotificationController.dismiss();
mTvPipMenuController.hideMenu();
@@ -377,12 +421,18 @@
@Override
public void onPipTransitionStarted(int direction, Rect pipBounds) {
- if (DEBUG) Log.d(TAG, "onPipTransition_Started(), state=" + stateToName(mState));
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: onPipTransition_Started(), state=%s", TAG, stateToName(mState));
+ }
}
@Override
public void onPipTransitionCanceled(int direction) {
- if (DEBUG) Log.d(TAG, "onPipTransition_Canceled(), state=" + stateToName(mState));
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: onPipTransition_Canceled(), state=%s", TAG, stateToName(mState));
+ }
}
@Override
@@ -390,18 +440,25 @@
if (PipAnimationController.isInPipDirection(direction) && mState == STATE_NO_PIP) {
setState(STATE_PIP);
}
- if (DEBUG) Log.d(TAG, "onPipTransition_Finished(), state=" + stateToName(mState));
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: onPipTransition_Finished(), state=%s", TAG, stateToName(mState));
+ }
}
private void setState(@State int state) {
if (DEBUG) {
- Log.d(TAG, "setState(), state=" + stateToName(state) + ", prev="
- + stateToName(mState));
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: setState(), state=%s, prev=%s",
+ TAG, stateToName(state), stateToName(mState));
}
mState = state;
if (mState == STATE_PIP_MENU) {
- if (DEBUG) Log.d(TAG, " > show menu");
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: > show menu", TAG);
+ }
mTvPipMenuController.showMenu();
}
@@ -429,7 +486,10 @@
public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task,
boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) {
if (task.getWindowingMode() == WINDOWING_MODE_PINNED) {
- if (DEBUG) Log.d(TAG, "onPinnedActivityRestartAttempt()");
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: onPinnedActivityRestartAttempt()", TAG);
+ }
// If the "Pip-ed" Activity is launched again by Launcher or intent, make it
// fullscreen.
@@ -445,8 +505,9 @@
@Override
public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
if (DEBUG) {
- Log.d(TAG, "onImeVisibilityChanged(), visible=" + imeVisible
- + ", height=" + imeHeight);
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: onImeVisibilityChanged(), visible=%b, height=%d",
+ TAG, imeVisible, imeHeight);
}
if (imeVisible == mTvPipBoundsState.isImeShowing()
@@ -464,7 +525,10 @@
@Override
public void onAspectRatioChanged(float ratio) {
- if (DEBUG) Log.d(TAG, "onAspectRatioChanged: " + ratio);
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: onAspectRatioChanged: %f", TAG, ratio);
+ }
boolean ratioChanged = mTvPipBoundsState.getAspectRatio() != ratio;
mTvPipBoundsState.setAspectRatio(ratio);
@@ -476,7 +540,10 @@
@Override
public void onExpandedAspectRatioChanged(float ratio) {
- if (DEBUG) Log.d(TAG, "onExpandedAspectRatioChanged: " + ratio);
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: onExpandedAspectRatioChanged: %f", TAG, ratio);
+ }
// 0) No update to the ratio --> don't do anything
@@ -526,35 +593,50 @@
@Override
public void onActionsChanged(ParceledListSlice<RemoteAction> actions) {
- if (DEBUG) Log.d(TAG, "onActionsChanged()");
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: onActionsChanged()", TAG);
+ }
mTvPipMenuController.setAppActions(actions);
}
});
} catch (RemoteException e) {
- Log.e(TAG, "Failed to register pinned stack listener", e);
+ ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Failed to register pinned stack listener, %s", TAG, e);
}
}
private static TaskInfo getPinnedTaskInfo() {
- if (DEBUG) Log.d(TAG, "getPinnedTaskInfo()");
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: getPinnedTaskInfo()", TAG);
+ }
try {
final TaskInfo taskInfo = ActivityTaskManager.getService().getRootTaskInfo(
WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
- if (DEBUG) Log.d(TAG, " > taskInfo=" + taskInfo);
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: > taskInfo=%s", TAG, taskInfo);
+ }
return taskInfo;
} catch (RemoteException e) {
- Log.e(TAG, "getRootTaskInfo() failed", e);
+ ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: getRootTaskInfo() failed, %s", TAG, e);
return null;
}
}
private static void removeTask(int taskId) {
- if (DEBUG) Log.d(TAG, "removeTask(), taskId=" + taskId);
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: removeTask(), taskId=%d", TAG, taskId);
+ }
try {
ActivityTaskManager.getService().removeTask(taskId);
} catch (Exception e) {
- Log.e(TAG, "Atm.removeTask() failed", e);
+ ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Atm.removeTask() failed, %s", TAG, e);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java
index b3c2306..1a035c5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java
@@ -30,17 +30,18 @@
import android.graphics.RectF;
import android.os.Handler;
import android.os.RemoteException;
-import android.util.Log;
import android.view.SurfaceControl;
import android.view.SyncRtSurfaceTransactionApplier;
import android.view.WindowManagerGlobal;
import androidx.annotation.Nullable;
+import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.common.SystemWindows;
import com.android.wm.shell.pip.PipMediaController;
import com.android.wm.shell.pip.PipMenuController;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
import java.util.ArrayList;
import java.util.List;
@@ -110,7 +111,10 @@
}
void setDelegate(Delegate delegate) {
- if (DEBUG) Log.d(TAG, "setDelegate(), delegate=" + delegate);
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: setDelegate(), delegate=%s", TAG, delegate);
+ }
if (mDelegate != null) {
throw new IllegalStateException(
"The delegate has already been set and should not change.");
@@ -133,7 +137,10 @@
}
private void attachPipMenuView() {
- if (DEBUG) Log.d(TAG, "attachPipMenuView()");
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: attachPipMenuView()", TAG);
+ }
if (mPipMenuView != null) {
detachPipMenuView();
@@ -148,7 +155,10 @@
@Override
public void showMenu() {
- if (DEBUG) Log.d(TAG, "showMenu()");
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: showMenu()", TAG);
+ }
if (mPipMenuView != null) {
Rect menuBounds = getMenuBounds(mTvPipBoundsState.getBounds());
@@ -189,10 +199,16 @@
void hideMenu() {
if (!isMenuVisible()) {
- if (DEBUG) Log.d(TAG, "hideMenu() - Menu isn't visible, so don't hide");
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: hideMenu() - Menu isn't visible, so don't hide", TAG);
+ }
return;
} else {
- if (DEBUG) Log.d(TAG, "hideMenu()");
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: hideMenu()", TAG);
+ }
}
mPipMenuView.hide();
@@ -208,7 +224,10 @@
@Override
public void onEnterMoveMode() {
- if (DEBUG) Log.d(TAG, "onEnterMoveMode - " + mInMoveMode);
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: onEnterMoveMode - %b", TAG, mInMoveMode);
+ }
mInMoveMode = true;
mPipMenuView.showMenuButtons(false);
mPipMenuView.showMovementHints(mDelegate.getPipGravity());
@@ -217,7 +236,10 @@
@Override
public boolean onExitMoveMode() {
- if (DEBUG) Log.d(TAG, "onExitMoveMode - " + mInMoveMode);
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: onExitMoveMode - %b", TAG, mInMoveMode);
+ }
if (mInMoveMode) {
mInMoveMode = false;
mPipMenuView.showMenuButtons(true);
@@ -230,7 +252,10 @@
@Override
public boolean onPipMovement(int keycode) {
- if (DEBUG) Log.d(TAG, "onPipMovement - " + mInMoveMode);
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: onPipMovement - %b", TAG, mInMoveMode);
+ }
if (mInMoveMode) {
mDelegate.movePip(keycode);
}
@@ -246,12 +271,18 @@
@Override
public void setAppActions(ParceledListSlice<RemoteAction> actions) {
- if (DEBUG) Log.d(TAG, "setAppActions()");
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: setAppActions()", TAG);
+ }
updateAdditionalActionsList(mAppActions, actions.getList());
}
private void onMediaActionsChanged(List<RemoteAction> actions) {
- if (DEBUG) Log.d(TAG, "onMediaActionsChanged()");
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: onMediaActionsChanged()", TAG);
+ }
// Hide disabled actions.
List<RemoteAction> enabledActions = new ArrayList<>();
@@ -292,7 +323,10 @@
@Override
public boolean isMenuVisible() {
boolean isVisible = mPipMenuView != null && mPipMenuView.isVisible();
- if (DEBUG) Log.d(TAG, "isMenuVisible: " + isVisible);
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: isMenuVisible: %b", TAG, isVisible);
+ }
return isVisible;
}
@@ -303,7 +337,10 @@
public void resizePipMenu(@android.annotation.Nullable SurfaceControl pipLeash,
@android.annotation.Nullable SurfaceControl.Transaction t,
Rect destinationBounds) {
- if (DEBUG) Log.d(TAG, "resizePipMenu: " + destinationBounds.toShortString());
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: resizePipMenu: %s", TAG, destinationBounds.toShortString());
+ }
if (destinationBounds.isEmpty()) {
return;
}
@@ -335,10 +372,16 @@
@Override
public void movePipMenu(SurfaceControl pipLeash, SurfaceControl.Transaction transaction,
Rect pipDestBounds) {
- if (DEBUG) Log.d(TAG, "movePipMenu: " + pipDestBounds.toShortString());
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: movePipMenu: %s", TAG, pipDestBounds.toShortString());
+ }
if (pipDestBounds.isEmpty()) {
- if (transaction == null && DEBUG) Log.d(TAG, "no transaction given");
+ if (transaction == null && DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: no transaction given", TAG);
+ }
return;
}
if (!maybeCreateSyncApplier()) {
@@ -351,10 +394,16 @@
// resizing and the PiP menu is also resized. We then want to do a scale from the current
// new menu bounds.
if (pipLeash != null && transaction != null) {
- if (DEBUG) Log.d(TAG, "mTmpSourceBounds based on mPipMenuView.getBoundsOnScreen()");
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: mTmpSourceBounds based on mPipMenuView.getBoundsOnScreen()", TAG);
+ }
mPipMenuView.getBoundsOnScreen(mTmpSourceBounds);
} else {
- if (DEBUG) Log.d(TAG, "mTmpSourceBounds based on menu width and height");
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: mTmpSourceBounds based on menu width and height", TAG);
+ }
mTmpSourceBounds.set(0, 0, menuDestBounds.width(), menuDestBounds.height());
}
@@ -389,7 +438,8 @@
private boolean maybeCreateSyncApplier() {
if (mPipMenuView == null || mPipMenuView.getViewRootImpl() == null) {
- Log.v(TAG, "Not going to move PiP, either menu or its parent is not created.");
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Not going to move PiP, either menu or its parent is not created.", TAG);
return false;
}
@@ -412,7 +462,10 @@
@Override
public void updateMenuBounds(Rect destinationBounds) {
Rect menuBounds = getMenuBounds(destinationBounds);
- if (DEBUG) Log.d(TAG, "updateMenuBounds: " + menuBounds.toShortString());
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: updateMenuBounds: %s", TAG, menuBounds.toShortString());
+ }
mSystemWindows.updateViewLayout(mPipMenuView,
getPipMenuLayoutParams(MENU_WINDOW_TITLE, menuBounds.width(),
menuBounds.height()));
@@ -423,7 +476,7 @@
@Override
public void onFocusTaskChanged(ActivityManager.RunningTaskInfo taskInfo) {
- Log.d(TAG, "onFocusTaskChanged");
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: onFocusTaskChanged", TAG);
}
@Override
@@ -465,13 +518,17 @@
}
private void grantPipMenuFocus(boolean grantFocus) {
- if (DEBUG) Log.d(TAG, "grantWindowFocus(" + grantFocus + ")");
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: grantWindowFocus(%b)", TAG, grantFocus);
+ }
try {
WindowManagerGlobal.getWindowSession().grantEmbeddedWindowFocus(null /* window */,
mSystemWindows.getFocusGrantToken(mPipMenuView), grantFocus);
} catch (Exception e) {
- Log.e(TAG, "Unable to update focus", e);
+ ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Unable to update focus, %s", TAG, e);
}
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java
index 3090139..984dea2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java
@@ -31,7 +31,6 @@
import android.graphics.Rect;
import android.os.Handler;
import android.util.AttributeSet;
-import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.SurfaceControl;
@@ -45,7 +44,9 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.R;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
import java.util.ArrayList;
import java.util.List;
@@ -118,17 +119,24 @@
}
void updateLayout(Rect updatedBounds) {
- Log.d(TAG, "update menu layout: " + updatedBounds.toShortString());
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: update menu layout: %s", TAG, updatedBounds.toShortString());
boolean previouslyVertical =
mCurrentBounds != null && mCurrentBounds.height() > mCurrentBounds.width();
boolean vertical = updatedBounds.height() > updatedBounds.width();
mCurrentBounds = updatedBounds;
if (previouslyVertical == vertical) {
- if (DEBUG) Log.d(TAG, "no update for menu layout");
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: no update for menu layout", TAG);
+ }
return;
} else {
- if (DEBUG) Log.d(TAG, "change menu layout to vertical: " + vertical);
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: change menu layout to vertical: %b", TAG, vertical);
+ }
}
if (vertical) {
@@ -154,7 +162,10 @@
}
void setIsExpanded(boolean expanded) {
- if (DEBUG) Log.d(TAG, "setIsExpanded, expanded: " + expanded);
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: setIsExpanded, expanded: %b", TAG, expanded);
+ }
mExpandButton.setImageResource(
expanded ? R.drawable.pip_ic_collapse : R.drawable.pip_ic_expand);
mExpandButton.setTextAndDescription(
@@ -162,7 +173,10 @@
}
void show(boolean inMoveMode, int gravity) {
- if (DEBUG) Log.d(TAG, "show(), inMoveMode: " + inMoveMode);
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: show(), inMoveMode: %b", TAG, inMoveMode);
+ }
if (inMoveMode) {
showMovementHints(gravity);
} else {
@@ -172,7 +186,9 @@
}
void hide() {
- if (DEBUG) Log.d(TAG, "hide()");
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: hide()", TAG);
+ }
animateAlphaTo(0, mActionButtonsContainer);
animateAlphaTo(0, mMenuFrameView);
hideMovementHints();
@@ -205,7 +221,10 @@
}
void setAdditionalActions(List<RemoteAction> actions, Handler mainHandler) {
- if (DEBUG) Log.d(TAG, "setAdditionalActions()");
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: setAdditionalActions()", TAG);
+ }
// Make sure we exactly as many additional buttons as we have actions to display.
final int actionsNumber = actions.size();
@@ -278,10 +297,12 @@
try {
action.getActionIntent().send();
} catch (PendingIntent.CanceledException e) {
- Log.w(TAG, "Failed to send action", e);
+ ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Failed to send action, %s", TAG, e);
}
} else {
- Log.w(TAG, "RemoteAction is null");
+ ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: RemoteAction is null", TAG);
}
}
}
@@ -289,8 +310,9 @@
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (DEBUG) {
- Log.d(TAG, "dispatchKeyEvent, action: " + event.getAction()
- + ", keycode: " + event.getKeyCode());
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: dispatchKeyEvent, action: %d, keycode: %d",
+ TAG, event.getAction(), event.getKeyCode());
}
if (mListener != null && event.getAction() == ACTION_UP) {
switch (event.getKeyCode()) {
@@ -317,7 +339,10 @@
* Shows user hints for moving the PiP, e.g. arrows.
*/
public void showMovementHints(int gravity) {
- if (DEBUG) Log.d(TAG, "showMovementHints(), position: " + Gravity.toString(gravity));
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: showMovementHints(), position: %s", TAG, Gravity.toString(gravity));
+ }
animateAlphaTo(checkGravity(gravity, Gravity.BOTTOM) ? 1f : 0f, mArrowUp);
animateAlphaTo(checkGravity(gravity, Gravity.TOP) ? 1f : 0f, mArrowDown);
@@ -333,7 +358,10 @@
* Hides user hints for moving the PiP, e.g. arrows.
*/
public void hideMovementHints() {
- if (DEBUG) Log.d(TAG, "hideMovementHints()");
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: hideMovementHints()", TAG);
+ }
animateAlphaTo(0, mArrowUp);
animateAlphaTo(0, mArrowRight);
animateAlphaTo(0, mArrowDown);
@@ -344,7 +372,10 @@
* Show or hide the pip user actions.
*/
public void showMenuButtons(boolean show) {
- if (DEBUG) Log.d(TAG, "showMenuButtons: " + show);
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: showMenuButtons: %b", TAG, show);
+ }
animateAlphaTo(show ? 1 : 0, mActionButtonsContainer);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java
index dd7e294..7bd3ce9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java
@@ -28,13 +28,13 @@
import android.graphics.Bitmap;
import android.media.MediaMetadata;
import android.os.Handler;
-import android.os.UserHandle;
import android.text.TextUtils;
-import android.util.Log;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
+import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.pip.PipMediaController;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
import java.util.Objects;
@@ -98,7 +98,10 @@
}
void setDelegate(Delegate delegate) {
- if (DEBUG) Log.d(TAG, "setDelegate(), delegate=" + delegate);
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: setDelegate(), delegate=%s", TAG, delegate);
+ }
if (mDelegate != null) {
throw new IllegalStateException(
"The delegate has already been set and should not change.");
@@ -240,7 +243,10 @@
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
- if (DEBUG) Log.d(TAG, "on(Broadcast)Receive(), action=" + action);
+ if (DEBUG) {
+ ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: on(Broadcast)Receive(), action=%s", TAG, action);
+ }
if (ACTION_SHOW_PIP_MENU.equals(action)) {
mDelegate.showPictureInPictureMenu();
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt
index 61e27f2..fb404b9 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt
@@ -16,6 +16,7 @@
package com.android.wm.shell.flicker.bubble
+import android.platform.test.annotations.Presubmit
import androidx.test.filters.FlakyTest
import androidx.test.filters.RequiresDevice
import androidx.test.uiautomator.By
@@ -24,6 +25,8 @@
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.annotation.Group4
import com.android.server.wm.flicker.dsl.FlickerBuilder
+import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
+import org.junit.Assume
import org.junit.runner.RunWith
import org.junit.Test
import org.junit.runners.Parameterized
@@ -69,9 +72,19 @@
}
}
- @FlakyTest
+ @Presubmit
@Test
fun testAppIsVisibleAtEnd() {
+ Assume.assumeFalse(isShellTransitionsEnabled)
+ testSpec.assertLayersEnd {
+ this.isVisible(testApp.component)
+ }
+ }
+
+ @FlakyTest
+ @Test
+ fun testAppIsVisibleAtEnd_ShellTransit() {
+ Assume.assumeTrue(isShellTransitionsEnabled)
testSpec.assertLayersEnd {
this.isVisible(testApp.component)
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleScreen.kt
index a57d3e6..c43230e 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleScreen.kt
@@ -16,6 +16,7 @@
package com.android.wm.shell.flicker.bubble
+import android.platform.test.annotations.Presubmit
import androidx.test.filters.FlakyTest
import android.platform.test.annotations.RequiresDevice
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
@@ -57,9 +58,19 @@
}
}
- @FlakyTest(bugId = 218642026)
+ @Presubmit
@Test
open fun testAppIsAlwaysVisible() {
+ Assume.assumeFalse(isShellTransitionsEnabled)
+ testSpec.assertLayers {
+ this.isVisible(testApp.component)
+ }
+ }
+
+ @FlakyTest(bugId = 218642026)
+ @Test
+ open fun testAppIsAlwaysVisible_ShellTransit() {
+ Assume.assumeTrue(isShellTransitionsEnabled)
testSpec.assertLayers {
this.isVisible(testApp.component)
}
diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppManager.java b/media/java/android/media/tv/interactive/TvInteractiveAppManager.java
index b6db4cf..9eb4a6c 100755
--- a/media/java/android/media/tv/interactive/TvInteractiveAppManager.java
+++ b/media/java/android/media/tv/interactive/TvInteractiveAppManager.java
@@ -626,6 +626,7 @@
/**
* This is called when the state of the interactive app service is changed.
*
+ * @param iAppServiceId The ID of the TV Interactive App service.
* @param type the interactive app type
* @param state the current state of the service of the given type
* @param err the error code for error state. {@link #ERROR_NONE} is used when the state is
@@ -815,8 +816,8 @@
* @param executor A {@link Executor} that the status change will be delivered to.
*/
public void registerCallback(
- @NonNull TvInteractiveAppCallback callback,
- @CallbackExecutor @NonNull Executor executor) {
+ @CallbackExecutor @NonNull Executor executor,
+ @NonNull TvInteractiveAppCallback callback) {
Preconditions.checkNotNull(callback);
Preconditions.checkNotNull(executor);
synchronized (mLock) {
diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppService.java b/media/java/android/media/tv/interactive/TvInteractiveAppService.java
index bb6edf5..d22fd83 100755
--- a/media/java/android/media/tv/interactive/TvInteractiveAppService.java
+++ b/media/java/android/media/tv/interactive/TvInteractiveAppService.java
@@ -16,6 +16,7 @@
package android.media.tv.interactive;
+import android.annotation.CallSuper;
import android.annotation.MainThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -351,6 +352,7 @@
* @param enable {@code true} if you want to enable the media view. {@code false}
* otherwise.
*/
+ @CallSuper
public void setMediaViewEnabled(final boolean enable) {
mHandler.post(new Runnable() {
@Override
@@ -467,11 +469,11 @@
* in {@link #onSetSurface}. This method is always called at least once, after
* {@link #onSetSurface} is called with non-null surface.
*
- * @param format The new PixelFormat of the surface.
+ * @param format The new {@link PixelFormat} of the surface.
* @param width The new width of the surface.
* @param height The new height of the surface.
*/
- public void onSurfaceChanged(int format, int width, int height) {
+ public void onSurfaceChanged(@PixelFormat.Format int format, int width, int height) {
}
/**
@@ -631,6 +633,7 @@
* @param right Right position in pixels, relative to the overlay view.
* @param bottom Bottom position in pixels, relative to the overlay view.
*/
+ @CallSuper
public void layoutSurface(final int left, final int top, final int right,
final int bottom) {
if (left > right || top > bottom) {
@@ -659,6 +662,7 @@
* Requests broadcast related information from the related TV input.
* @param request the request for broadcast info
*/
+ @CallSuper
public void requestBroadcastInfo(@NonNull final BroadcastInfoRequest request) {
executeOrPostRunnableOnMainThread(new Runnable() {
@MainThread
@@ -683,6 +687,7 @@
* Remove broadcast information request from the related TV input.
* @param requestId the ID of the request
*/
+ @CallSuper
public void removeBroadcastInfo(final int requestId) {
executeOrPostRunnableOnMainThread(new Runnable() {
@MainThread
@@ -709,6 +714,7 @@
* @param cmdType type of the specific command
* @param parameters parameters of the specific command
*/
+ @CallSuper
public void sendPlaybackCommandRequest(
@PlaybackCommandType @NonNull String cmdType, @Nullable Bundle parameters) {
executeOrPostRunnableOnMainThread(new Runnable() {
@@ -733,6 +739,7 @@
/**
* Sets broadcast video bounds.
*/
+ @CallSuper
public void setVideoBounds(@NonNull Rect rect) {
executeOrPostRunnableOnMainThread(new Runnable() {
@MainThread
@@ -755,6 +762,7 @@
/**
* Requests the URI of the current channel.
*/
+ @CallSuper
public void requestCurrentChannelUri() {
executeOrPostRunnableOnMainThread(new Runnable() {
@MainThread
@@ -777,6 +785,7 @@
/**
* Requests the logic channel number (LCN) of the current channel.
*/
+ @CallSuper
public void requestCurrentChannelLcn() {
executeOrPostRunnableOnMainThread(new Runnable() {
@MainThread
@@ -799,6 +808,7 @@
/**
* Requests stream volume.
*/
+ @CallSuper
public void requestStreamVolume() {
executeOrPostRunnableOnMainThread(new Runnable() {
@MainThread
@@ -821,6 +831,7 @@
/**
* Requests the list of {@link TvTrackInfo}.
*/
+ @CallSuper
public void requestTrackInfoList() {
executeOrPostRunnableOnMainThread(new Runnable() {
@MainThread
@@ -845,6 +856,7 @@
*
* @see android.media.tv.TvInputInfo
*/
+ @CallSuper
public void requestCurrentTvInputId() {
executeOrPostRunnableOnMainThread(new Runnable() {
@MainThread
@@ -869,6 +881,7 @@
*
* @param request The advertisement request
*/
+ @CallSuper
public void requestAd(@NonNull final AdRequest request) {
executeOrPostRunnableOnMainThread(new Runnable() {
@MainThread
@@ -1032,6 +1045,7 @@
* used when the state is not
* {@link TvInteractiveAppManager#INTERACTIVE_APP_STATE_ERROR}.
*/
+ @CallSuper
public void notifySessionStateChanged(
@TvInteractiveAppManager.InteractiveAppState int state,
@TvInteractiveAppManager.ErrorCode int err) {
@@ -1062,6 +1076,7 @@
*
* @see #onCreateBiInteractiveApp(Uri, Bundle)
*/
+ @CallSuper
public final void notifyBiInteractiveAppCreated(
@NonNull Uri biIAppUri, @Nullable String biIAppId) {
executeOrPostRunnableOnMainThread(new Runnable() {
@@ -1087,6 +1102,7 @@
* Notifies when the digital teletext app state is changed.
* @param state the current state.
*/
+ @CallSuper
public final void notifyTeletextAppStateChanged(
@TvInteractiveAppManager.TeletextAppState int state) {
executeOrPostRunnableOnMainThread(new Runnable() {
diff --git a/packages/ConnectivityT/framework-t/Android.bp b/packages/ConnectivityT/framework-t/Android.bp
index 6652780..217a1f67c3 100644
--- a/packages/ConnectivityT/framework-t/Android.bp
+++ b/packages/ConnectivityT/framework-t/Android.bp
@@ -154,17 +154,17 @@
],
}
+// TODO: remove this empty filegroup.
filegroup {
name: "framework-connectivity-tiramisu-sources",
- srcs: [
- ":framework-connectivity-ethernet-sources",
- ],
+ srcs: [],
visibility: ["//frameworks/base"],
}
filegroup {
name: "framework-connectivity-tiramisu-updatable-sources",
srcs: [
+ ":framework-connectivity-ethernet-sources",
":framework-connectivity-ipsec-sources",
":framework-connectivity-netstats-sources",
":framework-connectivity-nsd-sources",
diff --git a/packages/ConnectivityT/framework-t/src/android/net/ConnectivityFrameworkInitializerTiramisu.java b/packages/ConnectivityT/framework-t/src/android/net/ConnectivityFrameworkInitializerTiramisu.java
index 9bffbfb..61b34d0 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/ConnectivityFrameworkInitializerTiramisu.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/ConnectivityFrameworkInitializerTiramisu.java
@@ -34,8 +34,9 @@
private ConnectivityFrameworkInitializerTiramisu() {}
/**
- * Called by {@link SystemServiceRegistry}'s static initializer and registers nsd services to
- * {@link Context}, so that {@link Context#getSystemService} can return them.
+ * Called by {@link SystemServiceRegistry}'s static initializer and registers NetworkStats, nsd,
+ * ipsec and ethernet services to {@link Context}, so that {@link Context#getSystemService} can
+ * return them.
*
* @throws IllegalStateException if this is called anywhere besides
* {@link SystemServiceRegistry}.
@@ -68,5 +69,14 @@
return new NetworkStatsManager(context, service);
}
);
+
+ SystemServiceRegistry.registerContextAwareService(
+ Context.ETHERNET_SERVICE,
+ EthernetManager.class,
+ (context, serviceBinder) -> {
+ IEthernetManager service = IEthernetManager.Stub.asInterface(serviceBinder);
+ return new EthernetManager(context, service);
+ }
+ );
}
}
diff --git a/packages/ConnectivityT/framework-t/src/android/net/EthernetManager.java b/packages/ConnectivityT/framework-t/src/android/net/EthernetManager.java
index eba51c1..793f28d 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/EthernetManager.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/EthernetManager.java
@@ -33,7 +33,7 @@
import android.os.RemoteException;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.os.BackgroundThread;
+import com.android.modules.utils.BackgroundThread;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
diff --git a/packages/ConnectivityT/service/Android.bp b/packages/ConnectivityT/service/Android.bp
index 5100e7c..4b799c5 100644
--- a/packages/ConnectivityT/service/Android.bp
+++ b/packages/ConnectivityT/service/Android.bp
@@ -102,17 +102,16 @@
],
path: "src",
visibility: [
- "//frameworks/opt/net/ethernet",
+ "//frameworks/opt/net/ethernet/tests",
],
}
// Connectivity-T common libraries.
+// TODO: remove this empty filegroup.
filegroup {
name: "services.connectivity-tiramisu-sources",
- srcs: [
- ":services.connectivity-ethernet-sources",
- ],
+ srcs: [],
path: "src",
visibility: ["//frameworks/base/services/core"],
}
@@ -120,6 +119,7 @@
filegroup {
name: "services.connectivity-tiramisu-updatable-sources",
srcs: [
+ ":services.connectivity-ethernet-sources",
":services.connectivity-ipsec-sources",
":services.connectivity-netstats-sources",
":services.connectivity-nsd-sources",
diff --git a/services/tests/servicestests/src/com/android/server/net/IpConfigStoreTest.java b/packages/ConnectivityT/tests/unit/java/com/android/server/net/IpConfigStoreTest.java
similarity index 92%
rename from services/tests/servicestests/src/com/android/server/net/IpConfigStoreTest.java
rename to packages/ConnectivityT/tests/unit/java/com/android/server/net/IpConfigStoreTest.java
index 2f77126..ad0be58 100644
--- a/services/tests/servicestests/src/com/android/server/net/IpConfigStoreTest.java
+++ b/packages/ConnectivityT/tests/unit/java/com/android/server/net/IpConfigStoreTest.java
@@ -48,10 +48,16 @@
*/
@RunWith(AndroidJUnit4.class)
public class IpConfigStoreTest {
+ private static final int KEY_CONFIG = 17;
+ private static final String IFACE_1 = "eth0";
+ private static final String IFACE_2 = "eth1";
+ private static final String IP_ADDR_1 = "192.168.1.10/24";
+ private static final String IP_ADDR_2 = "192.168.1.20/24";
+ private static final String DNS_IP_ADDR_1 = "1.2.3.4";
+ private static final String DNS_IP_ADDR_2 = "5.6.7.8";
@Test
public void backwardCompatibility2to3() throws IOException {
- final int KEY_CONFIG = 17;
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
DataOutputStream outputStream = new DataOutputStream(byteStream);
@@ -73,13 +79,6 @@
@Test
public void staticIpMultiNetworks() throws Exception {
- final String IFACE_1 = "eth0";
- final String IFACE_2 = "eth1";
- final String IP_ADDR_1 = "192.168.1.10/24";
- final String IP_ADDR_2 = "192.168.1.20/24";
- final String DNS_IP_ADDR_1 = "1.2.3.4";
- final String DNS_IP_ADDR_2 = "5.6.7.8";
-
final ArrayList<InetAddress> dnsServers = new ArrayList<>();
dnsServers.add(InetAddresses.parseNumericAddress(DNS_IP_ADDR_1));
dnsServers.add(InetAddresses.parseNumericAddress(DNS_IP_ADDR_2));
@@ -144,11 +143,11 @@
/** Synchronously writes into given byte steam */
private static class MockedDelayedDiskWrite extends DelayedDiskWrite {
- final ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
+ final ByteArrayOutputStream mByteStream = new ByteArrayOutputStream();
@Override
public void write(String filePath, Writer w) {
- DataOutputStream outputStream = new DataOutputStream(byteStream);
+ DataOutputStream outputStream = new DataOutputStream(mByteStream);
try {
w.onWriteCalled(outputStream);
diff --git a/packages/SystemUI/res/layout/clipboard_edit_text_activity.xml b/packages/SystemUI/res/layout/clipboard_edit_text_activity.xml
index 8f6753a..da4088f 100644
--- a/packages/SystemUI/res/layout/clipboard_edit_text_activity.xml
+++ b/packages/SystemUI/res/layout/clipboard_edit_text_activity.xml
@@ -36,6 +36,7 @@
android:tooltipText="@*android:string/share"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/copy_button"
+ android:tint="?android:attr/textColorPrimary"
android:src="@drawable/ic_screenshot_share" />
<ScrollView
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java
index 28f21af..0529cdbc 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java
@@ -183,7 +183,7 @@
@Override
void resetState() {
mPasswordEntry.setTextOperationUser(UserHandle.of(KeyguardUpdateMonitor.getCurrentUser()));
- mMessageAreaController.setMessage(R.string.keyguard_enter_your_password);
+ mMessageAreaController.setMessage("");
final boolean wasDisabled = mPasswordEntry.isEnabled();
mView.setPasswordEntryEnabled(true);
mView.setPasswordEntryInputEnabled(true);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
index 7635f919..41f9240 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
@@ -358,7 +358,7 @@
}
private void displayDefaultSecurityMessage() {
- mMessageAreaController.setMessage(R.string.keyguard_enter_your_pattern);
+ mMessageAreaController.setMessage("");
}
private void handleAttemptLockout(long elapsedRealtimeDeadline) {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java
index cc7e4f7..f7423ed 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java
@@ -132,7 +132,6 @@
@Override
void resetState() {
mView.setPasswordEntryEnabled(true);
- mMessageAreaController.setMessage(R.string.keyguard_enter_your_pin);
}
@Override
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java
index 160d82a..9f4585f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java
@@ -76,6 +76,12 @@
}
@Override
+ void resetState() {
+ super.resetState();
+ mMessageAreaController.setMessage("");
+ }
+
+ @Override
public boolean startDisappearAnimation(Runnable finishRunnable) {
return mView.startDisappearAnimation(
mKeyguardUpdateMonitor.needsSlowUnlockTransition(), finishRunnable);
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
index 370686a..74659f7 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
@@ -558,7 +558,7 @@
switch(event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_HOVER_ENTER:
- if (!mDownDetected) {
+ if (!mDownDetected && mAccessibilityManager.isTouchExplorationEnabled()) {
mVibrator.vibrate(
Process.myUid(),
getContext().getOpPackageName(),
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index bf42db5..bc7a3f6 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -584,16 +584,18 @@
}
/**
- * Play haptic to signal udfps scanning started.
+ * If a11y touchExplorationEnabled, play haptic to signal UDFPS scanning started.
*/
@VisibleForTesting
public void playStartHaptic() {
- mVibrator.vibrate(
- Process.myUid(),
- mContext.getOpPackageName(),
- EFFECT_CLICK,
- "udfps-onStart-click",
- VIBRATION_ATTRIBUTES);
+ if (mAccessibilityManager.isTouchExplorationEnabled()) {
+ mVibrator.vibrate(
+ Process.myUid(),
+ mContext.getOpPackageName(),
+ EFFECT_CLICK,
+ "udfps-onStart-click",
+ VIBRATION_ATTRIBUTES);
+ }
}
@Nullable
diff --git a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingAnimation.java b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingAnimation.java
index 508262d..835025b 100644
--- a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingAnimation.java
+++ b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingAnimation.java
@@ -16,6 +16,8 @@
package com.android.systemui.charging;
+import static com.android.systemui.charging.WirelessChargingLayout.UNKNOWN_BATTERY_LEVEL;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
@@ -76,6 +78,16 @@
}
/**
+ * Creates a charging animation object using mostly default values for non-dozing and unknown
+ * battery level without charging number shown.
+ */
+ public static WirelessChargingAnimation makeChargingAnimationWithNoBatteryLevel(
+ @NonNull Context context, UiEventLogger uiEventLogger) {
+ return makeWirelessChargingAnimation(context, null,
+ UNKNOWN_BATTERY_LEVEL, UNKNOWN_BATTERY_LEVEL, null, false, uiEventLogger);
+ }
+
+ /**
* Show the view for the specified duration.
*/
public void show(long delay) {
diff --git a/packages/SystemUI/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerController.java b/packages/SystemUI/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerController.java
index e26c768..8000bdc 100644
--- a/packages/SystemUI/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerController.java
+++ b/packages/SystemUI/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerController.java
@@ -160,14 +160,15 @@
* Returns true if lock screen entry point for QR Code Scanner is to be enabled.
*/
public boolean isEnabledForLockScreenButton() {
- return mQRCodeScannerEnabled && mIntent != null && mConfigEnableLockScreenButton;
+ return mQRCodeScannerEnabled && mIntent != null && mConfigEnableLockScreenButton
+ && isActivityCallable(mIntent);
}
/**
* Returns true if quick settings entry point for QR Code Scanner is to be enabled.
*/
public boolean isEnabledForQuickSettings() {
- return mIntent != null;
+ return mIntent != null && isActivityCallable(mIntent);
}
/**
@@ -278,7 +279,7 @@
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
}
- if (isActivityCallable(intent)) {
+ if (isActivityAvailable(intent)) {
mQRCodeScannerActivity = qrCodeScannerActivity;
mComponentName = componentName;
mIntent = intent;
@@ -293,7 +294,7 @@
}
}
- private boolean isActivityCallable(Intent intent) {
+ private boolean isActivityAvailable(Intent intent) {
// Our intent should always be explicit and should have a component set
if (intent.getComponent() == null) return false;
@@ -307,6 +308,17 @@
flags).isEmpty();
}
+ private boolean isActivityCallable(Intent intent) {
+ // Our intent should always be explicit and should have a component set
+ if (intent.getComponent() == null) return false;
+
+ int flags = PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
+ | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS;
+ return !mContext.getPackageManager().queryIntentActivities(intent,
+ flags).isEmpty();
+ }
+
private void unregisterUserChangeObservers() {
mUserTracker.removeCallback(mUserChangedListener);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
index 32515a2..4cacbba 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
@@ -15,26 +15,22 @@
*/
package com.android.systemui.qs.external;
-import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Icon;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
-import android.os.Looper;
import android.os.RemoteException;
import android.os.UserHandle;
import android.service.quicksettings.IQSService;
import android.service.quicksettings.Tile;
-import android.service.quicksettings.TileService;
import android.util.ArrayMap;
import android.util.Log;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.internal.statusbar.StatusBarIcon;
@@ -42,6 +38,7 @@
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.qs.QSTileHost;
import com.android.systemui.settings.UserTracker;
+import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -51,6 +48,7 @@
import java.util.Objects;
import javax.inject.Inject;
+import javax.inject.Provider;
/**
* Runs the day-to-day operations of which tiles should be bound and when.
@@ -64,11 +62,12 @@
private final ArrayMap<ComponentName, CustomTile> mTiles = new ArrayMap<>();
private final ArrayMap<IBinder, CustomTile> mTokenMap = new ArrayMap<>();
private final Context mContext;
- private final Handler mHandler;
private final Handler mMainHandler;
+ private final Provider<Handler> mHandlerProvider;
private final QSTileHost mHost;
private final KeyguardStateController mKeyguardStateController;
private final BroadcastDispatcher mBroadcastDispatcher;
+ private final CommandQueue mCommandQueue;
private final UserTracker mUserTracker;
private int mMaxBound = DEFAULT_MAX_BOUND;
@@ -76,23 +75,20 @@
@Inject
public TileServices(
QSTileHost host,
- @Main Looper looper,
+ @Main Provider<Handler> handlerProvider,
BroadcastDispatcher broadcastDispatcher,
UserTracker userTracker,
- KeyguardStateController keyguardStateController) {
+ KeyguardStateController keyguardStateController,
+ CommandQueue commandQueue) {
mHost = host;
mKeyguardStateController = keyguardStateController;
mContext = mHost.getContext();
mBroadcastDispatcher = broadcastDispatcher;
- mHandler = new Handler(looper);
- mMainHandler = new Handler(Looper.getMainLooper());
+ mHandlerProvider = handlerProvider;
+ mMainHandler = mHandlerProvider.get();
mUserTracker = userTracker;
- mBroadcastDispatcher.registerReceiver(
- mRequestListeningReceiver,
- new IntentFilter(TileService.ACTION_REQUEST_LISTENING),
- null, // Use the default Executor
- UserHandle.ALL
- );
+ mCommandQueue = commandQueue;
+ mCommandQueue.addCallback(mRequestListeningCallback);
}
public Context getContext() {
@@ -118,7 +114,7 @@
protected TileServiceManager onCreateTileService(ComponentName component,
BroadcastDispatcher broadcastDispatcher) {
- return new TileServiceManager(this, mHandler, component,
+ return new TileServiceManager(this, mHandlerProvider.get(), component,
broadcastDispatcher, mUserTracker);
}
@@ -354,21 +350,14 @@
public void destroy() {
synchronized (mServices) {
mServices.values().forEach(service -> service.handleDestroy());
- mBroadcastDispatcher.unregisterReceiver(mRequestListeningReceiver);
}
+ mCommandQueue.removeCallback(mRequestListeningCallback);
}
- private final BroadcastReceiver mRequestListeningReceiver = new BroadcastReceiver() {
+ private final CommandQueue.Callbacks mRequestListeningCallback = new CommandQueue.Callbacks() {
@Override
- public void onReceive(Context context, Intent intent) {
- if (TileService.ACTION_REQUEST_LISTENING.equals(intent.getAction())) {
- try {
- ComponentName c = intent.getParcelableExtra(Intent.EXTRA_COMPONENT_NAME);
- requestListening(c);
- } catch (ClassCastException ex) {
- Log.e(TAG, "Bad component name", ex);
- }
- }
+ public void requestTileServiceListeningState(@NonNull ComponentName componentName) {
+ mMainHandler.post(() -> requestListening(componentName));
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 5932a64..d9a98b1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -163,6 +163,7 @@
private static final int MSG_MEDIA_TRANSFER_RECEIVER_STATE = 65 << MSG_SHIFT;
private static final int MSG_REGISTER_NEARBY_MEDIA_DEVICE_PROVIDER = 66 << MSG_SHIFT;
private static final int MSG_UNREGISTER_NEARBY_MEDIA_DEVICE_PROVIDER = 67 << MSG_SHIFT;
+ private static final int MSG_TILE_SERVICE_REQUEST_LISTENING_STATE = 68 << MSG_SHIFT;
public static final int FLAG_EXCLUDE_NONE = 0;
public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
@@ -433,6 +434,11 @@
default void setNavigationBarLumaSamplingEnabled(int displayId, boolean enable) {}
/**
+ * @see IStatusBar#requestTileServiceListeningState
+ */
+ default void requestTileServiceListeningState(@NonNull ComponentName componentName) {}
+
+ /**
* @see IStatusBar#requestAddTile
*/
default void requestAddTile(
@@ -1190,6 +1196,12 @@
}
@Override
+ public void requestTileServiceListeningState(@NonNull ComponentName componentName) {
+ mHandler.obtainMessage(MSG_TILE_SERVICE_REQUEST_LISTENING_STATE, componentName)
+ .sendToTarget();
+ }
+
+ @Override
public void requestAddTile(
@NonNull ComponentName componentName,
@NonNull CharSequence appName,
@@ -1686,6 +1698,12 @@
mCallbacks.get(i).unregisterNearbyMediaDevicesProvider(provider);
}
break;
+ case MSG_TILE_SERVICE_REQUEST_LISTENING_STATE:
+ ComponentName component = (ComponentName) msg.obj;
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ mCallbacks.get(i).requestTileServiceListeningState(component);
+ }
+ break;
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
index 2c1296f..7fbb0f1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
@@ -22,15 +22,18 @@
private val headsUpManager: HeadsUpManagerPhone,
private val jankMonitor: InteractionJankMonitor
) {
+ @JvmOverloads
fun getAnimatorController(
- notification: ExpandableNotificationRow
+ notification: ExpandableNotificationRow,
+ onFinishAnimationCallback: Runnable = Runnable {}
): NotificationLaunchAnimatorController {
return NotificationLaunchAnimatorController(
notificationShadeWindowViewController,
notificationListContainer,
headsUpManager,
notification,
- jankMonitor
+ jankMonitor,
+ onFinishAnimationCallback
)
}
}
@@ -45,7 +48,8 @@
private val notificationListContainer: NotificationListContainer,
private val headsUpManager: HeadsUpManagerPhone,
private val notification: ExpandableNotificationRow,
- private val jankMonitor: InteractionJankMonitor
+ private val jankMonitor: InteractionJankMonitor,
+ private val onFinishAnimationCallback: Runnable
) : ActivityLaunchAnimator.Controller {
companion object {
@@ -119,6 +123,7 @@
if (!willAnimate) {
removeHun(animate = true)
+ onFinishAnimationCallback.run()
}
}
@@ -137,6 +142,7 @@
notificationShadeWindowViewController.setExpandAnimationRunning(false)
notificationEntry.isExpandAnimationRunning = false
removeHun(animate = true)
+ onFinishAnimationCallback.run()
}
override fun onLaunchAnimationStart(isExpandingFullyAbove: Boolean) {
@@ -156,6 +162,7 @@
notificationListContainer.setExpandingNotification(null)
applyParams(null)
removeHun(animate = false)
+ onFinishAnimationCallback.run()
}
private fun applyParams(params: ExpandAnimationParameters?) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
index 0df2162..da0169b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
@@ -72,10 +72,11 @@
private var mEndLifetimeExtension: OnEndLifetimeExtensionCallback? = null
private lateinit var mNotifPipeline: NotifPipeline
private var mNow: Long = -1
- // notifs we've extended the lifetime for
- private val mNotifsExtendingLifetime = ArraySet<NotificationEntry>()
private val mPostedEntries = LinkedHashMap<String, PostedEntry>()
+ // notifs we've extended the lifetime for with cancellation callbacks
+ private val mNotifsExtendingLifetime = ArrayMap<NotificationEntry, Runnable?>()
+
override fun attach(pipeline: NotifPipeline) {
mNotifPipeline = pipeline
mHeadsUpManager.addListener(mOnHeadsUpChangedListener)
@@ -460,23 +461,20 @@
}
if (isSticky(entry)) {
val removeAfterMillis = mHeadsUpManager.getEarliestRemovalTime(entry.key)
- mExecutor.executeDelayed({
- val canStillRemove = mHeadsUpManager.canRemoveImmediately(entry.key)
- if (mNotifsExtendingLifetime.contains(entry) && canStillRemove) {
- mHeadsUpManager.removeNotification(entry.key, /* releaseImmediately */ true)
- }
+ mNotifsExtendingLifetime[entry] = mExecutor.executeDelayed({
+ mHeadsUpManager.removeNotification(entry.key, /* releaseImmediately */ true)
}, removeAfterMillis)
} else {
mExecutor.execute {
mHeadsUpManager.removeNotification(entry.key, /* releaseImmediately */ false)
}
+ mNotifsExtendingLifetime[entry] = null
}
- mNotifsExtendingLifetime.add(entry)
return true
}
override fun cancelLifetimeExtension(entry: NotificationEntry) {
- mNotifsExtendingLifetime.remove(entry)
+ mNotifsExtendingLifetime.remove(entry)?.run()
}
}
@@ -543,7 +541,8 @@
mPostedEntries[entry.key]?.calculateShouldBeHeadsUpStrict ?: isAttemptingToShowHun(entry)
private fun endNotifLifetimeExtensionIfExtended(entry: NotificationEntry) {
- if (mNotifsExtendingLifetime.remove(entry)) {
+ if (mNotifsExtendingLifetime.contains(entry)) {
+ mNotifsExtendingLifetime.remove(entry)?.run()
mEndLifetimeExtension?.onEndLifetimeExtension(mLifetimeExtender, entry)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java
index cd2affe..7c4e449 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java
@@ -73,7 +73,7 @@
GroupExpansionManager,
Dumpable {
- private static final String TAG = "NotifGroupManager";
+ private static final String TAG = "LegacyNotifGroupManager";
private static final boolean DEBUG = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.DEBUG);
private static final boolean SPEW = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.VERBOSE);
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
index a7f950e..ec2d608 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
@@ -2881,8 +2881,7 @@
}
boolean updateIsKeyguard(boolean forceStateChange) {
- boolean wakeAndUnlocking = mBiometricUnlockController.getMode()
- == BiometricUnlockController.MODE_WAKE_AND_UNLOCK;
+ boolean wakeAndUnlocking = mBiometricUnlockController.isWakeAndUnlock();
// For dozing, keyguard needs to be shown whenever the device is non-interactive. Otherwise
// there's no surface we can show to the user. Note that the device goes fully interactive
@@ -2892,7 +2891,7 @@
&& (!mDeviceInteractive || (isGoingToSleep()
&& (isScreenFullyOff()
|| (mKeyguardStateController.isShowing() && !isOccluded()))));
- boolean isWakingAndOccluded = isOccluded() && isWaking();
+ boolean isWakingAndOccluded = isOccluded() && isWakingOrAwake();
boolean shouldBeKeyguard = (mStatusBarStateController.isKeyguardRequested()
|| keyguardForDozing) && !wakeAndUnlocking && !isWakingAndOccluded;
if (keyguardForDozing) {
@@ -3076,7 +3075,6 @@
mMessageRouter.cancelMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
releaseGestureWakeLock();
mNotificationPanelViewController.onAffordanceLaunchEnded();
- mNotificationPanelViewController.cancelAnimation();
mNotificationPanelViewController.resetAlpha();
mNotificationPanelViewController.resetTranslation();
mNotificationPanelViewController.resetViewGroupFade();
@@ -3702,8 +3700,9 @@
== WakefulnessLifecycle.WAKEFULNESS_GOING_TO_SLEEP;
}
- boolean isWaking() {
- return mWakefulnessLifecycle.getWakefulness() == WakefulnessLifecycle.WAKEFULNESS_WAKING;
+ boolean isWakingOrAwake() {
+ return mWakefulnessLifecycle.getWakefulness() == WakefulnessLifecycle.WAKEFULNESS_WAKING
+ || mWakefulnessLifecycle.getWakefulness() == WakefulnessLifecycle.WAKEFULNESS_AWAKE;
}
public void notifyBiometricAuthModeChanged() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
index 0ff010a..16e5732 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
@@ -386,10 +386,12 @@
}
visible = true;
}
- if (visible) {
- mNotificationShadeView.setVisibility(View.VISIBLE);
- } else {
- mNotificationShadeView.setVisibility(View.INVISIBLE);
+ if (mNotificationShadeView != null) {
+ if (visible) {
+ mNotificationShadeView.setVisibility(View.VISIBLE);
+ } else {
+ mNotificationShadeView.setVisibility(View.INVISIBLE);
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
index 108d98a..637e4be 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
@@ -370,6 +370,8 @@
mLogger.logExpandingBubble(notificationKey);
removeHunAfterClick(row);
expandBubbleStackOnMainThread(entry);
+ mMainThreadHandler.post(
+ () -> mLaunchEventsEmitter.notifyFinishLaunchNotifActivity(entry));
} else {
startNotificationIntent(intent, fillInIntent, entry, row, animate, isActivityIntent);
}
@@ -395,7 +397,6 @@
mMainThreadHandler.post(() -> {
final Runnable removeNotification = () -> {
mOnUserInteractionCallback.onDismiss(entry, REASON_CLICK, summaryToRemove);
- mLaunchEventsEmitter.notifyFinishLaunchNotifActivity(entry);
};
if (mPresenter.isCollapsing()) {
// To avoid lags we're only performing the remove
@@ -405,9 +406,6 @@
removeNotification.run();
}
});
- } else {
- mMainThreadHandler.post(
- () -> mLaunchEventsEmitter.notifyFinishLaunchNotifActivity(entry));
}
mIsCollapsingToShowActivityOverLockscreen = false;
@@ -483,14 +481,19 @@
boolean isActivityIntent) {
mLogger.logStartNotificationIntent(entry.getKey(), intent);
try {
+ Runnable onFinishAnimationCallback =
+ () -> mLaunchEventsEmitter.notifyFinishLaunchNotifActivity(entry);
ActivityLaunchAnimator.Controller animationController =
new StatusBarLaunchAnimatorController(
- mNotificationAnimationProvider.getAnimatorController(row),
+ mNotificationAnimationProvider
+ .getAnimatorController(row, onFinishAnimationCallback),
mCentralSurfaces,
isActivityIntent);
-
- mActivityLaunchAnimator.startPendingIntentWithAnimation(animationController,
- animate, intent.getCreatorPackage(), (adapter) -> {
+ mActivityLaunchAnimator.startPendingIntentWithAnimation(
+ animationController,
+ animate,
+ intent.getCreatorPackage(),
+ (adapter) -> {
long eventTime = row.getAndResetLastActionUpTime();
Bundle options = eventTime > 0
? getActivityOptions(
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
index e980eb7..8e1e42a 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
@@ -88,6 +88,6 @@
fun onPause_clearsTextField() {
mKeyguardPatternViewController.init()
mKeyguardPatternViewController.onPause()
- verify(mKeyguardMessageAreaController).setMessage(R.string.keyguard_enter_your_pattern)
+ verify(mKeyguardMessageAreaController).setMessage("")
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
index 1856fda..613931f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -48,6 +48,7 @@
import android.testing.TestableLooper.RunWithLooper;
import android.view.LayoutInflater;
import android.view.MotionEvent;
+import android.view.View;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
@@ -64,8 +65,8 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
import com.android.systemui.statusbar.VibratorHelper;
-import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.CentralSurfaces;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.phone.SystemUIDialogManager;
import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
@@ -188,6 +189,7 @@
@Captor private ArgumentCaptor<IUdfpsOverlayController> mOverlayCaptor;
private IUdfpsOverlayController mOverlayController;
@Captor private ArgumentCaptor<UdfpsView.OnTouchListener> mTouchListenerCaptor;
+ @Captor private ArgumentCaptor<View.OnHoverListener> mHoverListenerCaptor;
@Captor private ArgumentCaptor<Runnable> mOnIlluminatedRunnableCaptor;
@Captor private ArgumentCaptor<ScreenLifecycle.Observer> mScreenObserverCaptor;
private ScreenLifecycle.Observer mScreenObserver;
@@ -568,23 +570,24 @@
}
@Test
- public void playHapticOnTouchUdfpsArea() throws RemoteException {
+ public void playHapticOnTouchUdfpsArea_a11yTouchExplorationEnabled() throws RemoteException {
// Configure UdfpsView to accept the ACTION_DOWN event
when(mUdfpsView.isIlluminationRequested()).thenReturn(false);
when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
- // GIVEN that the overlay is showing
+ // GIVEN that the overlay is showing and a11y touch exploration enabled
+ when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true);
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
mFgExecutor.runAllReady();
- // WHEN ACTION_DOWN is received
- verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
- MotionEvent downEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0);
- mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent);
- downEvent.recycle();
- MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0);
- mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent);
+ // WHEN ACTION_HOVER is received
+ verify(mUdfpsView).setOnHoverListener(mHoverListenerCaptor.capture());
+ MotionEvent enterEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_HOVER_ENTER, 0, 0, 0);
+ mHoverListenerCaptor.getValue().onHover(mUdfpsView, enterEvent);
+ enterEvent.recycle();
+ MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_HOVER_MOVE, 0, 0, 0);
+ mHoverListenerCaptor.getValue().onHover(mUdfpsView, moveEvent);
moveEvent.recycle();
// THEN tick haptic is played
@@ -600,4 +603,34 @@
assertEquals(VibrationAttributes.USAGE_COMMUNICATION_REQUEST,
UdfpsController.VIBRATION_ATTRIBUTES.getUsage());
}
+
+ @Test
+ public void noHapticOnTouchUdfpsArea_a11yTouchExplorationDisabled() throws RemoteException {
+ // Configure UdfpsView to accept the ACTION_DOWN event
+ when(mUdfpsView.isIlluminationRequested()).thenReturn(false);
+ when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
+
+ // GIVEN that the overlay is showing and a11y touch exploration NOT enabled
+ when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(false);
+ mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
+ BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
+ mFgExecutor.runAllReady();
+
+ // WHEN ACTION_DOWN is received
+ verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
+ MotionEvent downEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0);
+ mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent);
+ downEvent.recycle();
+ MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0);
+ mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent);
+ moveEvent.recycle();
+
+ // THEN NO haptic played
+ verify(mVibrator, never()).vibrate(
+ anyInt(),
+ anyString(),
+ any(),
+ anyString(),
+ any());
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
index 19a9863..6b7e5b93 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
@@ -20,21 +20,18 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Intent;
-import android.content.IntentFilter;
import android.os.Handler;
-import android.os.Looper;
+import android.os.RemoteException;
import android.os.UserHandle;
-import android.service.quicksettings.TileService;
+import android.service.quicksettings.IQSTileService;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -49,6 +46,7 @@
import com.android.systemui.qs.tileimpl.QSFactoryImpl;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.phone.AutoTileManager;
import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.StatusBarIconController;
@@ -68,17 +66,25 @@
import java.util.ArrayList;
import java.util.Optional;
+import javax.inject.Provider;
+
@SmallTest
@RunWith(AndroidTestingRunner.class)
@RunWithLooper
public class TileServicesTest extends SysuiTestCase {
private static int NUM_FAKES = TileServices.DEFAULT_MAX_BOUND * 2;
+ private static final ComponentName TEST_COMPONENT =
+ ComponentName.unflattenFromString("pkg/.cls");
+
private TileServices mTileService;
+ private TestableLooper mTestableLooper;
private ArrayList<TileServiceManager> mManagers;
@Mock
private BroadcastDispatcher mBroadcastDispatcher;
@Mock
+ private CommandQueue mCommandQueue;
+ @Mock
private StatusBarIconController mStatusBarIconController;
@Mock
private QSFactoryImpl mQSFactory;
@@ -116,17 +122,20 @@
MockitoAnnotations.initMocks(this);
mDependency.injectMockDependency(BluetoothController.class);
mManagers = new ArrayList<>();
+ mTestableLooper = TestableLooper.get(this);
when(mTileServiceRequestControllerBuilder.create(any()))
.thenReturn(mTileServiceRequestController);
when(mTileLifecycleManagerFactory.create(any(Intent.class), any(UserHandle.class)))
.thenReturn(mTileLifecycleManager);
+ Provider<Handler> provider = () -> new Handler(mTestableLooper.getLooper());
+
QSTileHost host = new QSTileHost(mContext,
mStatusBarIconController,
mQSFactory,
- new Handler(),
- Looper.myLooper(),
+ provider.get(),
+ mTestableLooper.getLooper(),
mPluginManager,
mTunerService,
() -> mAutoTileManager,
@@ -140,8 +149,8 @@
mock(CustomTileStatePersister.class),
mTileServiceRequestControllerBuilder,
mTileLifecycleManagerFactory);
- mTileService = new TestTileServices(host, Looper.getMainLooper(), mBroadcastDispatcher,
- mUserTracker, mKeyguardStateController);
+ mTileService = new TestTileServices(host, provider, mBroadcastDispatcher,
+ mUserTracker, mKeyguardStateController, mCommandQueue);
}
@After
@@ -152,24 +161,6 @@
}
@Test
- public void testActiveTileListenerRegisteredOnAllUsers() {
- ArgumentCaptor<IntentFilter> captor = ArgumentCaptor.forClass(IntentFilter.class);
- verify(mBroadcastDispatcher).registerReceiver(any(), captor.capture(), any(), eq(
- UserHandle.ALL));
- assertTrue(captor.getValue().hasAction(TileService.ACTION_REQUEST_LISTENING));
- }
-
- @Test
- public void testBadComponentName_doesntCrash() {
- ArgumentCaptor<BroadcastReceiver> captor = ArgumentCaptor.forClass(BroadcastReceiver.class);
- verify(mBroadcastDispatcher).registerReceiver(captor.capture(), any(), any(), eq(
- UserHandle.ALL));
- Intent intent = new Intent(TileService.ACTION_REQUEST_LISTENING)
- .putExtra(Intent.EXTRA_COMPONENT_NAME, "abc");
- captor.getValue().onReceive(mContext, intent);
- }
-
- @Test
public void testRecalculateBindAllowance() {
// Add some fake tiles.
for (int i = 0; i < NUM_FAKES; i++) {
@@ -225,11 +216,36 @@
}
}
+ @Test
+ public void testRegisterCommand() {
+ verify(mCommandQueue).addCallback(any());
+ }
+
+ @Test
+ public void testRequestListeningStatusCommand() throws RemoteException {
+ ArgumentCaptor<CommandQueue.Callbacks> captor =
+ ArgumentCaptor.forClass(CommandQueue.Callbacks.class);
+ verify(mCommandQueue).addCallback(captor.capture());
+
+ CustomTile mockTile = mock(CustomTile.class);
+ when(mockTile.getComponent()).thenReturn(TEST_COMPONENT);
+
+ TileServiceManager manager = mTileService.getTileWrapper(mockTile);
+ when(manager.isActiveTile()).thenReturn(true);
+ when(manager.getTileService()).thenReturn(mock(IQSTileService.class));
+
+ captor.getValue().requestTileServiceListeningState(TEST_COMPONENT);
+ mTestableLooper.processAllMessages();
+ verify(manager).setBindRequested(true);
+ verify(manager.getTileService()).onStartListening();
+ }
+
private class TestTileServices extends TileServices {
- TestTileServices(QSTileHost host, Looper looper,
+ TestTileServices(QSTileHost host, Provider<Handler> handlerProvider,
BroadcastDispatcher broadcastDispatcher, UserTracker userTracker,
- KeyguardStateController keyguardStateController) {
- super(host, looper, broadcastDispatcher, userTracker, keyguardStateController);
+ KeyguardStateController keyguardStateController, CommandQueue commandQueue) {
+ super(host, handlerProvider, broadcastDispatcher, userTracker, keyguardStateController,
+ commandQueue);
}
@Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt
index 3a60c04..9f82a567 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt
@@ -31,6 +31,7 @@
@Mock lateinit var notificationListContainer: NotificationListContainer
@Mock lateinit var headsUpManager: HeadsUpManagerPhone
@Mock lateinit var jankMonitor: InteractionJankMonitor
+ @Mock lateinit var onFinishAnimationCallback: Runnable
private lateinit var notificationTestHelper: NotificationTestHelper
private lateinit var notification: ExpandableNotificationRow
@@ -52,7 +53,8 @@
notificationListContainer,
headsUpManager,
notification,
- jankMonitor
+ jankMonitor,
+ onFinishAnimationCallback
)
}
@@ -61,7 +63,7 @@
}
@Test
- fun testHunIsRemovedIfWeDontAnimateLaunch() {
+ fun testHunIsRemovedAndCallbackIsInvokedIfWeDontAnimateLaunch() {
flagNotificationAsHun()
controller.onIntentStarted(willAnimate = false)
@@ -69,10 +71,11 @@
assertFalse(notification.entry.isExpandAnimationRunning)
verify(headsUpManager).removeNotification(
notificationKey, true /* releaseImmediately */, true /* animate */)
+ verify(onFinishAnimationCallback).run()
}
@Test
- fun testHunIsRemovedWhenAnimationIsCancelled() {
+ fun testHunIsRemovedAndCallbackIsInvokedWhenAnimationIsCancelled() {
flagNotificationAsHun()
controller.onLaunchAnimationCancelled()
@@ -80,10 +83,11 @@
assertFalse(notification.entry.isExpandAnimationRunning)
verify(headsUpManager).removeNotification(
notificationKey, true /* releaseImmediately */, true /* animate */)
+ verify(onFinishAnimationCallback).run()
}
@Test
- fun testHunIsRemovedWhenAnimationEnds() {
+ fun testHunIsRemovedAndCallbackIsInvokedWhenAnimationEnds() {
flagNotificationAsHun()
controller.onLaunchAnimationEnd(isExpandingFullyAbove = true)
@@ -91,6 +95,7 @@
assertFalse(notification.entry.isExpandAnimationRunning)
verify(headsUpManager).removeNotification(
notificationKey, true /* releaseImmediately */, false /* animate */)
+ verify(onFinishAnimationCallback).run()
}
@Test
@@ -99,4 +104,4 @@
assertTrue(notification.entry.isExpandAnimationRunning)
}
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt
index 144eefb..699f77f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt
@@ -170,11 +170,41 @@
}
@Test
+ fun testCancelAndReAddStickyNotification() {
+ whenever(mHeadsUpManager.isSticky(anyString())).thenReturn(true)
+ addHUN(mEntry)
+ whenever(mHeadsUpManager.canRemoveImmediately(anyString())).thenReturn(false, true, false)
+ whenever(mHeadsUpManager.getEarliestRemovalTime(anyString())).thenReturn(1000L)
+ assertTrue(mNotifLifetimeExtender.maybeExtendLifetime(mEntry, 0))
+ addHUN(mEntry)
+ assertFalse(mNotifLifetimeExtender.maybeExtendLifetime(mEntry, 0))
+ mExecutor.advanceClockToLast()
+ mExecutor.runAllReady()
+ assertTrue(mNotifLifetimeExtender.maybeExtendLifetime(mEntry, 0))
+ verify(mHeadsUpManager, times(0)).removeNotification(anyString(), eq(false))
+ verify(mHeadsUpManager, times(0)).removeNotification(anyString(), eq(true))
+ }
+
+ @Test
+ fun hunNotRemovedWhenExtensionCancelled() {
+ whenever(mHeadsUpManager.isSticky(anyString())).thenReturn(true)
+ addHUN(mEntry)
+ whenever(mHeadsUpManager.canRemoveImmediately(anyString())).thenReturn(false)
+ whenever(mHeadsUpManager.getEarliestRemovalTime(anyString())).thenReturn(1000L)
+ assertTrue(mNotifLifetimeExtender.maybeExtendLifetime(mEntry, 0))
+ mNotifLifetimeExtender.cancelLifetimeExtension(mEntry)
+ mExecutor.advanceClockToLast()
+ mExecutor.runAllReady()
+ verify(mHeadsUpManager, times(0)).removeNotification(anyString(), any())
+ }
+
+ @Test
fun testCancelUpdatedStickyNotification() {
whenever(mHeadsUpManager.isSticky(anyString())).thenReturn(true)
addHUN(mEntry)
whenever(mHeadsUpManager.getEarliestRemovalTime(anyString())).thenReturn(1000L, 500L)
assertTrue(mNotifLifetimeExtender.maybeExtendLifetime(mEntry, 0))
+ addHUN(mEntry)
mExecutor.advanceClockToLast()
mExecutor.runAllReady()
verify(mHeadsUpManager, times(0)).removeNotification(anyString(), eq(false))
@@ -305,6 +335,7 @@
mHuns.add(entry)
whenever(mHeadsUpManager.topEntry).thenReturn(entry)
mOnHeadsUpChangedListener.onHeadsUpStateChanged(entry, true)
+ mNotifLifetimeExtender.cancelLifetimeExtension(entry)
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
index 27179fd..d48ce8c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
@@ -85,6 +85,7 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.Mockito;
@@ -188,10 +189,11 @@
when(mNotifPipelineFlags.isNewPipelineEnabled()).thenReturn(false);
when(mOnUserInteractionCallback.getGroupSummaryToDismiss(mNotificationRow.getEntry()))
.thenReturn(null);
- when(mVisibilityProvider.obtain(anyString(), anyBoolean())).thenAnswer(
- invocation-> NotificationVisibility.obtain(invocation.getArgument(0), 0, 1, false));
- when(mVisibilityProvider.obtain(any(NotificationEntry.class), anyBoolean())).thenAnswer(
- invocation-> NotificationVisibility.obtain(
+ when(mVisibilityProvider.obtain(anyString(), anyBoolean()))
+ .thenAnswer(invocation -> NotificationVisibility.obtain(
+ invocation.getArgument(0), 0, 1, false));
+ when(mVisibilityProvider.obtain(any(NotificationEntry.class), anyBoolean()))
+ .thenAnswer(invocation -> NotificationVisibility.obtain(
invocation.<NotificationEntry>getArgument(0).getKey(), 0, 1, false));
HeadsUpManagerPhone headsUpManager = mock(HeadsUpManagerPhone.class);
@@ -431,12 +433,18 @@
}
@Test
- public void testNotifActivityStarterEventSourceFinishEvent_postPanelCollapse() {
+ public void testNotifActivityStarterEventSourceFinishEvent_postPanelCollapse()
+ throws Exception {
NotifActivityLaunchEvents.Listener listener =
mock(NotifActivityLaunchEvents.Listener.class);
mLaunchEventsEmitter.registerListener(listener);
mNotificationActivityStarter
.onNotificationClicked(mNotificationRow.getEntry().getSbn(), mNotificationRow);
+ ArgumentCaptor<ActivityLaunchAnimator.Controller> controllerCaptor =
+ ArgumentCaptor.forClass(ActivityLaunchAnimator.Controller.class);
+ verify(mActivityLaunchAnimator).startPendingIntentWithAnimation(
+ controllerCaptor.capture(), anyBoolean(), any(), any());
+ controllerCaptor.getValue().onIntentStarted(false);
verify(listener).onFinishLaunchNotifActivity(mNotificationRow.getEntry());
}
}
diff --git a/services/api/current.txt b/services/api/current.txt
index 45c0059..5a28802 100644
--- a/services/api/current.txt
+++ b/services/api/current.txt
@@ -38,7 +38,7 @@
package com.android.server.am {
public interface ActivityManagerLocal {
- method public boolean bindSdkSandboxService(@NonNull android.content.Intent, @NonNull android.content.ServiceConnection, int, @NonNull String, int) throws android.os.RemoteException;
+ method public boolean bindSdkSandboxService(@NonNull android.content.Intent, @NonNull android.content.ServiceConnection, int, @NonNull String, @NonNull String, int) throws android.os.RemoteException;
method public boolean canStartForegroundService(int, int, @NonNull String);
}
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 58fa9fb..839cdc6 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -91,7 +91,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IBatteryStats;
-import com.android.internal.telephony.ICarrierPrivilegesListener;
+import com.android.internal.telephony.ICarrierPrivilegesCallback;
import com.android.internal.telephony.IOnSubscriptionsChangedListener;
import com.android.internal.telephony.IPhoneStateListener;
import com.android.internal.telephony.ITelephonyRegistry;
@@ -153,7 +153,7 @@
IPhoneStateListener callback;
IOnSubscriptionsChangedListener onSubscriptionsChangedListenerCallback;
IOnSubscriptionsChangedListener onOpportunisticSubscriptionsChangedListenerCallback;
- ICarrierPrivilegesListener carrierPrivilegesListener;
+ ICarrierPrivilegesCallback carrierPrivilegesCallback;
int callerUid;
int callerPid;
@@ -178,8 +178,8 @@
return (onOpportunisticSubscriptionsChangedListenerCallback != null);
}
- boolean matchCarrierPrivilegesListener() {
- return carrierPrivilegesListener != null;
+ boolean matchCarrierPrivilegesCallback() {
+ return carrierPrivilegesCallback != null;
}
boolean canReadCallLog() {
@@ -199,7 +199,7 @@
+ onSubscriptionsChangedListenerCallback
+ " onOpportunisticSubscriptionsChangedListenererCallback="
+ onOpportunisticSubscriptionsChangedListenerCallback
- + " carrierPrivilegesListener=" + carrierPrivilegesListener
+ + " carrierPrivilegesCallback=" + carrierPrivilegesCallback
+ " subId=" + subId + " phoneId=" + phoneId + " events=" + eventList + "}";
}
}
@@ -414,7 +414,9 @@
mPreciseDataConnectionStates;
/** Per-phoneId snapshot of privileged packages (names + UIDs). */
- private List<Pair<List<String>, int[]>> mCarrierPrivilegeStates;
+ @NonNull private List<Pair<List<String>, int[]>> mCarrierPrivilegeStates;
+ /** Per-phoneId of CarrierService (PackageName, UID) pair. */
+ @NonNull private List<Pair<String, Integer>> mCarrierServiceStates;
/**
* Support backward compatibility for {@link android.telephony.TelephonyDisplayInfo}.
@@ -705,6 +707,7 @@
cutListToSize(mPhysicalChannelConfigs, mNumPhones);
cutListToSize(mLinkCapacityEstimateLists, mNumPhones);
cutListToSize(mCarrierPrivilegeStates, mNumPhones);
+ cutListToSize(mCarrierServiceStates, mNumPhones);
return;
}
@@ -746,6 +749,7 @@
mAllowedNetworkTypeValue[i] = -1;
mLinkCapacityEstimateLists.add(i, INVALID_LCE_LIST);
mCarrierPrivilegeStates.add(i, new Pair<>(Collections.emptyList(), new int[0]));
+ mCarrierServiceStates.add(i, new Pair<>(null, Process.INVALID_UID));
}
}
}
@@ -813,6 +817,7 @@
mDataEnabledReason = new int[numPhones];
mLinkCapacityEstimateLists = new ArrayList<>();
mCarrierPrivilegeStates = new ArrayList<>();
+ mCarrierServiceStates = new ArrayList<>();
for (int i = 0; i < numPhones; i++) {
mCallState[i] = TelephonyManager.CALL_STATE_IDLE;
@@ -851,6 +856,7 @@
mAllowedNetworkTypeValue[i] = -1;
mLinkCapacityEstimateLists.add(i, INVALID_LCE_LIST);
mCarrierPrivilegeStates.add(i, new Pair<>(Collections.emptyList(), new int[0]));
+ mCarrierServiceStates.add(i, new Pair<>(null, Process.INVALID_UID));
}
mAppOps = mContext.getSystemService(AppOpsManager.class);
@@ -2784,16 +2790,16 @@
}
@Override
- public void addCarrierPrivilegesListener(
+ public void addCarrierPrivilegesCallback(
int phoneId,
- ICarrierPrivilegesListener callback,
- String callingPackage,
- String callingFeatureId) {
+ @NonNull ICarrierPrivilegesCallback callback,
+ @NonNull String callingPackage,
+ @NonNull String callingFeatureId) {
int callerUserId = UserHandle.getCallingUserId();
mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
- "addCarrierPrivilegesListener");
+ "addCarrierPrivilegesCallback");
if (VDBG) {
log(
"listen carrier privs: E pkg=" + pii(callingPackage) + " phoneId=" + phoneId
@@ -2813,7 +2819,7 @@
if (r == null) return;
r.context = mContext;
- r.carrierPrivilegesListener = callback;
+ r.carrierPrivilegesCallback = callback;
r.callingPackage = callingPackage;
r.callingFeatureId = callingFeatureId;
r.callerUid = Binder.getCallingUid();
@@ -2825,10 +2831,18 @@
}
Pair<List<String>, int[]> state = mCarrierPrivilegeStates.get(phoneId);
+ Pair<String, Integer> carrierServiceState = mCarrierServiceStates.get(phoneId);
try {
- r.carrierPrivilegesListener.onCarrierPrivilegesChanged(
- Collections.unmodifiableList(state.first),
- Arrays.copyOf(state.second, state.second.length));
+ if (r.matchCarrierPrivilegesCallback()) {
+ // Here, two callbacks are triggered in quick succession on the same binder.
+ // In typical case, we expect the callers to care about only one or the other.
+ r.carrierPrivilegesCallback.onCarrierPrivilegesChanged(
+ Collections.unmodifiableList(state.first),
+ Arrays.copyOf(state.second, state.second.length));
+
+ r.carrierPrivilegesCallback.onCarrierServiceChanged(carrierServiceState.first,
+ carrierServiceState.second);
+ }
} catch (RemoteException ex) {
remove(r.binder);
}
@@ -2836,12 +2850,12 @@
}
@Override
- public void removeCarrierPrivilegesListener(
- ICarrierPrivilegesListener callback, String callingPackage) {
+ public void removeCarrierPrivilegesCallback(
+ @NonNull ICarrierPrivilegesCallback callback, @NonNull String callingPackage) {
mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
- "removeCarrierPrivilegesListener");
+ "removeCarrierPrivilegesCallback");
remove(callback.asBinder());
}
@@ -2866,13 +2880,13 @@
for (Record r : mRecords) {
// Listeners are per-slot, not per-subscription. This is to provide a stable
// view across SIM profile switches.
- if (!r.matchCarrierPrivilegesListener()
+ if (!r.matchCarrierPrivilegesCallback()
|| !idMatch(r, SubscriptionManager.INVALID_SUBSCRIPTION_ID, phoneId)) {
continue;
}
try {
// Make sure even in-process listeners can't modify the values.
- r.carrierPrivilegesListener.onCarrierPrivilegesChanged(
+ r.carrierPrivilegesCallback.onCarrierPrivilegesChanged(
Collections.unmodifiableList(privilegedPackageNames),
Arrays.copyOf(privilegedUids, privilegedUids.length));
} catch (RemoteException ex) {
@@ -2883,6 +2897,34 @@
}
}
+ @Override
+ public void notifyCarrierServiceChanged(int phoneId, @Nullable String packageName, int uid) {
+ if (!checkNotifyPermission("notifyCarrierServiceChanged")) return;
+ if (!validatePhoneId(phoneId)) return;
+ if (VDBG) {
+ log("notifyCarrierServiceChanged: phoneId=" + phoneId
+ + ", package=" + pii(packageName) + ", uid=" + uid);
+ }
+
+ synchronized (mRecords) {
+ mCarrierServiceStates.set(
+ phoneId, new Pair<>(packageName, uid));
+ for (Record r : mRecords) {
+ // Listeners are per-slot, not per-subscription.
+ if (!r.matchCarrierPrivilegesCallback()
+ || !idMatch(r, SubscriptionManager.INVALID_SUBSCRIPTION_ID, phoneId)) {
+ continue;
+ }
+ try {
+ r.carrierPrivilegesCallback.onCarrierServiceChanged(packageName, uid);
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
+ }
+ }
+ handleRemoveListLocked();
+ }
+ }
+
@NeverCompile // Avoid size overhead of debugging code.
@Override
public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
@@ -2938,6 +2980,9 @@
pw.println(
"mCarrierPrivilegeState=<packages=" + pii(carrierPrivilegeState.first)
+ ", uids=" + Arrays.toString(carrierPrivilegeState.second) + ">");
+ Pair<String, Integer> carrierServiceState = mCarrierServiceStates.get(i);
+ pw.println("mCarrierServiceState=<package=" + pii(carrierServiceState.first)
+ + ", uid=" + carrierServiceState.second + ">");
pw.decreaseIndent();
}
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index d4ad718..48e3264 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -2722,7 +2722,7 @@
int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, final IServiceConnection connection, int flags,
String instanceName, boolean isSdkSandboxService, int sdkSandboxClientAppUid,
- String callingPackage, final int userId)
+ String sdkSandboxClientAppPackage, String callingPackage, final int userId)
throws TransactionTooLargeException {
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "bindService: " + service
+ " type=" + resolvedType + " conn=" + connection.asBinder()
@@ -2807,8 +2807,9 @@
final boolean allowInstant = (flags & Context.BIND_ALLOW_INSTANT) != 0;
ServiceLookupResult res = retrieveServiceLocked(service, instanceName,
- isSdkSandboxService, sdkSandboxClientAppUid, resolvedType, callingPackage,
- callingPid, callingUid, userId, true, callerFg, isBindExternal, allowInstant);
+ isSdkSandboxService, sdkSandboxClientAppUid, sdkSandboxClientAppPackage,
+ resolvedType, callingPackage, callingPid, callingUid, userId, true, callerFg,
+ isBindExternal, allowInstant);
if (res == null) {
return 0;
}
@@ -3228,14 +3229,14 @@
int callingPid, int callingUid, int userId,
boolean createIfNeeded, boolean callingFromFg, boolean isBindExternal,
boolean allowInstant) {
- return retrieveServiceLocked(service, instanceName, false, 0, resolvedType, callingPackage,
- callingPid, callingUid, userId, createIfNeeded, callingFromFg, isBindExternal,
- allowInstant);
+ return retrieveServiceLocked(service, instanceName, false, 0, null, resolvedType,
+ callingPackage, callingPid, callingUid, userId, createIfNeeded, callingFromFg,
+ isBindExternal, allowInstant);
}
private ServiceLookupResult retrieveServiceLocked(Intent service,
String instanceName, boolean isSdkSandboxService, int sdkSandboxClientAppUid,
- String resolvedType,
+ String sdkSandboxClientAppPackage, String resolvedType,
String callingPackage, int callingPid, int callingUid, int userId,
boolean createIfNeeded, boolean callingFromFg, boolean isBindExternal,
boolean allowInstant) {
@@ -3416,7 +3417,8 @@
: null;
r = new ServiceRecord(mAm, className, name, definingPackageName,
definingUid, filter, sInfo, callingFromFg, res,
- sdkSandboxProcessName, sdkSandboxClientAppUid);
+ sdkSandboxProcessName, sdkSandboxClientAppUid,
+ sdkSandboxClientAppPackage);
res.setService(r);
smap.mServicesByInstanceName.put(name, r);
smap.mServicesByIntent.put(filter, r);
@@ -4195,7 +4197,7 @@
if (r.isSdkSandbox) {
final int uid = Process.toSdkSandboxUid(r.sdkSandboxClientAppUid);
app = mAm.startSdkSandboxProcessLocked(procName, r.appInfo, true, intentFlags,
- hostingRecord, ZYGOTE_POLICY_FLAG_EMPTY, uid);
+ hostingRecord, ZYGOTE_POLICY_FLAG_EMPTY, uid, r.sdkSandboxClientAppPackage);
r.isolationHostProc = app;
} else {
app = mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
diff --git a/services/core/java/com/android/server/am/ActivityManagerLocal.java b/services/core/java/com/android/server/am/ActivityManagerLocal.java
index 3226a2b..1d2c36b 100644
--- a/services/core/java/com/android/server/am/ActivityManagerLocal.java
+++ b/services/core/java/com/android/server/am/ActivityManagerLocal.java
@@ -74,6 +74,8 @@
* @param conn Receives information as the service is started and stopped.
* This must be a valid ServiceConnection object; it must not be null.
* @param clientAppUid Uid of the app for which the sdk sandbox process needs to be spawned.
+ * @param clientAppPackage Package of the app for which the sdk sandbox process needs to
+ * be spawned. This package must belong to the clientAppUid.
* @param processName Unique identifier for the service instance. Each unique name here will
* result in a different service instance being created. Identifiers must only contain
* ASCII letters, digits, underscores, and periods.
@@ -87,6 +89,7 @@
*/
@SuppressLint("RethrowRemoteException")
boolean bindSdkSandboxService(@NonNull Intent service, @NonNull ServiceConnection conn,
- int clientAppUid, @NonNull String processName, @Context.BindServiceFlags int flags)
+ int clientAppUid, @NonNull String clientAppPackage, @NonNull String processName,
+ @Context.BindServiceFlags int flags)
throws RemoteException;
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 95e35ef..0735648 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -36,6 +36,7 @@
import static android.app.ActivityManager.StopUserOnSwitch;
import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
import static android.app.ActivityManagerInternal.ALLOW_NON_FULL;
+import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.OP_NONE;
import static android.content.pm.ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT;
import static android.content.pm.PackageManager.GET_SHARED_LIBRARY_FILES;
@@ -1895,6 +1896,7 @@
0,
false,
0,
+ null,
new HostingRecord("system"));
app.setPersistent(true);
app.setPid(MY_PID);
@@ -2783,7 +2785,8 @@
false /* knownToBeDead */, 0 /* intentFlags */,
sNullHostingRecord /* hostingRecord */, ZYGOTE_POLICY_FLAG_EMPTY,
true /* allowWhileBooting */, true /* isolated */,
- uid, false /* supplemental */, 0 /* supplementalUid */,
+ uid, false /* isSdkSandbox */, 0 /* sdkSandboxUid */,
+ null /* sdkSandboxClientAppPackage */,
abiOverride, entryPoint, entryPointArgs, crashHandler);
return proc != null;
}
@@ -2792,11 +2795,12 @@
@GuardedBy("this")
final ProcessRecord startSdkSandboxProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
- HostingRecord hostingRecord, int zygotePolicyFlags, int sdkSandboxUid) {
+ HostingRecord hostingRecord, int zygotePolicyFlags, int sdkSandboxUid,
+ String sdkSandboxClientAppPackage) {
return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
hostingRecord, zygotePolicyFlags, false /* allowWhileBooting */,
false /* isolated */, 0 /* isolatedUid */,
- true /* isSdkSandbox */, sdkSandboxUid,
+ true /* isSdkSandbox */, sdkSandboxUid, sdkSandboxClientAppPackage,
null /* ABI override */, null /* entryPoint */,
null /* entryPointArgs */, null /* crashHandler */);
}
@@ -2808,7 +2812,8 @@
boolean isolated) {
return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
hostingRecord, zygotePolicyFlags, allowWhileBooting, isolated, 0 /* isolatedUid */,
- false /* isSdkSandbox */, 0 /* sdkSandboxClientdAppUid */,
+ false /* isSdkSandbox */, 0 /* sdkSandboxClientAppUid */,
+ null /* sdkSandboxClientAppPackage */,
null /* ABI override */, null /* entryPoint */,
null /* entryPointArgs */, null /* crashHandler */);
}
@@ -4773,7 +4778,8 @@
thread.runIsolatedEntryPoint(
app.getIsolatedEntryPoint(), app.getIsolatedEntryPointArgs());
} else if (instr2 != null) {
- thread.bindApplication(processName, appInfo, providerList,
+ thread.bindApplication(processName, appInfo, app.sdkSandboxClientAppPackage,
+ providerList,
instr2.mClass,
profilerInfo, instr2.mArguments,
instr2.mWatcher,
@@ -4787,8 +4793,8 @@
app.getDisabledCompatChanges(), serializedSystemFontMap,
app.getStartElapsedTime(), app.getStartUptime());
} else {
- thread.bindApplication(processName, appInfo, providerList, null, profilerInfo,
- null, null, null, testMode,
+ thread.bindApplication(processName, appInfo, app.sdkSandboxClientAppPackage,
+ providerList, null, profilerInfo, null, null, null, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.isPersistent(),
new Configuration(app.getWindowProcessController().getConfiguration()),
@@ -5749,6 +5755,18 @@
owningUid, exported);
}
+ private void enforceDebuggable(ProcessRecord proc) {
+ if (!Build.IS_DEBUGGABLE && !proc.isDebuggable()) {
+ throw new SecurityException("Process not debuggable: " + proc.info.packageName);
+ }
+ }
+
+ private void enforceDebuggable(ApplicationInfo info) {
+ if (!Build.IS_DEBUGGABLE && (info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
+ throw new SecurityException("Process not debuggable: " + info.packageName);
+ }
+ }
+
/**
* As the only public entry point for permissions checking, this method
* can enforce the semantic that requesting a check on a null global
@@ -6553,7 +6571,7 @@
if (app == null) {
app = mProcessList.newProcessRecordLocked(info, customProcess, isolated, 0,
- false, 0,
+ false, 0, null,
new HostingRecord("added application",
customProcess != null ? customProcess : info.processName));
updateLruProcessLocked(app, false, null);
@@ -6786,22 +6804,25 @@
}
void setTrackAllocationApp(ApplicationInfo app, String processName) {
- if (!Build.IS_DEBUGGABLE) {
- if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
- throw new SecurityException("Process not debuggable: " + app.packageName);
- }
- }
+ enforceDebuggable(app);
synchronized (mProcLock) {
mTrackAllocationApp = processName;
}
}
- void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
+ void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo,
+ ApplicationInfo sdkSandboxClientApp) {
synchronized (mAppProfiler.mProfilerLock) {
if (!Build.IS_DEBUGGABLE) {
boolean isAppDebuggable = (app.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
boolean isAppProfileable = app.isProfileableByShell();
+
+ if (sdkSandboxClientApp != null) {
+ isAppDebuggable |=
+ (sdkSandboxClientApp.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
+ isAppProfileable |= sdkSandboxClientApp.isProfileableByShell();
+ }
if (!isAppDebuggable && !isAppProfileable) {
throw new SecurityException("Process not debuggable, "
+ "and not profileable by shell: " + app.packageName);
@@ -6812,11 +6833,7 @@
}
void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
- if (!Build.IS_DEBUGGABLE) {
- if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
- throw new SecurityException("Process not debuggable: " + app.packageName);
- }
- }
+ enforceDebuggable(app);
mNativeDebuggingApp = processName;
}
@@ -12395,13 +12412,13 @@
String resolvedType, IServiceConnection connection, int flags, String instanceName,
String callingPackage, int userId) throws TransactionTooLargeException {
return bindServiceInstance(caller, token, service, resolvedType, connection, flags,
- instanceName, false, 0, callingPackage, userId);
+ instanceName, false, 0, null, callingPackage, userId);
}
private int bindServiceInstance(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, IServiceConnection connection, int flags, String instanceName,
- boolean isSdkSandboxService, int sdkSandboxClientdAppUid, String callingPackage,
- int userId)
+ boolean isSdkSandboxService, int sdkSandboxClientAppUid,
+ String sdkSandboxClientAppPackage, String callingPackage, int userId)
throws TransactionTooLargeException {
enforceNotIsolatedCaller("bindService");
@@ -12438,8 +12455,8 @@
}
synchronized (this) {
return mServices.bindServiceLocked(caller, token, service, resolvedType, connection,
- flags, instanceName, isSdkSandboxService, sdkSandboxClientdAppUid,
- callingPackage, userId);
+ flags, instanceName, isSdkSandboxService, sdkSandboxClientAppUid,
+ sdkSandboxClientAppPackage, callingPackage, userId);
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
@@ -15562,12 +15579,7 @@
throw new IllegalArgumentException("Unknown process: " + process);
}
- boolean isDebuggable = Build.IS_DEBUGGABLE;
- if (!isDebuggable) {
- if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
- throw new SecurityException("Process not debuggable: " + proc);
- }
- }
+ enforceDebuggable(proc);
mOomAdjuster.mCachedAppOptimizer.enableFreezer(false);
@@ -15670,10 +15682,7 @@
throw new SecurityException("No process found for calling pid "
+ Binder.getCallingPid());
}
- if (!Build.IS_DEBUGGABLE
- && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
- throw new SecurityException("Not running a debuggable build");
- }
+ enforceDebuggable(proc);
processName = proc.processName;
uid = proc.uid;
if (reportPackage != null && !proc.getPkgList().containsKey(reportPackage)) {
@@ -15884,13 +15893,7 @@
return false;
}
- if (!Build.IS_DEBUGGABLE) {
- if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
- return false;
- }
- }
-
- return true;
+ return Build.IS_DEBUGGABLE || process.isDebuggable();
}
public boolean startBinderTracking() throws RemoteException {
@@ -16022,22 +16025,29 @@
@Override
public boolean bindSdkSandboxService(Intent service, ServiceConnection conn,
- int userAppUid, String processName, int flags) throws RemoteException {
+ int clientAppUid, String clientAppPackage, String processName, int flags)
+ throws RemoteException {
if (service == null) {
throw new IllegalArgumentException("intent is null");
}
if (conn == null) {
throw new IllegalArgumentException("connection is null");
}
+ if (clientAppPackage == null) {
+ throw new IllegalArgumentException("clientAppPackage is null");
+ }
if (processName == null) {
throw new IllegalArgumentException("processName is null");
}
if (service.getComponent() == null) {
throw new IllegalArgumentException("service must specify explicit component");
}
- if (!UserHandle.isApp(userAppUid)) {
+ if (!UserHandle.isApp(clientAppUid)) {
throw new IllegalArgumentException("uid is not within application range");
}
+ if (mAppOpsService.checkPackage(clientAppUid, clientAppPackage) != MODE_ALLOWED) {
+ throw new IllegalArgumentException("uid does not belong to provided package");
+ }
Handler handler = mContext.getMainThreadHandler();
@@ -16046,8 +16056,8 @@
return ActivityManagerService.this.bindServiceInstance(
mContext.getIApplicationThread(), mContext.getActivityToken(), service,
service.resolveTypeIfNeeded(mContext.getContentResolver()), sd, flags,
- processName, /*isSupplementalProcessService*/ true, userAppUid,
- mContext.getOpPackageName(), UserHandle.getUserId(userAppUid)) != 0;
+ processName, /*isSdkSandboxService*/ true, clientAppUid, clientAppPackage,
+ mContext.getOpPackageName(), UserHandle.getUserId(clientAppUid)) != 0;
}
@Override
@@ -16837,7 +16847,7 @@
}
if (profilerInfo != null) {
- setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo);
+ setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo, null);
}
wmLock.notify();
}
@@ -17625,11 +17635,7 @@
throw new IllegalArgumentException("Unknown process: " + process);
}
- if (!Build.IS_DEBUGGABLE) {
- if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
- throw new SecurityException("Process not debuggable: " + proc);
- }
- }
+ enforceDebuggable(proc);
thread.attachAgent(path);
}
diff --git a/services/core/java/com/android/server/am/AppProfiler.java b/services/core/java/com/android/server/am/AppProfiler.java
index d6a4cf6..16a7283 100644
--- a/services/core/java/com/android/server/am/AppProfiler.java
+++ b/services/core/java/com/android/server/am/AppProfiler.java
@@ -58,7 +58,6 @@
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.Uri;
import android.os.Binder;
@@ -608,13 +607,7 @@
if (check != null) {
if ((pss * 1024) >= check && profile.getThread() != null
&& mMemWatchDumpProcName == null) {
- boolean isDebuggable = Build.IS_DEBUGGABLE;
- if (!isDebuggable) {
- if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
- isDebuggable = true;
- }
- }
- if (isDebuggable) {
+ if (Build.IS_DEBUGGABLE || proc.isDebuggable()) {
Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
startHeapDumpLPf(profile, false);
} else {
@@ -1702,7 +1695,8 @@
try {
if (start) {
stopProfilerLPf(null, 0);
- mService.setProfileApp(proc.info, proc.processName, profilerInfo);
+ mService.setProfileApp(proc.info, proc.processName, profilerInfo,
+ proc.isSdkSandbox ? proc.getClientInfoForSdkSandbox() : null);
mProfileData.setProfileProc(proc);
mProfileType = profileType;
ParcelFileDescriptor fd = profilerInfo.profileFd;
@@ -1886,8 +1880,7 @@
BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
if (ps == null || !ps.isActive()) {
st.batteryStats = ps = bstats.getProcessStatsLocked(
- bstats.mapUid(st.uid), st.name,
- elapsedRealtime, uptime);
+ st.uid, st.name, elapsedRealtime, uptime);
}
ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
}
@@ -2076,7 +2069,7 @@
if (mAppAgentMap != null && mAppAgentMap.containsKey(processName)) {
// We need to do a debuggable check here. See setAgentApp for why the check is
// postponed to here.
- if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
+ if (app.isDebuggable()) {
String agent = mAppAgentMap.get(processName);
// Do not overwrite already requested agent.
if (profilerInfo == null) {
@@ -2133,7 +2126,7 @@
if (preBindAgent != null) {
thread.attachAgent(preBindAgent);
}
- if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
+ if (app.isDebuggable()) {
thread.attachStartupAgents(app.info.dataDir);
}
return profilerInfo;
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 91822ac..eb7897b 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -799,6 +799,7 @@
final BatteryUsageStatsQuery querySinceReset =
new BatteryUsageStatsQuery.Builder()
.includeProcessStateData()
+ .includeVirtualUids()
.build();
bus = getBatteryUsageStats(List.of(querySinceReset)).get(0);
break;
@@ -806,6 +807,7 @@
final BatteryUsageStatsQuery queryPowerProfile =
new BatteryUsageStatsQuery.Builder()
.includeProcessStateData()
+ .includeVirtualUids()
.powerProfileModeledOnly()
.build();
bus = getBatteryUsageStats(List.of(queryPowerProfile)).get(0);
@@ -821,6 +823,7 @@
final BatteryUsageStatsQuery queryBeforeReset =
new BatteryUsageStatsQuery.Builder()
.includeProcessStateData()
+ .includeVirtualUids()
.aggregateSnapshots(sessionStart, sessionEnd)
.build();
bus = getBatteryUsageStats(List.of(queryBeforeReset)).get(0);
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 48ca59d..253686c 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -1718,8 +1718,16 @@
int runtimeFlags = 0;
boolean debuggableFlag = (app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
- if (!debuggableFlag && app.isSdkSandbox) {
- debuggableFlag = isAppForSdkSandboxDebuggable(app);
+ boolean isProfileableByShell = app.info.isProfileableByShell();
+ boolean isProfileable = app.info.isProfileable();
+
+ if (app.isSdkSandbox) {
+ ApplicationInfo clientInfo = app.getClientInfoForSdkSandbox();
+ if (clientInfo != null) {
+ debuggableFlag |= (clientInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
+ isProfileableByShell |= clientInfo.isProfileableByShell();
+ isProfileable |= clientInfo.isProfileable();
+ }
}
if (debuggableFlag) {
@@ -1741,10 +1749,10 @@
if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || mService.mSafeMode) {
runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
}
- if ((app.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_PROFILEABLE_BY_SHELL) != 0) {
+ if (isProfileableByShell) {
runtimeFlags |= Zygote.PROFILE_FROM_SHELL;
}
- if (app.info.isProfileable()) {
+ if (isProfileable) {
runtimeFlags |= Zygote.PROFILEABLE;
}
if ("1".equals(SystemProperties.get("debug.checkjni"))) {
@@ -1812,7 +1820,7 @@
}
String invokeWith = null;
- if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
+ if (debuggableFlag) {
// Debuggable apps may include a wrapper script with their library directory.
String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
@@ -1887,24 +1895,6 @@
}
}
- /** Return true if the client app for the SDK sandbox process is debuggable. */
- private boolean isAppForSdkSandboxDebuggable(ProcessRecord sandboxProcess) {
- // TODO (b/221004701) use client app process name
- final int appUid = Process.getAppUidForSdkSandboxUid(sandboxProcess.uid);
- IPackageManager pm = mService.getPackageManager();
- try {
- String[] packages = pm.getPackagesForUid(appUid);
- for (String aPackage : packages) {
- ApplicationInfo i = pm.getApplicationInfo(aPackage, 0, sandboxProcess.userId);
- if ((i.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
- return true;
- }
- }
- } catch (RemoteException e) {
- // shouldn't happen
- }
- return false;
- }
@GuardedBy("mService")
boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint, ProcessRecord app,
@@ -2365,7 +2355,7 @@
ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
int zygotePolicyFlags, boolean allowWhileBooting, boolean isolated, int isolatedUid,
- boolean isSdkSandbox, int sdkSandboxUid,
+ boolean isSdkSandbox, int sdkSandboxUid, String sdkSandboxClientAppPackage,
String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
long startTime = SystemClock.uptimeMillis();
ProcessRecord app;
@@ -2460,7 +2450,7 @@
if (app == null) {
checkSlow(startTime, "startProcess: creating new process record");
app = newProcessRecordLocked(info, processName, isolated, isolatedUid, isSdkSandbox,
- sdkSandboxUid, hostingRecord);
+ sdkSandboxUid, sdkSandboxClientAppPackage, hostingRecord);
if (app == null) {
Slog.w(TAG, "Failed making new process record for "
+ processName + "/" + info.uid + " isolated=" + isolated);
@@ -2956,7 +2946,7 @@
@GuardedBy("mService")
ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
boolean isolated, int isolatedUid, boolean isSdkSandbox, int sdkSandboxUid,
- HostingRecord hostingRecord) {
+ String sdkSandboxClientAppPackage, HostingRecord hostingRecord) {
String proc = customProcess != null ? customProcess : info.processName;
final int userId = UserHandle.getUserId(info.uid);
int uid = info.uid;
@@ -2992,6 +2982,7 @@
FrameworkStatsLog.ISOLATED_UID_CHANGED__EVENT__CREATED);
}
final ProcessRecord r = new ProcessRecord(mService, info, proc, uid,
+ sdkSandboxClientAppPackage,
hostingRecord.getDefiningUid(), hostingRecord.getDefiningProcessName());
final ProcessStateRecord state = r.mState;
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index f7cc3d7..b4ff870 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -27,6 +27,7 @@
import android.app.ApplicationExitInfo.SubReason;
import android.app.IApplicationThread;
import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManagerInternal;
import android.content.pm.ProcessInfo;
import android.content.pm.VersionedPackage;
import android.content.res.CompatibilityInfo;
@@ -84,6 +85,8 @@
final int uid; // uid of process; may be different from 'info' if isolated
final int userId; // user of process.
final String processName; // name of the process
+ final String sdkSandboxClientAppPackage; // if this is an sdk sandbox process, name of the
+ // app package for which it is running
/**
* Overall state of process's uid.
@@ -493,11 +496,12 @@
ProcessRecord(ActivityManagerService _service, ApplicationInfo _info, String _processName,
int _uid) {
- this(_service, _info, _processName, _uid, -1, null);
+ this(_service, _info, _processName, _uid, null, -1, null);
}
ProcessRecord(ActivityManagerService _service, ApplicationInfo _info, String _processName,
- int _uid, int _definingUid, String _definingProcessName) {
+ int _uid, String _sdkSandboxClientAppPackage, int _definingUid,
+ String _definingProcessName) {
mService = _service;
mProcLock = _service.mProcLock;
info = _info;
@@ -530,6 +534,7 @@
uid = _uid;
userId = UserHandle.getUserId(_uid);
processName = _processName;
+ sdkSandboxClientAppPackage = _sdkSandboxClientAppPackage;
mPersistent = false;
mRemoved = false;
mProfile = new ProcessProfileRecord(this);
@@ -861,6 +866,29 @@
return mDebugging;
}
+ @Nullable
+ public ApplicationInfo getClientInfoForSdkSandbox() {
+ if (!isSdkSandbox || sdkSandboxClientAppPackage == null) {
+ throw new IllegalStateException(
+ "getClientInfoForSdkSandbox called for non-sandbox process"
+ );
+ }
+ PackageManagerInternal pm = mService.getPackageManagerInternal();
+ return pm.getApplicationInfo(
+ sdkSandboxClientAppPackage, /* flags */0, Process.SYSTEM_UID, userId);
+ }
+
+ public boolean isDebuggable() {
+ if ((info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
+ return true;
+ }
+ if (isSdkSandbox) {
+ ApplicationInfo clientInfo = getClientInfoForSdkSandbox();
+ return clientInfo != null && (clientInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
+ }
+ return false;
+ }
+
@GuardedBy("mService")
void setDebugging(boolean debugging) {
mDebugging = debugging;
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index c53d4d6..795311f 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -96,6 +96,8 @@
final long createRealTime; // when this service was created
final boolean isSdkSandbox; // whether this is a sdk sandbox service
final int sdkSandboxClientAppUid; // the app uid for which this sdk sandbox service is running
+ final String sdkSandboxClientAppPackage; // the app package for which this sdk sandbox service
+ // is running
final ArrayMap<Intent.FilterComparison, IntentBindRecord> bindings
= new ArrayMap<Intent.FilterComparison, IntentBindRecord>();
// All active bindings to the service.
@@ -573,13 +575,14 @@
Intent.FilterComparison intent, ServiceInfo sInfo, boolean callerIsFg,
Runnable restarter) {
this(ams, name, instanceName, definingPackageName, definingUid, intent, sInfo, callerIsFg,
- restarter, null, 0);
+ restarter, null, 0, null);
}
ServiceRecord(ActivityManagerService ams, ComponentName name,
ComponentName instanceName, String definingPackageName, int definingUid,
Intent.FilterComparison intent, ServiceInfo sInfo, boolean callerIsFg,
- Runnable restarter, String sdkSandboxProcessName, int sdkSandboxClientAppUid) {
+ Runnable restarter, String sdkSandboxProcessName, int sdkSandboxClientAppUid,
+ String sdkSandboxClientAppPackage) {
this.ams = ams;
this.name = name;
this.instanceName = instanceName;
@@ -590,8 +593,9 @@
serviceInfo = sInfo;
appInfo = sInfo.applicationInfo;
packageName = sInfo.applicationInfo.packageName;
- isSdkSandbox = sdkSandboxProcessName != null;
+ this.isSdkSandbox = sdkSandboxProcessName != null;
this.sdkSandboxClientAppUid = sdkSandboxClientAppUid;
+ this.sdkSandboxClientAppPackage = sdkSandboxClientAppPackage;
if ((sInfo.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) != 0) {
processName = sInfo.processName + ":" + instanceName.getClassName();
} else if (sdkSandboxProcessName != null) {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 265ad7d..1885b55 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -630,6 +630,7 @@
private int mWarnRemoteViewsSizeBytes;
private int mStripRemoteViewsSizeBytes;
final boolean mEnableAppSettingMigration;
+ private boolean mForceUserSetOnUpgrade;
private MetricsLogger mMetricsLogger;
private TriPredicate<String, Integer, String> mAllowedManagedServicePackages;
@@ -2294,6 +2295,7 @@
mMsgPkgsAllowedAsConvos = Set.of(getStringArrayResource(
com.android.internal.R.array.config_notificationMsgPkgsAllowedAsConvos));
+
mStatsManager = statsManager;
mToastRateLimiter = toastRateLimiter;
@@ -2386,6 +2388,9 @@
WorkerHandler handler = new WorkerHandler(Looper.myLooper());
+ mForceUserSetOnUpgrade = getContext().getResources().getBoolean(
+ R.bool.config_notificationForceUserSetOnUpgrade);
+
init(handler, new RankingHandlerWorker(mRankingThread.getLooper()),
AppGlobals.getPackageManager(), getContext().getPackageManager(),
getLocalService(LightsManager.class),
@@ -2414,7 +2419,8 @@
LocalServices.getService(ActivityManagerInternal.class),
createToastRateLimiter(), new PermissionHelper(LocalServices.getService(
PermissionManagerServiceInternal.class), AppGlobals.getPackageManager(),
- AppGlobals.getPermissionManager(), mEnableAppSettingMigration),
+ AppGlobals.getPermissionManager(), mEnableAppSettingMigration,
+ mForceUserSetOnUpgrade),
LocalServices.getService(UsageStatsManagerInternal.class));
publishBinderService(Context.NOTIFICATION_SERVICE, mService, /* allowIsolated= */ false,
@@ -6069,6 +6075,7 @@
pw.println(" mMaxPackageEnqueueRate=" + mMaxPackageEnqueueRate);
pw.println(" hideSilentStatusBar="
+ mPreferencesHelper.shouldHideSilentStatusIcons());
+ pw.println(" mForceUserSetOnUpgrade=" + mForceUserSetOnUpgrade);
}
pw.println(" mArchive=" + mArchive.toString());
mArchive.dumpImpl(pw, filter);
diff --git a/services/core/java/com/android/server/notification/PermissionHelper.java b/services/core/java/com/android/server/notification/PermissionHelper.java
index e551f10..b4230c1 100644
--- a/services/core/java/com/android/server/notification/PermissionHelper.java
+++ b/services/core/java/com/android/server/notification/PermissionHelper.java
@@ -57,13 +57,16 @@
private final IPermissionManager mPermManager;
// TODO (b/194833441): Remove when the migration is enabled
private final boolean mMigrationEnabled;
+ private final boolean mForceUserSetOnUpgrade;
public PermissionHelper(PermissionManagerServiceInternal pmi, IPackageManager packageManager,
- IPermissionManager permManager, boolean migrationEnabled) {
+ IPermissionManager permManager, boolean migrationEnabled,
+ boolean forceUserSetOnUpgrade) {
mPmi = pmi;
mPackageManager = packageManager;
mPermManager = permManager;
mMigrationEnabled = migrationEnabled;
+ mForceUserSetOnUpgrade = forceUserSetOnUpgrade;
}
public boolean isMigrationEnabled() {
@@ -223,8 +226,9 @@
return;
}
if (!isPermissionFixed(pkgPerm.packageName, pkgPerm.userId)) {
+ boolean userSet = mForceUserSetOnUpgrade ? true : pkgPerm.userModifiedSettings;
setNotificationPermission(pkgPerm.packageName, pkgPerm.userId, pkgPerm.granted,
- pkgPerm.userSet, !pkgPerm.userSet);
+ userSet, !userSet);
}
}
@@ -305,13 +309,13 @@
public final String packageName;
public final @UserIdInt int userId;
public final boolean granted;
- public final boolean userSet;
+ public final boolean userModifiedSettings;
public PackagePermission(String pkg, int userId, boolean granted, boolean userSet) {
this.packageName = pkg;
this.userId = userId;
this.granted = granted;
- this.userSet = userSet;
+ this.userModifiedSettings = userSet;
}
@Override
@@ -319,13 +323,14 @@
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PackagePermission that = (PackagePermission) o;
- return userId == that.userId && granted == that.granted && userSet == that.userSet
+ return userId == that.userId && granted == that.granted && userModifiedSettings
+ == that.userModifiedSettings
&& Objects.equals(packageName, that.packageName);
}
@Override
public int hashCode() {
- return Objects.hash(packageName, userId, granted, userSet);
+ return Objects.hash(packageName, userId, granted, userModifiedSettings);
}
@Override
@@ -334,7 +339,7 @@
"packageName='" + packageName + '\'' +
", userId=" + userId +
", granted=" + granted +
- ", userSet=" + userSet +
+ ", userSet=" + userModifiedSettings +
'}';
}
}
diff --git a/services/core/java/com/android/server/pm/InitAndSystemPackageHelper.java b/services/core/java/com/android/server/pm/InitAndSystemPackageHelper.java
index f452b29..91750de 100644
--- a/services/core/java/com/android/server/pm/InitAndSystemPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InitAndSystemPackageHelper.java
@@ -30,6 +30,7 @@
import static com.android.server.pm.PackageManagerService.SCAN_REQUIRE_KNOWN;
import static com.android.server.pm.PackageManagerService.SYSTEM_PARTITIONS;
import static com.android.server.pm.PackageManagerService.TAG;
+import static com.android.server.pm.pkg.parsing.ParsingPackageUtils.PARSE_CHECK_MAX_SDK_VERSION;
import android.annotation.Nullable;
import android.content.pm.parsing.ApkLiteParseUtils;
@@ -313,10 +314,14 @@
@GuardedBy({"mPm.mInstallLock", "mPm.mLock"})
private void scanDirTracedLI(File scanDir, List<File> frameworkSplits,
- final int parseFlags, int scanFlags,
+ int parseFlags, int scanFlags,
long currentTime, PackageParser2 packageParser, ExecutorService executorService) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + scanDir.getAbsolutePath() + "]");
try {
+ if ((scanFlags & SCAN_AS_APK_IN_APEX) != 0) {
+ // when scanning apk in apexes, we want to check the maxSdkVersion
+ parseFlags |= PARSE_CHECK_MAX_SDK_VERSION;
+ }
mInstallPackageHelper.installPackagesFromDir(scanDir, frameworkSplits, parseFlags,
scanFlags, currentTime, packageParser, executorService);
} finally {
diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java
index cbba346..40f859c 100644
--- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java
+++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java
@@ -302,6 +302,8 @@
ParsingPackage setMinSdkVersion(int minSdkVersion);
+ ParsingPackage setMaxSdkVersion(int maxSdkVersion);
+
ParsingPackage setNetworkSecurityConfigRes(int networkSecurityConfigRes);
ParsingPackage setNonLocalizedLabel(CharSequence nonLocalizedLabel);
diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageImpl.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageImpl.java
index 1484df8..67d9aec 100644
--- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageImpl.java
+++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageImpl.java
@@ -383,6 +383,7 @@
@Nullable
private SparseIntArray minExtensionVersions;
private int minSdkVersion = ParsingUtils.DEFAULT_MIN_SDK_VERSION;
+ private int maxSdkVersion = ParsingUtils.DEFAULT_MAX_SDK_VERSION;
private int networkSecurityConfigRes;
@Nullable
private CharSequence nonLocalizedLabel;
@@ -1306,6 +1307,7 @@
dest.writeFloat(this.maxAspectRatio);
dest.writeFloat(this.minAspectRatio);
dest.writeInt(this.minSdkVersion);
+ dest.writeInt(this.maxSdkVersion);
dest.writeInt(this.networkSecurityConfigRes);
dest.writeCharSequence(this.nonLocalizedLabel);
dest.writeString(this.permission);
@@ -1454,6 +1456,7 @@
this.maxAspectRatio = in.readFloat();
this.minAspectRatio = in.readFloat();
this.minSdkVersion = in.readInt();
+ this.maxSdkVersion = in.readInt();
this.networkSecurityConfigRes = in.readInt();
this.nonLocalizedLabel = in.readCharSequence();
this.permission = in.readString();
@@ -2068,6 +2071,11 @@
}
@Override
+ public int getMaxSdkVersion() {
+ return maxSdkVersion;
+ }
+
+ @Override
public int getNetworkSecurityConfigRes() {
return networkSecurityConfigRes;
}
@@ -2592,6 +2600,12 @@
}
@Override
+ public ParsingPackageImpl setMaxSdkVersion(int value) {
+ maxSdkVersion = value;
+ return this;
+ }
+
+ @Override
public ParsingPackageImpl setNetworkSecurityConfigRes(int value) {
networkSecurityConfigRes = value;
return this;
diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
index 112b9e0..b323948 100644
--- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
+++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
@@ -209,6 +209,8 @@
public static final int SDK_VERSION = Build.VERSION.SDK_INT;
public static final String[] SDK_CODENAMES = Build.VERSION.ACTIVE_CODENAMES;
+ public static final String[] PREVIOUS_CODENAMES =
+ Build.VERSION.KNOWN_CODENAMES.toArray(new String[]{});
public static boolean sCompatibilityModeEnabled = true;
public static boolean sUseRoundIcon = false;
@@ -236,6 +238,7 @@
*/
public static final int PARSE_IGNORE_OVERLAY_REQUIRED_SYSTEM_PROPERTY = 1 << 7;
public static final int PARSE_FRAMEWORK_RES_SPLITS = 1 << 8;
+ public static final int PARSE_CHECK_MAX_SDK_VERSION = 1 << 9;
public static final int PARSE_CHATTY = 1 << 31;
@@ -1002,7 +1005,7 @@
case TAG_FEATURE_GROUP:
return parseFeatureGroup(input, pkg, res, parser);
case TAG_USES_SDK:
- return parseUsesSdk(input, pkg, res, parser);
+ return parseUsesSdk(input, pkg, res, parser, flags);
case TAG_SUPPORT_SCREENS:
return parseSupportScreens(input, pkg, res, parser);
case TAG_PROTECTED_BROADCAST:
@@ -1514,15 +1517,17 @@
}
private static ParseResult<ParsingPackage> parseUsesSdk(ParseInput input,
- ParsingPackage pkg, Resources res, XmlResourceParser parser)
+ ParsingPackage pkg, Resources res, XmlResourceParser parser, int flags)
throws IOException, XmlPullParserException {
if (SDK_VERSION > 0) {
+ final boolean checkMaxSdkVersion = (flags & PARSE_CHECK_MAX_SDK_VERSION) != 0;
TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestUsesSdk);
try {
int minVers = ParsingUtils.DEFAULT_MIN_SDK_VERSION;
String minCode = null;
int targetVers = ParsingUtils.DEFAULT_TARGET_SDK_VERSION;
String targetCode = null;
+ int maxVers = Integer.MAX_VALUE;
TypedValue val = sa.peekValue(R.styleable.AndroidManifestUsesSdk_minSdkVersion);
if (val != null) {
@@ -1550,6 +1555,14 @@
targetCode = minCode;
}
+ if (checkMaxSdkVersion) {
+ val = sa.peekValue(R.styleable.AndroidManifestUsesSdk_maxSdkVersion);
+ if (val != null) {
+ // maxSdkVersion only supports integer
+ maxVers = val.data;
+ }
+ }
+
ParseResult<Integer> targetSdkVersionResult = FrameworkParsingPackageUtils
.computeTargetSdkVersion(targetVers, targetCode, SDK_CODENAMES, input);
if (targetSdkVersionResult.isError()) {
@@ -1574,6 +1587,15 @@
pkg.setMinSdkVersion(minSdkVersion)
.setTargetSdkVersion(targetSdkVersion);
+ if (checkMaxSdkVersion) {
+ ParseResult<Integer> maxSdkVersionResult = FrameworkParsingPackageUtils
+ .computeMaxSdkVersion(maxVers, SDK_VERSION, input);
+ if (maxSdkVersionResult.isError()) {
+ return input.error(maxSdkVersionResult);
+ }
+ int maxSdkVersion = maxSdkVersionResult.getResult();
+ pkg.setMaxSdkVersion(maxSdkVersion);
+ }
int type;
final int innerDepth = parser.getDepth();
diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingUtils.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingUtils.java
index cb474df..0751285 100644
--- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingUtils.java
+++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingUtils.java
@@ -50,6 +50,7 @@
public static final String ANDROID_RES_NAMESPACE = "http://schemas.android.com/apk/res/android";
public static final int DEFAULT_MIN_SDK_VERSION = 1;
+ public static final int DEFAULT_MAX_SDK_VERSION = Integer.MAX_VALUE;
public static final int DEFAULT_TARGET_SDK_VERSION = 0;
public static final int NOT_SET = -1;
diff --git a/services/core/java/com/android/server/pm/pkg/parsing/PkgWithoutStateAppInfo.java b/services/core/java/com/android/server/pm/pkg/parsing/PkgWithoutStateAppInfo.java
index 3205b76..99bcdb96 100644
--- a/services/core/java/com/android/server/pm/pkg/parsing/PkgWithoutStateAppInfo.java
+++ b/services/core/java/com/android/server/pm/pkg/parsing/PkgWithoutStateAppInfo.java
@@ -250,6 +250,11 @@
int getMinSdkVersion();
/**
+ * @see R.styleable#AndroidManifestUsesSdk_maxSdkVersion
+ */
+ int getMaxSdkVersion();
+
+ /**
* @see ApplicationInfo#getNativeHeapZeroInitialized()
* @see R.styleable#AndroidManifestApplication_nativeHeapZeroInitialized
*/
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 59b9daf..8087738 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -36,6 +36,7 @@
import android.app.StatusBarManager;
import android.app.compat.CompatChanges;
import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledAfter;
import android.compat.annotation.EnabledSince;
import android.content.ComponentName;
import android.content.Context;
@@ -135,6 +136,17 @@
@EnabledSince(targetSdkVersion = Build.VERSION_CODES.S)
private static final long LOCK_DOWN_COLLAPSE_STATUS_BAR = 173031413L;
+ /**
+ * In apps targeting {@link android.os.Build.VERSION_CODES#TIRAMISU} or higher, calling
+ * {@link android.service.quicksettings.TileService#requestListeningState} will check that the
+ * calling package (uid) and the package of the target {@link android.content.ComponentName}
+ * match. It'll also make sure that the context used can take actions on behalf of the current
+ * user.
+ */
+ @ChangeId
+ @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.S_V2)
+ static final long REQUEST_LISTENING_MUST_MATCH_PACKAGE = 172251878L;
+
private final Context mContext;
private final Handler mHandler = new Handler();
@@ -1652,6 +1664,7 @@
@Override
public void hideCurrentInputMethodForBubbles() {
+ enforceStatusBarService();
final long token = Binder.clearCallingIdentity();
try {
InputMethodManagerInternal.get().hideCurrentInputMethod(
@@ -1776,6 +1789,42 @@
}
@Override
+ public void requestTileServiceListeningState(
+ @NonNull ComponentName componentName,
+ int userId
+ ) {
+ int callingUid = Binder.getCallingUid();
+ String packageName = componentName.getPackageName();
+
+ boolean mustPerformChecks = CompatChanges.isChangeEnabled(
+ REQUEST_LISTENING_MUST_MATCH_PACKAGE, callingUid);
+
+ if (mustPerformChecks) {
+ // Check calling user can act on behalf of current user
+ userId = mActivityManagerInternal.handleIncomingUser(Binder.getCallingPid(), callingUid,
+ userId, false, ActivityManagerInternal.ALLOW_NON_FULL,
+ "requestTileServiceListeningState", packageName);
+
+ // Check calling uid matches package
+ checkCallingUidPackage(packageName, callingUid, userId);
+
+ int currentUser = mActivityManagerInternal.getCurrentUserId();
+
+ // Check current user
+ if (userId != currentUser) {
+ throw new IllegalArgumentException("User " + userId + " is not the current user.");
+ }
+ }
+ if (mBar != null) {
+ try {
+ mBar.requestTileServiceListeningState(componentName);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "requestTileServiceListeningState", e);
+ }
+ }
+ }
+
+ @Override
public void requestAddTile(
@NonNull ComponentName componentName,
@NonNull CharSequence label,
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index bd4b8d1..cc1d0e2 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -715,7 +715,7 @@
(disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0;
List<ComponentName> enabledAgents = lockPatternUtils.getEnabledTrustAgents(userInfo.id);
- if (enabledAgents == null) {
+ if (enabledAgents.isEmpty()) {
if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
+ ": no agents enabled by user");
continue;
@@ -1080,9 +1080,7 @@
}
List<ComponentName> previouslyEnabledAgents = utils.getEnabledTrustAgents(userId);
- if (previouslyEnabledAgents != null) {
- discoveredAgents.addAll(previouslyEnabledAgents);
- }
+ discoveredAgents.addAll(previouslyEnabledAgents);
utils.setEnabledTrustAgents(discoveredAgents, userId);
Settings.Secure.putIntForUser(mContext.getContentResolver(),
Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, userId);
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 2355333..94fc51d 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -3376,11 +3376,17 @@
return new ArrayList<>();
}
} else {
+ final RecentTasks recentTasks = mWindowManager.mAtmService.getRecentTasks();
+ final int recentsComponentUid = recentTasks != null
+ ? recentTasks.getRecentsComponentUid()
+ : -1;
final ArrayList<ActivityRecord> activities = new ArrayList<>();
- forAllRootTasks(rootTask -> {
- if (!dumpVisibleRootTasksOnly || rootTask.shouldBeVisible(null)) {
- activities.addAll(rootTask.getDumpActivitiesLocked(name, userId));
+ forAllLeafTasks(task -> {
+ final boolean isRecents = (task.effectiveUid == recentsComponentUid);
+ if (!dumpVisibleRootTasksOnly || task.shouldBeVisible(null) || isRecents) {
+ activities.addAll(task.getDumpActivitiesLocked(name, userId));
}
+ return false;
});
return activities;
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
index 1cf4c1b..5a2f28f 100644
--- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
+++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
@@ -566,9 +566,14 @@
try (ZipOutputStream out = new ZipOutputStream(getRawOutputStream())) {
ArrayList<Pair<String, ByteTransferPipe>> requestList = new ArrayList<>();
synchronized (mInternal.mGlobalLock) {
+ final RecentTasks recentTasks = mInternal.mAtmService.getRecentTasks();
+ final int recentsComponentUid = recentTasks != null
+ ? recentTasks.getRecentsComponentUid()
+ : -1;
// Request dump from all windows parallelly before writing to disk.
mInternal.mRoot.forAllWindows(w -> {
- if (w.isVisible()) {
+ final boolean isRecents = (w.getUid() == recentsComponentUid);
+ if (w.isVisible() || isRecents) {
ByteTransferPipe pipe = null;
try {
pipe = new ByteTransferPipe();
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index 1c6a3b5..0cd9494 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -106,7 +106,6 @@
register_android_server_HardwarePropertiesManagerService(env);
register_android_server_storage_AppFuse(env);
register_android_server_SyntheticPasswordManager(env);
- register_android_graphics_GraphicsStatsService(env);
register_android_hardware_display_DisplayViewport(env);
register_android_server_am_CachedAppOptimizer(env);
register_android_server_am_LowMemDetector(env);
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index c8eaa23..f7c66c5 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -293,8 +293,6 @@
"com.android.server.wifi.p2p.WifiP2pService";
private static final String LOWPAN_SERVICE_CLASS =
"com.android.server.lowpan.LowpanService";
- private static final String ETHERNET_SERVICE_CLASS =
- "com.android.server.ethernet.EthernetService";
private static final String JOB_SCHEDULER_SERVICE_CLASS =
"com.android.server.job.JobSchedulerService";
private static final String LOCK_SETTINGS_SERVICE_CLASS =
@@ -1995,13 +1993,6 @@
t.traceEnd();
}
- if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET) ||
- mPackageManager.hasSystemFeature(PackageManager.FEATURE_USB_HOST)) {
- t.traceBegin("StartEthernet");
- mSystemServiceManager.startService(ETHERNET_SERVICE_CLASS);
- t.traceEnd();
- }
-
t.traceBegin("StartPacProxyService");
try {
pacProxyService = new PacProxyService(context);
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/SharedLibrariesImplTest.kt b/services/tests/mockingservicestests/src/com/android/server/pm/SharedLibrariesImplTest.kt
index 1515282..97b52a9 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/SharedLibrariesImplTest.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/SharedLibrariesImplTest.kt
@@ -24,7 +24,6 @@
import android.os.storage.StorageManager
import android.util.ArrayMap
import android.util.PackageUtils
-import com.android.internal.util.FunctionalUtils
import com.android.server.SystemConfig.SharedLibraryEntry
import com.android.server.compat.PlatformCompat
import com.android.server.extendedtestutils.wheneverStatic
@@ -35,7 +34,6 @@
import com.android.server.testutils.any
import com.android.server.testutils.eq
import com.android.server.testutils.mock
-import com.android.server.testutils.mockThrowOnUnmocked
import com.android.server.testutils.nullable
import com.android.server.testutils.spy
import com.android.server.testutils.whenever
@@ -59,6 +57,7 @@
import kotlin.test.assertFalse
import kotlin.test.assertTrue
+@Ignore("b/216603387")
@RunWith(JUnit4::class)
class SharedLibrariesImplTest {
@@ -249,7 +248,6 @@
assertThat(testPackageSetting.usesLibraryFiles).contains(builtinLibPath(BUILTIN_LIB_NAME))
}
- @Ignore("b/216603387")
@Test
fun updateSharedLibraries_withStaticLibPackage() {
val testPackageSetting = mExistingSettings[STATIC_LIB_PACKAGE_NAME]!!
@@ -262,7 +260,6 @@
assertThat(testPackageSetting.usesLibraryFiles).contains(apkPath(DYNAMIC_LIB_PACKAGE_NAME))
}
- @Ignore("b/216603387")
@Test
fun updateSharedLibraries_withConsumerPackage() {
val testPackageSetting = mExistingSettings[CONSUMER_PACKAGE_NAME]!!
@@ -276,7 +273,6 @@
assertThat(testPackageSetting.usesLibraryFiles).contains(apkPath(STATIC_LIB_PACKAGE_NAME))
}
- @Ignore("b/216603387")
@Test
fun updateAllSharedLibraries() {
mExistingSettings.forEach {
diff --git a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
index 4de15c8..928c76d 100644
--- a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
@@ -330,11 +330,12 @@
@Test
public void testPriorityPersisted() throws Exception {
- final JobInfo.Builder b = new Builder(92, mComponent)
+ final JobInfo job = new Builder(92, mComponent)
.setOverrideDeadline(5000)
.setPriority(JobInfo.PRIORITY_MIN)
- .setPersisted(true);
- final JobStatus js = JobStatus.createFromJobInfo(b.build(), SOME_UID, null, -1, null);
+ .setPersisted(true)
+ .build();
+ final JobStatus js = JobStatus.createFromJobInfo(job, SOME_UID, null, -1, null);
mTaskStoreUnderTest.add(js);
waitForPendingIo();
@@ -342,7 +343,7 @@
mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet, true);
final JobStatus loaded = jobStatusSet.getAllJobs().iterator().next();
assertEquals("Priority not correctly persisted.",
- JobInfo.PRIORITY_MIN, loaded.getEffectivePriority());
+ JobInfo.PRIORITY_MIN, job.getPriority());
}
/**
diff --git a/services/tests/servicestests/src/com/android/server/statusbar/StatusBarManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/statusbar/StatusBarManagerServiceTest.java
index 1442f1c..d76a1de 100644
--- a/services/tests/servicestests/src/com/android/server/statusbar/StatusBarManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/statusbar/StatusBarManagerServiceTest.java
@@ -23,9 +23,11 @@
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.anyLong;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.argThat;
import static org.mockito.Mockito.eq;
@@ -37,6 +39,7 @@
import android.Manifest;
import android.app.ActivityManagerInternal;
import android.app.StatusBarManager;
+import android.compat.testing.PlatformCompatChangeRule;
import android.content.ComponentName;
import android.content.Intent;
import android.content.om.IOverlayManager;
@@ -62,10 +65,13 @@
import com.android.server.policy.GlobalActionsProvider;
import com.android.server.wm.ActivityTaskManagerInternal;
+import libcore.junit.util.compat.CoreCompatChangeRule;
+
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.ArgumentCaptor;
@@ -73,6 +79,7 @@
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.mockito.stubbing.Answer;
@RunWith(JUnit4.class)
public class StatusBarManagerServiceTest {
@@ -88,6 +95,9 @@
public final TestableContext mContext =
new NoBroadcastContextWrapper(InstrumentationRegistry.getContext());
+ @Rule
+ public TestRule mCompatChangeRule = new PlatformCompatChangeRule();
+
@Mock
private ActivityTaskManagerInternal mActivityTaskManagerInternal;
@Mock
@@ -127,6 +137,7 @@
when(mMockStatusBar.asBinder()).thenReturn(mMockStatusBar);
when(mApplicationInfo.loadLabel(any())).thenReturn(APP_NAME);
+ mockHandleIncomingUser();
mStatusBarManagerService = new StatusBarManagerService(mContext);
LocalServices.removeServiceForTest(StatusBarManagerInternal.class);
@@ -142,6 +153,80 @@
}
@Test
+ @CoreCompatChangeRule.EnableCompatChanges(
+ {StatusBarManagerService.REQUEST_LISTENING_MUST_MATCH_PACKAGE})
+ public void testRequestActive_changeEnabled_OKCall() throws RemoteException {
+ int user = 0;
+ mockEverything(user);
+ mStatusBarManagerService.requestTileServiceListeningState(TEST_COMPONENT, user);
+
+ verify(mMockStatusBar).requestTileServiceListeningState(TEST_COMPONENT);
+ }
+
+ @Test
+ @CoreCompatChangeRule.EnableCompatChanges(
+ {StatusBarManagerService.REQUEST_LISTENING_MUST_MATCH_PACKAGE})
+ public void testRequestActive_changeEnabled_differentPackage_fail() throws RemoteException {
+ when(mPackageManagerInternal.getPackageUid(TEST_PACKAGE, 0L, mContext.getUserId()))
+ .thenReturn(Binder.getCallingUid() + 1);
+ try {
+ mStatusBarManagerService.requestTileServiceListeningState(TEST_COMPONENT, 0);
+ fail("Should cause security exception");
+ } catch (SecurityException e) { }
+ verify(mMockStatusBar, never()).requestTileServiceListeningState(TEST_COMPONENT);
+ }
+
+ @Test
+ @CoreCompatChangeRule.EnableCompatChanges(
+ {StatusBarManagerService.REQUEST_LISTENING_MUST_MATCH_PACKAGE})
+ public void testRequestActive_changeEnabled_notCurrentUser_fail() throws RemoteException {
+ mockUidCheck();
+ int user = 0;
+ mockCurrentUserCheck(user);
+ try {
+ mStatusBarManagerService.requestTileServiceListeningState(TEST_COMPONENT, user + 1);
+ fail("Should cause illegal argument exception");
+ } catch (IllegalArgumentException e) { }
+
+ // Do not call into SystemUI
+ verify(mMockStatusBar, never()).requestTileServiceListeningState(TEST_COMPONENT);
+ }
+
+ @Test
+ @CoreCompatChangeRule.DisableCompatChanges(
+ {StatusBarManagerService.REQUEST_LISTENING_MUST_MATCH_PACKAGE})
+ public void testRequestActive_changeDisabled_pass() throws RemoteException {
+ int user = 0;
+ mockEverything(user);
+ mStatusBarManagerService.requestTileServiceListeningState(TEST_COMPONENT, user);
+
+ verify(mMockStatusBar).requestTileServiceListeningState(TEST_COMPONENT);
+ }
+
+ @Test
+ @CoreCompatChangeRule.DisableCompatChanges(
+ {StatusBarManagerService.REQUEST_LISTENING_MUST_MATCH_PACKAGE})
+ public void testRequestActive_changeDisabled_differentPackage_pass() throws RemoteException {
+ when(mPackageManagerInternal.getPackageUid(TEST_PACKAGE, 0L, mContext.getUserId()))
+ .thenReturn(Binder.getCallingUid() + 1);
+ mStatusBarManagerService.requestTileServiceListeningState(TEST_COMPONENT, 0);
+
+ verify(mMockStatusBar).requestTileServiceListeningState(TEST_COMPONENT);
+ }
+
+ @Test
+ @CoreCompatChangeRule.DisableCompatChanges(
+ {StatusBarManagerService.REQUEST_LISTENING_MUST_MATCH_PACKAGE})
+ public void testRequestActive_changeDisabled_notCurrentUser_pass() throws RemoteException {
+ mockUidCheck();
+ int user = 0;
+ mockCurrentUserCheck(user);
+ mStatusBarManagerService.requestTileServiceListeningState(TEST_COMPONENT, user + 1);
+
+ verify(mMockStatusBar).requestTileServiceListeningState(TEST_COMPONENT);
+ }
+
+ @Test
public void testHandleIncomingUserCalled() {
int fakeUser = 17;
try {
@@ -252,7 +337,7 @@
mockCurrentUserCheck(user);
IntentMatcher im = new IntentMatcher(
new Intent(TileService.ACTION_QS_TILE).setComponent(TEST_COMPONENT));
- when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0),
+ when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0L),
eq(user), anyInt())).thenReturn(null);
Callback callback = new Callback();
@@ -272,7 +357,7 @@
IntentMatcher im = new IntentMatcher(
new Intent(TileService.ACTION_QS_TILE).setComponent(TEST_COMPONENT));
- when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0),
+ when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0L),
eq(user), anyInt())).thenReturn(r);
when(mPackageManagerInternal.getComponentEnabledSetting(TEST_COMPONENT,
Binder.getCallingUid(), user)).thenReturn(
@@ -294,7 +379,7 @@
IntentMatcher im = new IntentMatcher(
new Intent(TileService.ACTION_QS_TILE).setComponent(TEST_COMPONENT));
- when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0),
+ when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0L),
eq(user), anyInt())).thenReturn(r);
when(mPackageManagerInternal.getComponentEnabledSetting(TEST_COMPONENT,
Binder.getCallingUid(), user)).thenReturn(
@@ -318,7 +403,7 @@
IntentMatcher im = new IntentMatcher(
new Intent(TileService.ACTION_QS_TILE).setComponent(TEST_COMPONENT));
- when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0),
+ when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0L),
eq(user), anyInt())).thenReturn(r);
when(mPackageManagerInternal.getComponentEnabledSetting(TEST_COMPONENT,
Binder.getCallingUid(), user)).thenReturn(
@@ -342,7 +427,7 @@
IntentMatcher im = new IntentMatcher(
new Intent(TileService.ACTION_QS_TILE).setComponent(TEST_COMPONENT));
- when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0),
+ when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0L),
eq(user), anyInt())).thenReturn(r);
when(mPackageManagerInternal.getComponentEnabledSetting(TEST_COMPONENT,
Binder.getCallingUid(), user)).thenReturn(
@@ -641,7 +726,7 @@
}
private void mockUidCheck(String packageName) {
- when(mPackageManagerInternal.getPackageUid(eq(packageName), anyInt(), anyInt()))
+ when(mPackageManagerInternal.getPackageUid(eq(packageName), anyLong(), anyInt()))
.thenReturn(Binder.getCallingUid());
}
@@ -667,7 +752,7 @@
IntentMatcher im = new IntentMatcher(
new Intent(TileService.ACTION_QS_TILE).setComponent(componentName));
- when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0),
+ when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0L),
eq(user), anyInt())).thenReturn(r);
when(mPackageManagerInternal.getComponentEnabledSetting(componentName,
Binder.getCallingUid(), user)).thenReturn(
@@ -679,6 +764,15 @@
PROCESS_STATE_TOP);
}
+ private void mockHandleIncomingUser() {
+ when(mActivityManagerInternal.handleIncomingUser(anyInt(), anyInt(), anyInt(), anyBoolean(),
+ anyInt(), anyString(), anyString())).thenAnswer(
+ (Answer<Integer>) invocation -> {
+ return invocation.getArgument(2); // same user
+ }
+ );
+ }
+
private void mockEverything(int user) {
mockUidCheck();
mockCurrentUserCheck(user);
diff --git a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
index 1ce957d..210d2fa 100644
--- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
@@ -62,7 +62,10 @@
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.intThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
@@ -76,11 +79,13 @@
import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.ContextWrapper;
+import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
+import android.content.pm.ResolveInfo;
import android.hardware.display.DisplayManager;
import android.os.Handler;
import android.os.Looper;
@@ -118,6 +123,7 @@
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
/**
* Unit test for AppStandbyController.
@@ -421,8 +427,31 @@
pib.packageName = PACKAGE_BACKGROUND_LOCATION;
packages.add(pib);
- doReturn(packages).when(mockPm).getInstalledPackagesAsUser(anyInt(), anyInt());
+ // Set up getInstalledPackagesAsUser().
+ doReturn(packages).when(mockPm).getInstalledPackagesAsUser(anyInt(),
+ anyInt());
+
+ // Set up getInstalledPackagesAsUser() for "MATCH_ONLY_SYSTEM"
+ doReturn(
+ packages.stream().filter(pinfo -> pinfo.applicationInfo.isSystemApp())
+ .collect(Collectors.toList())
+ ).when(mockPm).getInstalledPackagesAsUser(
+ intThat(i -> (i & PackageManager.MATCH_SYSTEM_ONLY) != 0),
+ anyInt());
+
+ // Set up queryIntentActivitiesAsUser()
+ final ArrayList<ResolveInfo> systemFrontDoorActivities = new ArrayList<>();
+ final ResolveInfo frontDoorActivity = new ResolveInfo();
+ frontDoorActivity.activityInfo = new ActivityInfo();
+ frontDoorActivity.activityInfo.packageName = pis.packageName;
+ systemFrontDoorActivities.add(frontDoorActivity);
+ doReturn(systemFrontDoorActivities).when(mockPm)
+ .queryIntentActivitiesAsUser(any(Intent.class),
+ intThat(i -> (i & PackageManager.MATCH_SYSTEM_ONLY) != 0),
+ anyInt());
+
+ // Set up other APIs.
try {
for (int i = 0; i < packages.size(); ++i) {
PackageInfo pkg = packages.get(i);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java
index 50151bf..46b47f4 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java
@@ -88,7 +88,7 @@
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
- mPermissionHelper = new PermissionHelper(mPmi, mPackageManager, mPermManager, true);
+ mPermissionHelper = new PermissionHelper(mPmi, mPackageManager, mPermManager, true, false);
PackageInfo testPkgInfo = new PackageInfo();
testPkgInfo.requestedPermissions = new String[]{ Manifest.permission.POST_NOTIFICATIONS };
when(mPackageManager.getPackageInfo(anyString(), anyLong(), anyInt()))
@@ -100,7 +100,7 @@
public void testMethodsThrowIfMigrationDisabled() throws IllegalAccessException,
InvocationTargetException {
PermissionHelper permHelper =
- new PermissionHelper(mPmi, mPackageManager, mPermManager, false);
+ new PermissionHelper(mPmi, mPackageManager, mPermManager, false, false);
Method[] allMethods = PermissionHelper.class.getDeclaredMethods();
for (Method method : allMethods) {
@@ -302,6 +302,26 @@
}
@Test
+ public void testSetNotificationPermission_pkgPerm_grantedByDefaultPermSet_allUserSet()
+ throws Exception {
+ mPermissionHelper = new PermissionHelper(mPmi, mPackageManager, mPermManager, true, true);
+ when(mPmi.checkPermission(anyString(), anyString(), anyInt()))
+ .thenReturn(PERMISSION_DENIED);
+ when(mPermManager.getPermissionFlags(anyString(),
+ eq(Manifest.permission.POST_NOTIFICATIONS),
+ anyInt())).thenReturn(FLAG_PERMISSION_GRANTED_BY_DEFAULT);
+ PermissionHelper.PackagePermission pkgPerm = new PermissionHelper.PackagePermission(
+ "pkg", 10, true, false);
+
+ mPermissionHelper.setNotificationPermission(pkgPerm);
+ verify(mPermManager).grantRuntimePermission(
+ "pkg", Manifest.permission.POST_NOTIFICATIONS, 10);
+ verify(mPermManager).updatePermissionFlags("pkg", Manifest.permission.POST_NOTIFICATIONS,
+ FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_REVIEW_REQUIRED,
+ FLAG_PERMISSION_USER_SET, true, 10);
+ }
+
+ @Test
public void testSetNotificationPermission_revokeUserSet() throws Exception {
when(mPmi.checkPermission(anyString(), anyString(), anyInt()))
.thenReturn(PERMISSION_GRANTED);
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 1eb391d..5ef22de 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -16790,7 +16790,10 @@
* Callback to listen for when the set of packages with carrier privileges for a SIM changes.
*
* @hide
+ * @deprecated Use {@link CarrierPrivilegesCallback} instead. This API will be removed soon
+ * prior to API finalization.
*/
+ @Deprecated
@SystemApi
public interface CarrierPrivilegesListener {
/**
@@ -16810,6 +16813,54 @@
}
/**
+ * Callbacks to listen for when the set of packages with carrier privileges for a SIM changes.
+ *
+ * <p>Of note, when multiple callbacks are registered, they may be triggered one after another.
+ * The ordering of them is not guaranteed and thus should not be depend on.
+ *
+ * @hide
+ */
+ @SystemApi
+ public interface CarrierPrivilegesCallback {
+ /**
+ * Called when the set of packages with carrier privileges has changed.
+ *
+ * <p>Of note, this callback will <b>not</b> be fired if a carrier triggers a SIM profile
+ * switch and the same set of packages remains privileged after the switch.
+ *
+ * <p>At registration, the callback will receive the current set of privileged packages.
+ *
+ * @param privilegedPackageNames The updated set of package names that have carrier
+ * privileges
+ * @param privilegedUids The updated set of UIDs that have carrier privileges
+ */
+ void onCarrierPrivilegesChanged(
+ @NonNull Set<String> privilegedPackageNames, @NonNull Set<Integer> privilegedUids);
+
+ /**
+ * Called when the {@link CarrierService} for the current user profile has changed.
+ *
+ * <p>This method does nothing by default. Clients that are interested in the carrier
+ * service change should override this method to get package name and UID info.
+ *
+ * <p>At registration, the callback will receive the current carrier service info.
+ *
+ * <p>Of note, this callback will <b>not</b> be fired if a carrier triggers a SIM profile
+ * switch and the same carrier service remains after switch.
+ *
+ * @param carrierServicePackageName package name of the {@link CarrierService}. May be
+ * {@code null} when no carrier service is detected.
+ * @param carrierServiceUid UID of the {@link CarrierService}. May be
+ * {@link android.os.Process#INVALID_UID} if no carrier
+ * service is detected.
+ */
+ default void onCarrierServiceChanged(
+ @Nullable String carrierServicePackageName, int carrierServiceUid) {
+ // do nothing by default
+ }
+ }
+
+ /**
* Registers a {@link CarrierPrivilegesListener} on the given {@code logicalSlotIndex} to
* receive callbacks when the set of packages with carrier privileges changes. The callback will
* immediately be called with the latest state.
@@ -16818,7 +16869,10 @@
* @param executor The executor where {@code listener} will be invoked
* @param listener The callback to register
* @hide
+ * @deprecated Use {@link #unregisterCarrierPrivilegesCallback} instead. This API will be
+ * removed prior to API finalization.
*/
+ @Deprecated
@SystemApi
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public void addCarrierPrivilegesListener(
@@ -16842,7 +16896,10 @@
* Unregisters an existing {@link CarrierPrivilegesListener}.
*
* @hide
+ * @deprecated Use {@link #unregisterCarrierPrivilegesCallback} instead. This API will be
+ * removed prior to API finalization.
*/
+ @Deprecated
@SystemApi
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public void removeCarrierPrivilegesListener(@NonNull CarrierPrivilegesListener listener) {
@@ -16890,4 +16947,53 @@
ex.rethrowAsRuntimeException();
}
}
+
+ /**
+ * Registers a {@link CarrierPrivilegesCallback} on the given {@code logicalSlotIndex} to
+ * receive callbacks when the set of packages with carrier privileges changes. The callback will
+ * immediately be called with the latest state.
+ *
+ * @param logicalSlotIndex The SIM slot to listen on
+ * @param executor The executor where {@code callback} will be invoked
+ * @param callback The callback to register
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ public void registerCarrierPrivilegesCallback(
+ int logicalSlotIndex,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull CarrierPrivilegesCallback callback) {
+ if (mContext == null) {
+ throw new IllegalStateException("Telephony service is null");
+ } else if (executor == null || callback == null) {
+ throw new IllegalArgumentException(
+ "CarrierPrivilegesCallback and executor must be non-null");
+ }
+ mTelephonyRegistryMgr = mContext.getSystemService(TelephonyRegistryManager.class);
+ if (mTelephonyRegistryMgr == null) {
+ throw new IllegalStateException("Telephony registry service is null");
+ }
+ mTelephonyRegistryMgr.addCarrierPrivilegesCallback(logicalSlotIndex, executor, callback);
+ }
+
+ /**
+ * Unregisters an existing {@link CarrierPrivilegesCallback}.
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ public void unregisterCarrierPrivilegesCallback(@NonNull CarrierPrivilegesCallback callback) {
+ if (mContext == null) {
+ throw new IllegalStateException("Telephony service is null");
+ } else if (callback == null) {
+ throw new IllegalArgumentException("CarrierPrivilegesCallback must be non-null");
+ }
+ mTelephonyRegistryMgr = mContext.getSystemService(TelephonyRegistryManager.class);
+ if (mTelephonyRegistryMgr == null) {
+ throw new IllegalStateException("Telephony registry service is null");
+ }
+ mTelephonyRegistryMgr.removeCarrierPrivilegesCallback(callback);
+ }
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
index b0e53e9..c3a4769 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
@@ -74,7 +74,7 @@
* Checks that the nav bar layer starts invisible, becomes visible during unlocking animation
* and remains visible at the end
*/
- @Postsubmit
+ @Presubmit
@Test
fun navBarLayerVisibilityChanges() {
testSpec.assertLayers {
diff --git a/wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java b/wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java
index 8630ec4..d85a5bd 100644
--- a/wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java
+++ b/wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java
@@ -967,16 +967,16 @@
*
* @param ifaceName Name of the interface.
*/
- public int getMaxNumScanSsids(@NonNull String ifaceName) {
+ public int getMaxSsidsPerScan(@NonNull String ifaceName) {
IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName);
if (scannerImpl == null) {
Log.e(TAG, "No valid wificond scanner interface handler for iface=" + ifaceName);
return 0;
}
try {
- return scannerImpl.getMaxNumScanSsids();
+ return scannerImpl.getMaxSsidsPerScan();
} catch (RemoteException e1) {
- Log.e(TAG, "Failed to getMaxNumScanSsids");
+ Log.e(TAG, "Failed to getMaxSsidsPerScan");
}
return 0;
}