diff options
340 files changed, 5179 insertions, 1486 deletions
diff --git a/Android.mk b/Android.mk index 6f9680347655..bd04214e427e 100644 --- a/Android.mk +++ b/Android.mk @@ -251,6 +251,8 @@ LOCAL_SRC_FILES += \ core/java/android/os/storage/IObbActionListener.aidl \ core/java/android/security/IKeystoreService.aidl \ core/java/android/security/keymaster/IKeyAttestationApplicationIdProvider.aidl \ + core/java/android/service/autofill/IAutoFillManagerService.aidl \ + core/java/android/service/autofill/IAutoFillService.aidl \ core/java/android/service/carrier/ICarrierService.aidl \ core/java/android/service/carrier/ICarrierMessagingCallback.aidl \ core/java/android/service/carrier/ICarrierMessagingService.aidl \ diff --git a/api/current.txt b/api/current.txt index 22871fab9c06..dda8ce35daf5 100644 --- a/api/current.txt +++ b/api/current.txt @@ -18,6 +18,7 @@ package android { field public static final java.lang.String BATTERY_STATS = "android.permission.BATTERY_STATS"; field public static final java.lang.String BIND_ACCESSIBILITY_SERVICE = "android.permission.BIND_ACCESSIBILITY_SERVICE"; field public static final java.lang.String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET"; + field public static final java.lang.String BIND_AUTO_FILL = "android.permission.BIND_AUTO_FILL"; field public static final deprecated java.lang.String BIND_CARRIER_MESSAGING_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_SERVICE"; field public static final java.lang.String BIND_CARRIER_SERVICES = "android.permission.BIND_CARRIER_SERVICES"; field public static final java.lang.String BIND_CHOOSER_TARGET_SERVICE = "android.permission.BIND_CHOOSER_TARGET_SERVICE"; @@ -28,6 +29,7 @@ package android { field public static final java.lang.String BIND_INPUT_METHOD = "android.permission.BIND_INPUT_METHOD"; field public static final java.lang.String BIND_MIDI_DEVICE_SERVICE = "android.permission.BIND_MIDI_DEVICE_SERVICE"; field public static final java.lang.String BIND_NFC_SERVICE = "android.permission.BIND_NFC_SERVICE"; + field public static final java.lang.String BIND_NOTIFICATION_ASSISTANT_SERVICE = "android.permission.BIND_NOTIFICATION_ASSISTANT_SERVICE"; field public static final java.lang.String BIND_NOTIFICATION_LISTENER_SERVICE = "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"; field public static final java.lang.String BIND_PRINT_SERVICE = "android.permission.BIND_PRINT_SERVICE"; field public static final java.lang.String BIND_QUICK_SETTINGS_TILE = "android.permission.BIND_QUICK_SETTINGS_TILE"; @@ -577,8 +579,11 @@ package android { field public static final int focusable = 16842970; // 0x10100da field public static final int focusableInTouchMode = 16842971; // 0x10100db field public static final deprecated int focusedMonthDateColor = 16843587; // 0x1010343 + field public static final int font = 16844082; // 0x1010532 field public static final int fontFamily = 16843692; // 0x10103ac field public static final int fontFeatureSettings = 16843959; // 0x10104b7 + field public static final int fontStyle = 16844081; // 0x1010531 + field public static final int fontWeight = 16844083; // 0x1010533 field public static final int footerDividersEnabled = 16843311; // 0x101022f field public static final int forceHasOverlappingRendering = 16844065; // 0x1010521 field public static final int foreground = 16843017; // 0x1010109 @@ -29330,6 +29335,7 @@ package android.os { method public void finishBroadcast(); method public java.lang.Object getBroadcastCookie(int); method public E getBroadcastItem(int); + method public java.lang.Object getRegisteredCallbackCookie(int); method public int getRegisteredCallbackCount(); method public void kill(); method public void onCallbackDied(E); @@ -32077,6 +32083,7 @@ package android.provider { field public static final java.lang.String EXTRA_LOADING = "loading"; field public static final java.lang.String EXTRA_ORIENTATION = "android.provider.extra.ORIENTATION"; field public static final java.lang.String EXTRA_PROMPT = "android.provider.extra.PROMPT"; + field public static final java.lang.String EXTRA_INITIAL_URI = "android.provider.extra.INITIAL_URI"; field public static final java.lang.String PROVIDER_INTERFACE = "android.content.action.DOCUMENTS_PROVIDER"; } @@ -34627,6 +34634,20 @@ package android.security.keystore { } +package android.service.autofill { + + public abstract class AutoFillService extends android.app.Service { + ctor public AutoFillService(); + method public final android.os.IBinder onBind(android.content.Intent); + method public void onNewSession(java.lang.String, android.os.Bundle, int, android.app.assist.AssistStructure); + method public void onReady(); + method public void onSessionFinished(java.lang.String); + method public void onShutdown(); + field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutoFillService"; + } + +} + package android.service.carrier { public class CarrierIdentifier implements android.os.Parcelable { @@ -34829,6 +34850,21 @@ package android.service.media { package android.service.notification { + public final class Adjustment implements android.os.Parcelable { + ctor public Adjustment(java.lang.String, java.lang.String, int, android.os.Bundle, java.lang.CharSequence, android.net.Uri, int); + ctor protected Adjustment(android.os.Parcel); + method public int describeContents(); + method public java.lang.CharSequence getExplanation(); + method public int getImportance(); + method public java.lang.String getKey(); + method public java.lang.String getPackage(); + method public android.net.Uri getReference(); + method public android.os.Bundle getSignals(); + method public int getUser(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.service.notification.Adjustment> CREATOR; + } + public final class Condition implements android.os.Parcelable { ctor public Condition(android.net.Uri, java.lang.String, int); ctor public Condition(android.net.Uri, java.lang.String, java.lang.String, java.lang.String, int, int, int); @@ -34875,6 +34911,34 @@ package android.service.notification { field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.ConditionProviderService"; } + public abstract class NotificationAssistantService extends android.service.notification.NotificationListenerService { + ctor public NotificationAssistantService(); + method public final void adjustNotification(android.service.notification.Adjustment); + method public final void adjustNotifications(java.util.List<android.service.notification.Adjustment>); + method public final android.os.IBinder onBind(android.content.Intent); + method public abstract android.service.notification.Adjustment onNotificationEnqueued(android.service.notification.StatusBarNotification, int, boolean); + method public void onNotificationRemoved(java.lang.String, long, int); + field public static final int REASON_APP_CANCEL = 8; // 0x8 + field public static final int REASON_APP_CANCEL_ALL = 9; // 0x9 + field public static final int REASON_CHANNEL_BANNED = 17; // 0x11 + field public static final int REASON_DELEGATE_CANCEL = 2; // 0x2 + field public static final int REASON_DELEGATE_CANCEL_ALL = 3; // 0x3 + field public static final int REASON_DELEGATE_CLICK = 1; // 0x1 + field public static final int REASON_DELEGATE_ERROR = 4; // 0x4 + field public static final int REASON_GROUP_OPTIMIZATION = 13; // 0xd + field public static final int REASON_GROUP_SUMMARY_CANCELED = 12; // 0xc + field public static final int REASON_LISTENER_CANCEL = 10; // 0xa + field public static final int REASON_LISTENER_CANCEL_ALL = 11; // 0xb + field public static final int REASON_PACKAGE_BANNED = 7; // 0x7 + field public static final int REASON_PACKAGE_CHANGED = 5; // 0x5 + field public static final int REASON_PACKAGE_SUSPENDED = 14; // 0xe + field public static final int REASON_PROFILE_TURNED_OFF = 15; // 0xf + field public static final int REASON_SNOOZED = 18; // 0x12 + field public static final int REASON_UNAUTOBUNDLED = 16; // 0x10 + field public static final int REASON_USER_STOPPED = 6; // 0x6 + field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.NotificationAssistantService"; + } + public abstract class NotificationListenerService extends android.app.Service { ctor public NotificationListenerService(); method public final void cancelAllNotifications(); @@ -34936,7 +35000,7 @@ package android.service.notification { } public class StatusBarNotification implements android.os.Parcelable { - ctor public StatusBarNotification(java.lang.String, java.lang.String, int, java.lang.String, int, int, int, android.app.Notification, android.os.UserHandle, long); + ctor public deprecated StatusBarNotification(java.lang.String, java.lang.String, int, java.lang.String, int, int, int, android.app.Notification, android.os.UserHandle, long); ctor public StatusBarNotification(android.os.Parcel); method public android.service.notification.StatusBarNotification clone(); method public int describeContents(); @@ -34944,6 +35008,7 @@ package android.service.notification { method public int getId(); method public java.lang.String getKey(); method public android.app.Notification getNotification(); + method public android.app.NotificationChannel getNotificationChannel(); method public java.lang.String getOverrideGroupKey(); method public java.lang.String getPackageName(); method public long getPostTime(); @@ -37578,6 +37643,7 @@ package android.telephony { method public void listen(android.telephony.PhoneStateListener, int); method public java.lang.String sendEnvelopeWithStatus(java.lang.String); method public void sendUssdRequest(java.lang.String, android.telephony.TelephonyManager.OnReceiveUssdResponseCallback, android.os.Handler); + method public void sendUssdRequest(java.lang.String, int, android.telephony.TelephonyManager.OnReceiveUssdResponseCallback, android.os.Handler); method public boolean setLine1NumberForDisplay(java.lang.String, java.lang.String); method public boolean setOperatorBrandOverride(java.lang.String); method public boolean setPreferredNetworkTypeToGlobal(); diff --git a/api/system-current.txt b/api/system-current.txt index a8a725eda771..42aa329b110c 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -28,6 +28,7 @@ package android { field public static final java.lang.String BATTERY_STATS = "android.permission.BATTERY_STATS"; field public static final java.lang.String BIND_ACCESSIBILITY_SERVICE = "android.permission.BIND_ACCESSIBILITY_SERVICE"; field public static final java.lang.String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET"; + field public static final java.lang.String BIND_AUTO_FILL = "android.permission.BIND_AUTO_FILL"; field public static final deprecated java.lang.String BIND_CARRIER_MESSAGING_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_SERVICE"; field public static final java.lang.String BIND_CARRIER_SERVICES = "android.permission.BIND_CARRIER_SERVICES"; field public static final java.lang.String BIND_CHOOSER_TARGET_SERVICE = "android.permission.BIND_CHOOSER_TARGET_SERVICE"; @@ -41,6 +42,7 @@ package android { field public static final java.lang.String BIND_KEYGUARD_APPWIDGET = "android.permission.BIND_KEYGUARD_APPWIDGET"; field public static final java.lang.String BIND_MIDI_DEVICE_SERVICE = "android.permission.BIND_MIDI_DEVICE_SERVICE"; field public static final java.lang.String BIND_NFC_SERVICE = "android.permission.BIND_NFC_SERVICE"; + field public static final java.lang.String BIND_NOTIFICATION_ASSISTANT_SERVICE = "android.permission.BIND_NOTIFICATION_ASSISTANT_SERVICE"; field public static final java.lang.String BIND_NOTIFICATION_LISTENER_SERVICE = "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"; field public static final java.lang.String BIND_PRINT_RECOMMENDATION_SERVICE = "android.permission.BIND_PRINT_RECOMMENDATION_SERVICE"; field public static final java.lang.String BIND_PRINT_SERVICE = "android.permission.BIND_PRINT_SERVICE"; @@ -130,6 +132,7 @@ package android { field public static final java.lang.String MANAGE_ACTIVITY_STACKS = "android.permission.MANAGE_ACTIVITY_STACKS"; field public static final java.lang.String MANAGE_APP_OPS_RESTRICTIONS = "android.permission.MANAGE_APP_OPS_RESTRICTIONS"; field public static final java.lang.String MANAGE_APP_TOKENS = "android.permission.MANAGE_APP_TOKENS"; + field public static final java.lang.String MANAGE_AUTO_FILL = "android.permission.MANAGE_AUTO_FILL"; field public static final java.lang.String MANAGE_CA_CERTIFICATES = "android.permission.MANAGE_CA_CERTIFICATES"; field public static final java.lang.String MANAGE_DEVICE_ADMINS = "android.permission.MANAGE_DEVICE_ADMINS"; field public static final java.lang.String MANAGE_DOCUMENTS = "android.permission.MANAGE_DOCUMENTS"; @@ -683,8 +686,11 @@ package android { field public static final int focusable = 16842970; // 0x10100da field public static final int focusableInTouchMode = 16842971; // 0x10100db field public static final deprecated int focusedMonthDateColor = 16843587; // 0x1010343 + field public static final int font = 16844082; // 0x1010532 field public static final int fontFamily = 16843692; // 0x10103ac field public static final int fontFeatureSettings = 16843959; // 0x10104b7 + field public static final int fontStyle = 16844081; // 0x1010531 + field public static final int fontWeight = 16844083; // 0x1010533 field public static final int footerDividersEnabled = 16843311; // 0x101022f field public static final int forceHasOverlappingRendering = 16844065; // 0x1010521 field public static final int foreground = 16843017; // 0x1010109 @@ -4545,7 +4551,9 @@ package android.app { ctor public EphemeralResolverService(); method public final void attachBaseContext(android.content.Context); method public final android.os.IBinder onBind(android.content.Intent); - method public abstract java.util.List<android.content.pm.EphemeralResolveInfo> onEphemeralResolveInfoList(int[], int); + method public abstract deprecated java.util.List<android.content.pm.EphemeralResolveInfo> onEphemeralResolveInfoList(int[], int); + method public java.util.List<android.content.pm.EphemeralResolveInfo> onGetEphemeralIntentFilter(int[]); + method public java.util.List<android.content.pm.EphemeralResolveInfo> onGetEphemeralResolveInfo(int[]); field public static final java.lang.String EXTRA_RESOLVE_INFO = "android.app.extra.RESOLVE_INFO"; field public static final java.lang.String EXTRA_SEQUENCE = "android.app.extra.SEQUENCE"; } @@ -9189,6 +9197,7 @@ package android.content { field public static final java.lang.String EXTRA_SHORTCUT_INTENT = "android.intent.extra.shortcut.INTENT"; field public static final java.lang.String EXTRA_SHORTCUT_NAME = "android.intent.extra.shortcut.NAME"; field public static final java.lang.String EXTRA_SHUTDOWN_USERSPACE_ONLY = "android.intent.extra.SHUTDOWN_USERSPACE_ONLY"; + field public static final java.lang.String EXTRA_SPLIT_NAME = "android.intent.extra.SPLIT_NAME"; field public static final java.lang.String EXTRA_STREAM = "android.intent.extra.STREAM"; field public static final java.lang.String EXTRA_SUBJECT = "android.intent.extra.SUBJECT"; field public static final java.lang.String EXTRA_TEMPLATE = "android.intent.extra.TEMPLATE"; @@ -9893,18 +9902,39 @@ package android.content.pm { field public int reqTouchScreen; } + public final class EphemeralIntentFilter implements android.os.Parcelable { + ctor public EphemeralIntentFilter(java.lang.String, java.util.List<android.content.IntentFilter>); + method public int describeContents(); + method public java.util.List<android.content.IntentFilter> getFilters(); + method public java.lang.String getSplitName(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.content.pm.EphemeralIntentFilter> CREATOR; + } + public final class EphemeralResolveInfo implements android.os.Parcelable { - ctor public EphemeralResolveInfo(android.net.Uri, java.lang.String, java.util.List<android.content.IntentFilter>); + ctor public deprecated EphemeralResolveInfo(android.net.Uri, java.lang.String, java.util.List<android.content.IntentFilter>); + ctor public EphemeralResolveInfo(android.content.pm.EphemeralResolveInfo.EphemeralDigest, java.lang.String, java.util.List<android.content.pm.EphemeralIntentFilter>); + ctor public EphemeralResolveInfo(java.lang.String, java.lang.String, java.util.List<android.content.pm.EphemeralIntentFilter>); method public int describeContents(); method public byte[] getDigestBytes(); method public int getDigestPrefix(); - method public java.util.List<android.content.IntentFilter> getFilters(); + method public deprecated java.util.List<android.content.IntentFilter> getFilters(); + method public java.util.List<android.content.pm.EphemeralIntentFilter> getIntentFilters(); method public java.lang.String getPackageName(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.content.pm.EphemeralResolveInfo> CREATOR; field public static final java.lang.String SHA_ALGORITHM = "SHA-256"; } + public static final class EphemeralResolveInfo.EphemeralDigest implements android.os.Parcelable { + ctor public EphemeralResolveInfo.EphemeralDigest(java.lang.String); + method public int describeContents(); + method public byte[][] getDigestBytes(); + method public int[] getDigestPrefix(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.content.pm.EphemeralResolveInfo.EphemeralDigest> CREATOR; + } + public final class FeatureGroupInfo implements android.os.Parcelable { ctor public FeatureGroupInfo(); ctor public FeatureGroupInfo(android.content.pm.FeatureGroupInfo); @@ -31858,6 +31888,7 @@ package android.os { method public void finishBroadcast(); method public java.lang.Object getBroadcastCookie(int); method public E getBroadcastItem(int); + method public java.lang.Object getRegisteredCallbackCookie(int); method public int getRegisteredCallbackCount(); method public void kill(); method public void onCallbackDied(E); @@ -34740,6 +34771,7 @@ package android.provider { field public static final java.lang.String EXTRA_LOADING = "loading"; field public static final java.lang.String EXTRA_ORIENTATION = "android.provider.extra.ORIENTATION"; field public static final java.lang.String EXTRA_PROMPT = "android.provider.extra.PROMPT"; + field public static final java.lang.String EXTRA_INITIAL_URI = "android.provider.extra.INITIAL_URI"; field public static final java.lang.String PROVIDER_INTERFACE = "android.content.action.DOCUMENTS_PROVIDER"; } @@ -37395,6 +37427,20 @@ package android.security.keystore { } +package android.service.autofill { + + public abstract class AutoFillService extends android.app.Service { + ctor public AutoFillService(); + method public final android.os.IBinder onBind(android.content.Intent); + method public void onNewSession(java.lang.String, android.os.Bundle, int, android.app.assist.AssistStructure); + method public void onReady(); + method public void onSessionFinished(java.lang.String); + method public void onShutdown(); + field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutoFillService"; + } + +} + package android.service.carrier { public class CarrierIdentifier implements android.os.Parcelable { @@ -37658,6 +37704,34 @@ package android.service.notification { field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.ConditionProviderService"; } + public abstract class NotificationAssistantService extends android.service.notification.NotificationListenerService { + ctor public NotificationAssistantService(); + method public final void adjustNotification(android.service.notification.Adjustment); + method public final void adjustNotifications(java.util.List<android.service.notification.Adjustment>); + method public final android.os.IBinder onBind(android.content.Intent); + method public abstract android.service.notification.Adjustment onNotificationEnqueued(android.service.notification.StatusBarNotification, int, boolean); + method public void onNotificationRemoved(java.lang.String, long, int); + field public static final int REASON_APP_CANCEL = 8; // 0x8 + field public static final int REASON_APP_CANCEL_ALL = 9; // 0x9 + field public static final int REASON_CHANNEL_BANNED = 17; // 0x11 + field public static final int REASON_DELEGATE_CANCEL = 2; // 0x2 + field public static final int REASON_DELEGATE_CANCEL_ALL = 3; // 0x3 + field public static final int REASON_DELEGATE_CLICK = 1; // 0x1 + field public static final int REASON_DELEGATE_ERROR = 4; // 0x4 + field public static final int REASON_GROUP_OPTIMIZATION = 13; // 0xd + field public static final int REASON_GROUP_SUMMARY_CANCELED = 12; // 0xc + field public static final int REASON_LISTENER_CANCEL = 10; // 0xa + field public static final int REASON_LISTENER_CANCEL_ALL = 11; // 0xb + field public static final int REASON_PACKAGE_BANNED = 7; // 0x7 + field public static final int REASON_PACKAGE_CHANGED = 5; // 0x5 + field public static final int REASON_PACKAGE_SUSPENDED = 14; // 0xe + field public static final int REASON_PROFILE_TURNED_OFF = 15; // 0xf + field public static final int REASON_SNOOZED = 18; // 0x12 + field public static final int REASON_UNAUTOBUNDLED = 16; // 0x10 + field public static final int REASON_USER_STOPPED = 6; // 0x6 + field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.NotificationAssistantService"; + } + public abstract class NotificationListenerService extends android.app.Service { ctor public NotificationListenerService(); method public final void cancelAllNotifications(); @@ -37725,39 +37799,8 @@ package android.service.notification { field public static final android.os.Parcelable.Creator<android.service.notification.NotificationListenerService.RankingMap> CREATOR; } - public abstract class NotificationRankerService extends android.service.notification.NotificationListenerService { - ctor public NotificationRankerService(); - method public final void adjustNotification(android.service.notification.Adjustment); - method public final void adjustNotifications(java.util.List<android.service.notification.Adjustment>); - method public final android.os.IBinder onBind(android.content.Intent); - method public void onNotificationActionClick(java.lang.String, long, int); - method public void onNotificationClick(java.lang.String, long); - method public abstract android.service.notification.Adjustment onNotificationEnqueued(android.service.notification.StatusBarNotification, int, boolean); - method public void onNotificationRemoved(java.lang.String, long, int); - method public void onNotificationVisibilityChanged(java.lang.String, long, boolean); - field public static final int REASON_APP_CANCEL = 8; // 0x8 - field public static final int REASON_APP_CANCEL_ALL = 9; // 0x9 - field public static final int REASON_CHANNEL_BANNED = 17; // 0x11 - field public static final int REASON_DELEGATE_CANCEL = 2; // 0x2 - field public static final int REASON_DELEGATE_CANCEL_ALL = 3; // 0x3 - field public static final int REASON_DELEGATE_CLICK = 1; // 0x1 - field public static final int REASON_DELEGATE_ERROR = 4; // 0x4 - field public static final int REASON_GROUP_OPTIMIZATION = 13; // 0xd - field public static final int REASON_GROUP_SUMMARY_CANCELED = 12; // 0xc - field public static final int REASON_LISTENER_CANCEL = 10; // 0xa - field public static final int REASON_LISTENER_CANCEL_ALL = 11; // 0xb - field public static final int REASON_PACKAGE_BANNED = 7; // 0x7 - field public static final int REASON_PACKAGE_CHANGED = 5; // 0x5 - field public static final int REASON_PACKAGE_SUSPENDED = 14; // 0xe - field public static final int REASON_PROFILE_TURNED_OFF = 15; // 0xf - field public static final int REASON_SNOOZED = 18; // 0x12 - field public static final int REASON_UNAUTOBUNDLED = 16; // 0x10 - field public static final int REASON_USER_STOPPED = 6; // 0x6 - field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.NotificationRankerService"; - } - public class StatusBarNotification implements android.os.Parcelable { - ctor public StatusBarNotification(java.lang.String, java.lang.String, int, java.lang.String, int, int, int, android.app.Notification, android.os.UserHandle, long); + ctor public deprecated StatusBarNotification(java.lang.String, java.lang.String, int, java.lang.String, int, int, int, android.app.Notification, android.os.UserHandle, long); ctor public StatusBarNotification(android.os.Parcel); method public android.service.notification.StatusBarNotification clone(); method public int describeContents(); @@ -37765,6 +37808,7 @@ package android.service.notification { method public int getId(); method public java.lang.String getKey(); method public android.app.Notification getNotification(); + method public android.app.NotificationChannel getNotificationChannel(); method public java.lang.String getOverrideGroupKey(); method public java.lang.String getPackageName(); method public long getPostTime(); @@ -40727,6 +40771,7 @@ package android.telephony { method public boolean needsOtaServiceProvisioning(); method public java.lang.String sendEnvelopeWithStatus(java.lang.String); method public void sendUssdRequest(java.lang.String, android.telephony.TelephonyManager.OnReceiveUssdResponseCallback, android.os.Handler); + method public void sendUssdRequest(java.lang.String, int, android.telephony.TelephonyManager.OnReceiveUssdResponseCallback, android.os.Handler); method public void setDataEnabled(boolean); method public void setDataEnabled(int, boolean); method public boolean setLine1NumberForDisplay(java.lang.String, java.lang.String); diff --git a/api/test-current.txt b/api/test-current.txt index 50dfa2a9c77e..13f31038960c 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -18,6 +18,7 @@ package android { field public static final java.lang.String BATTERY_STATS = "android.permission.BATTERY_STATS"; field public static final java.lang.String BIND_ACCESSIBILITY_SERVICE = "android.permission.BIND_ACCESSIBILITY_SERVICE"; field public static final java.lang.String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET"; + field public static final java.lang.String BIND_AUTO_FILL = "android.permission.BIND_AUTO_FILL"; field public static final deprecated java.lang.String BIND_CARRIER_MESSAGING_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_SERVICE"; field public static final java.lang.String BIND_CARRIER_SERVICES = "android.permission.BIND_CARRIER_SERVICES"; field public static final java.lang.String BIND_CHOOSER_TARGET_SERVICE = "android.permission.BIND_CHOOSER_TARGET_SERVICE"; @@ -28,6 +29,7 @@ package android { field public static final java.lang.String BIND_INPUT_METHOD = "android.permission.BIND_INPUT_METHOD"; field public static final java.lang.String BIND_MIDI_DEVICE_SERVICE = "android.permission.BIND_MIDI_DEVICE_SERVICE"; field public static final java.lang.String BIND_NFC_SERVICE = "android.permission.BIND_NFC_SERVICE"; + field public static final java.lang.String BIND_NOTIFICATION_ASSISTANT_SERVICE = "android.permission.BIND_NOTIFICATION_ASSISTANT_SERVICE"; field public static final java.lang.String BIND_NOTIFICATION_LISTENER_SERVICE = "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"; field public static final java.lang.String BIND_PRINT_SERVICE = "android.permission.BIND_PRINT_SERVICE"; field public static final java.lang.String BIND_QUICK_SETTINGS_TILE = "android.permission.BIND_QUICK_SETTINGS_TILE"; @@ -577,8 +579,11 @@ package android { field public static final int focusable = 16842970; // 0x10100da field public static final int focusableInTouchMode = 16842971; // 0x10100db field public static final deprecated int focusedMonthDateColor = 16843587; // 0x1010343 + field public static final int font = 16844082; // 0x1010532 field public static final int fontFamily = 16843692; // 0x10103ac field public static final int fontFeatureSettings = 16843959; // 0x10104b7 + field public static final int fontStyle = 16844081; // 0x1010531 + field public static final int fontWeight = 16844083; // 0x1010533 field public static final int footerDividersEnabled = 16843311; // 0x101022f field public static final int forceHasOverlappingRendering = 16844065; // 0x1010521 field public static final int foreground = 16843017; // 0x1010109 @@ -29412,6 +29417,7 @@ package android.os { method public void finishBroadcast(); method public java.lang.Object getBroadcastCookie(int); method public E getBroadcastItem(int); + method public java.lang.Object getRegisteredCallbackCookie(int); method public int getRegisteredCallbackCount(); method public void kill(); method public void onCallbackDied(E); @@ -32163,6 +32169,7 @@ package android.provider { field public static final java.lang.String EXTRA_LOADING = "loading"; field public static final java.lang.String EXTRA_ORIENTATION = "android.provider.extra.ORIENTATION"; field public static final java.lang.String EXTRA_PROMPT = "android.provider.extra.PROMPT"; + field public static final java.lang.String EXTRA_INITIAL_URI = "android.provider.extra.INITIAL_URI"; field public static final java.lang.String PROVIDER_INTERFACE = "android.content.action.DOCUMENTS_PROVIDER"; } @@ -32763,6 +32770,7 @@ package android.provider { field public static final java.lang.String ALLOWED_GEOLOCATION_ORIGINS = "allowed_geolocation_origins"; field public static final deprecated java.lang.String ALLOW_MOCK_LOCATION = "mock_location"; field public static final java.lang.String ANDROID_ID = "android_id"; + field public static final java.lang.String AUTO_FILL_SERVICE = "auto_fill_service"; field public static final deprecated java.lang.String BACKGROUND_DATA = "background_data"; field public static final deprecated java.lang.String BLUETOOTH_ON = "bluetooth_on"; field public static final android.net.Uri CONTENT_URI; @@ -34716,6 +34724,20 @@ package android.security.keystore { } +package android.service.autofill { + + public abstract class AutoFillService extends android.app.Service { + ctor public AutoFillService(); + method public final android.os.IBinder onBind(android.content.Intent); + method public void onNewSession(java.lang.String, android.os.Bundle, int, android.app.assist.AssistStructure); + method public void onReady(); + method public void onSessionFinished(java.lang.String); + method public void onShutdown(); + field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutoFillService"; + } + +} + package android.service.carrier { public class CarrierIdentifier implements android.os.Parcelable { @@ -34918,6 +34940,21 @@ package android.service.media { package android.service.notification { + public final class Adjustment implements android.os.Parcelable { + ctor public Adjustment(java.lang.String, java.lang.String, int, android.os.Bundle, java.lang.CharSequence, android.net.Uri, int); + ctor protected Adjustment(android.os.Parcel); + method public int describeContents(); + method public java.lang.CharSequence getExplanation(); + method public int getImportance(); + method public java.lang.String getKey(); + method public java.lang.String getPackage(); + method public android.net.Uri getReference(); + method public android.os.Bundle getSignals(); + method public int getUser(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.service.notification.Adjustment> CREATOR; + } + public final class Condition implements android.os.Parcelable { ctor public Condition(android.net.Uri, java.lang.String, int); ctor public Condition(android.net.Uri, java.lang.String, java.lang.String, java.lang.String, int, int, int); @@ -34964,6 +35001,34 @@ package android.service.notification { field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.ConditionProviderService"; } + public abstract class NotificationAssistantService extends android.service.notification.NotificationListenerService { + ctor public NotificationAssistantService(); + method public final void adjustNotification(android.service.notification.Adjustment); + method public final void adjustNotifications(java.util.List<android.service.notification.Adjustment>); + method public final android.os.IBinder onBind(android.content.Intent); + method public abstract android.service.notification.Adjustment onNotificationEnqueued(android.service.notification.StatusBarNotification, int, boolean); + method public void onNotificationRemoved(java.lang.String, long, int); + field public static final int REASON_APP_CANCEL = 8; // 0x8 + field public static final int REASON_APP_CANCEL_ALL = 9; // 0x9 + field public static final int REASON_CHANNEL_BANNED = 17; // 0x11 + field public static final int REASON_DELEGATE_CANCEL = 2; // 0x2 + field public static final int REASON_DELEGATE_CANCEL_ALL = 3; // 0x3 + field public static final int REASON_DELEGATE_CLICK = 1; // 0x1 + field public static final int REASON_DELEGATE_ERROR = 4; // 0x4 + field public static final int REASON_GROUP_OPTIMIZATION = 13; // 0xd + field public static final int REASON_GROUP_SUMMARY_CANCELED = 12; // 0xc + field public static final int REASON_LISTENER_CANCEL = 10; // 0xa + field public static final int REASON_LISTENER_CANCEL_ALL = 11; // 0xb + field public static final int REASON_PACKAGE_BANNED = 7; // 0x7 + field public static final int REASON_PACKAGE_CHANGED = 5; // 0x5 + field public static final int REASON_PACKAGE_SUSPENDED = 14; // 0xe + field public static final int REASON_PROFILE_TURNED_OFF = 15; // 0xf + field public static final int REASON_SNOOZED = 18; // 0x12 + field public static final int REASON_UNAUTOBUNDLED = 16; // 0x10 + field public static final int REASON_USER_STOPPED = 6; // 0x6 + field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.NotificationAssistantService"; + } + public abstract class NotificationListenerService extends android.app.Service { ctor public NotificationListenerService(); method public final void cancelAllNotifications(); @@ -35025,7 +35090,7 @@ package android.service.notification { } public class StatusBarNotification implements android.os.Parcelable { - ctor public StatusBarNotification(java.lang.String, java.lang.String, int, java.lang.String, int, int, int, android.app.Notification, android.os.UserHandle, long); + ctor public deprecated StatusBarNotification(java.lang.String, java.lang.String, int, java.lang.String, int, int, int, android.app.Notification, android.os.UserHandle, long); ctor public StatusBarNotification(android.os.Parcel); method public android.service.notification.StatusBarNotification clone(); method public int describeContents(); @@ -35033,6 +35098,7 @@ package android.service.notification { method public int getId(); method public java.lang.String getKey(); method public android.app.Notification getNotification(); + method public android.app.NotificationChannel getNotificationChannel(); method public java.lang.String getOverrideGroupKey(); method public java.lang.String getPackageName(); method public long getPostTime(); @@ -37667,6 +37733,7 @@ package android.telephony { method public void listen(android.telephony.PhoneStateListener, int); method public java.lang.String sendEnvelopeWithStatus(java.lang.String); method public void sendUssdRequest(java.lang.String, android.telephony.TelephonyManager.OnReceiveUssdResponseCallback, android.os.Handler); + method public void sendUssdRequest(java.lang.String, int, android.telephony.TelephonyManager.OnReceiveUssdResponseCallback, android.os.Handler); method public boolean setLine1NumberForDisplay(java.lang.String, java.lang.String); method public boolean setOperatorBrandOverride(java.lang.String); method public boolean setPreferredNetworkTypeToGlobal(); diff --git a/cmds/locksettings/Android.mk b/cmds/locksettings/Android.mk new file mode 100644 index 000000000000..76766c7c6955 --- /dev/null +++ b/cmds/locksettings/Android.mk @@ -0,0 +1,30 @@ +# Copyright (C) 2016 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := $(call all-subdir-java-files) +LOCAL_MODULE := locksettings +LOCAL_MODULE_TAGS := optional +include $(BUILD_JAVA_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_MODULE := locksettings +LOCAL_SRC_FILES := locksettings +LOCAL_MODULE_CLASS := EXECUTABLES +LOCAL_MODULE_TAGS := optional +include $(BUILD_PREBUILT) + + diff --git a/cmds/locksettings/locksettings b/cmds/locksettings/locksettings new file mode 100755 index 000000000000..c963b238726b --- /dev/null +++ b/cmds/locksettings/locksettings @@ -0,0 +1,5 @@ +# Script to start "locksettings" on the device +# +base=/system +export CLASSPATH=$base/framework/locksettings.jar +exec app_process $base/bin com.android.commands.locksettings.LockSettingsCmd "$@" diff --git a/cmds/locksettings/src/com/android/commands/locksettings/LockSettingsCmd.java b/cmds/locksettings/src/com/android/commands/locksettings/LockSettingsCmd.java new file mode 100644 index 000000000000..1e426d62e4e0 --- /dev/null +++ b/cmds/locksettings/src/com/android/commands/locksettings/LockSettingsCmd.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.commands.locksettings; + +import android.os.ResultReceiver; +import android.os.ServiceManager; +import android.os.ShellCallback; + +import com.android.internal.os.BaseCommand; +import com.android.internal.widget.ILockSettings; + +import java.io.FileDescriptor; +import java.io.PrintStream; + +public final class LockSettingsCmd extends BaseCommand { + + private static final String USAGE = + "usage: locksettings set-pattern [--old OLD_CREDENTIAL] NEW_PATTERN\n" + + " locksettings set-pin [--old OLD_CREDENTIAL] NEW_PIN\n" + + " locksettings set-password [--old OLD_CREDENTIAL] NEW_PASSWORD\n" + + " locksettings clear [--old OLD_CREDENTIAL]\n" + + "\n" + + "locksettings set-pattern: sets a pattern\n" + + " A pattern is specified by a non-separated list of numbers that index the cell\n" + + " on the pattern in a 1-based manner in left to right and top to bottom order,\n" + + " i.e. the top-left cell is indexed with 1, whereas the bottom-right cell\n" + + " is indexed with 9. Example: 1234\n" + + "\n" + + "locksettings set-pin: sets a PIN\n" + + "\n" + + "locksettings set-password: sets a password\n" + + "\n" + + "locksettings clear: clears the unlock credential\n"; + + public static void main(String[] args) { + (new LockSettingsCmd()).run(args); + } + + @Override + public void onShowUsage(PrintStream out) { + out.println(USAGE); + } + + @Override + public void onRun() throws Exception { + ILockSettings lockSettings = ILockSettings.Stub.asInterface( + ServiceManager.getService("lock_settings")); + lockSettings.asBinder().shellCommand(FileDescriptor.in, FileDescriptor.out, + FileDescriptor.err, getRawArgs(), new ShellCallback(), new ResultReceiver(null) {}); + } +} diff --git a/compiled-classes-phone b/compiled-classes-phone index 8428e41fab4a..33e3e0437aa6 100644 --- a/compiled-classes-phone +++ b/compiled-classes-phone @@ -3610,9 +3610,9 @@ android.service.notification.NotificationListenerService$NotificationListenerWra android.service.notification.NotificationListenerService$Ranking android.service.notification.NotificationListenerService$RankingMap android.service.notification.NotificationListenerService$RankingMap$1 -android.service.notification.NotificationRankerService -android.service.notification.NotificationRankerService$MyHandler -android.service.notification.NotificationRankerService$NotificationRankingServiceWrapper +android.service.notification.NotificationAssistantService +android.service.notification.NotificationAssistantService$MyHandler +android.service.notification.NotificationAssistantService$NotificationRankingServiceWrapper android.service.notification.NotificationRankingUpdate android.service.notification.NotificationRankingUpdate$1 android.service.notification.StatusBarNotification diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 9af7d8bae314..df970a47de21 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -91,33 +91,18 @@ public class ActivityManager { static final class UidObserver extends IUidObserver.Stub { final OnUidImportanceListener mListener; - final int mImportanceCutpoint; - int mLastImportance; - UidObserver(OnUidImportanceListener listener, int importanceCutpoint) { + UidObserver(OnUidImportanceListener listener) { mListener = listener; - mImportanceCutpoint = importanceCutpoint; } @Override public void onUidStateChanged(int uid, int procState) { - final boolean lastAboveCut = mLastImportance <= mImportanceCutpoint; - final int importance = RunningAppProcessInfo.procStateToImportance(procState); - final boolean newAboveCut = importance <= mImportanceCutpoint; - /* - Log.d(TAG, "Uid " + uid + " state change from " + mLastImportance + " to " - + importance + " @ cut " + mImportanceCutpoint - + ": lastAbove=" + lastAboveCut + " newAbove=" + newAboveCut); - */ - mLastImportance = importance; - if (lastAboveCut != newAboveCut) { - mListener.onUidImportance(uid, importance); - } + mListener.onUidImportance(uid, RunningAppProcessInfo.procStateToImportance(procState)); } @Override public void onUidGone(int uid) { - mLastImportance = RunningAppProcessInfo.IMPORTANCE_GONE; mListener.onUidImportance(uid, RunningAppProcessInfo.IMPORTANCE_GONE); } @@ -380,8 +365,8 @@ public class ActivityManager { /** @hide User operation call: one of related users cannot be stopped. */ public static final int USER_OP_ERROR_RELATED_USERS_CANNOT_STOP = -4; - /** @hide Process does not exist. */ - public static final int PROCESS_STATE_NONEXISTENT = -1; + /** @hide Not a real process state. */ + public static final int PROCESS_STATE_UNKNOWN = -1; /** @hide Process is a persistent system process. */ public static final int PROCESS_STATE_PERSISTENT = 0; @@ -442,11 +427,14 @@ public class ActivityManager { /** @hide Process is being cached for later use and is empty. */ public static final int PROCESS_STATE_CACHED_EMPTY = 16; + /** @hide Process does not exist. */ + public static final int PROCESS_STATE_NONEXISTENT = 17; + /** @hide The lowest process state number */ - public static final int MIN_PROCESS_STATE = PROCESS_STATE_NONEXISTENT; + public static final int MIN_PROCESS_STATE = PROCESS_STATE_PERSISTENT; /** @hide The highest process state number */ - public static final int MAX_PROCESS_STATE = PROCESS_STATE_CACHED_EMPTY; + public static final int MAX_PROCESS_STATE = PROCESS_STATE_NONEXISTENT; /** @hide Should this process state be considered a background state? */ public static final boolean isProcStateBackground(int procState) { @@ -2890,6 +2878,29 @@ public class ActivityManager { } } + /** @hide */ + public static int importanceToProcState(int importance) { + if (importance == IMPORTANCE_GONE) { + return PROCESS_STATE_NONEXISTENT; + } else if (importance >= IMPORTANCE_BACKGROUND) { + return PROCESS_STATE_HOME; + } else if (importance >= IMPORTANCE_SERVICE) { + return PROCESS_STATE_SERVICE; + } else if (importance > IMPORTANCE_CANT_SAVE_STATE) { + return PROCESS_STATE_HEAVY_WEIGHT; + } else if (importance >= IMPORTANCE_PERCEPTIBLE) { + return PROCESS_STATE_IMPORTANT_BACKGROUND; + } else if (importance >= IMPORTANCE_VISIBLE) { + return PROCESS_STATE_IMPORTANT_FOREGROUND; + } else if (importance >= IMPORTANCE_TOP_SLEEPING) { + return PROCESS_STATE_TOP_SLEEPING; + } else if (importance >= IMPORTANCE_FOREGROUND_SERVICE) { + return PROCESS_STATE_FOREGROUND_SERVICE; + } else { + return PROCESS_STATE_BOUND_FOREGROUND_SERVICE; + } + } + /** * The relative importance level that the system places on this * process. May be one of {@link #IMPORTANCE_FOREGROUND}, @@ -3146,10 +3157,12 @@ public class ActivityManager { throw new IllegalArgumentException("Listener already registered: " + listener); } // TODO: implement the cut point in the system process to avoid IPCs. - UidObserver observer = new UidObserver(listener, importanceCutpoint); + UidObserver observer = new UidObserver(listener); try { getService().registerUidObserver(observer, - UID_OBSERVER_PROCSTATE | UID_OBSERVER_GONE, mContext.getOpPackageName()); + UID_OBSERVER_PROCSTATE | UID_OBSERVER_GONE, + RunningAppProcessInfo.importanceToProcState(importanceCutpoint), + mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -3587,7 +3600,7 @@ public class ActivityManager { * allowed to run code through scheduled alarms, receiving broadcasts, * etc. A started user may be either the current foreground user or a * background user; the result here does not distinguish between the two. - * @param userid the user's id. Zero indicates the default user. + * @param userId the user's id. Zero indicates the default user. * @hide */ public boolean isUserRunning(int userId) { diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index 10f0425cbdc4..199fda4cd09c 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -16,7 +16,10 @@ package android.app; import android.content.Intent; +import android.os.Debug; import android.os.IBinder; +import android.util.Log; + import com.android.server.LocalServices; /** @@ -25,6 +28,8 @@ import com.android.server.LocalServices; */ @Deprecated public abstract class ActivityManagerNative { + private final static String TAG = "ActivityManagerNative"; + /** * Cast a Binder object into an activity manager interface, generating * a proxy if needed. @@ -51,7 +56,14 @@ public abstract class ActivityManagerNative { */ static public boolean isSystemReady() { if (!sSystemReady) { - sSystemReady = LocalServices.getService(ActivityManagerInternal.class).isSystemReady(); + if (ActivityThread.isSystem()) { + sSystemReady = + LocalServices.getService(ActivityManagerInternal.class).isSystemReady(); + } else { + // Since this is being called from outside system server, system should be + // ready by now. + sSystemReady = true; + } } return sSystemReady; } diff --git a/core/java/android/app/EphemeralResolverService.java b/core/java/android/app/EphemeralResolverService.java index ba791085d617..d8d73404f2ae 100644 --- a/core/java/android/app/EphemeralResolverService.java +++ b/core/java/android/app/EphemeralResolverService.java @@ -40,6 +40,7 @@ public abstract class EphemeralResolverService extends Service { public static final String EXTRA_RESOLVE_INFO = "android.app.extra.RESOLVE_INFO"; public static final String EXTRA_SEQUENCE = "android.app.extra.SEQUENCE"; private static final String EXTRA_PREFIX = "android.app.PREFIX"; + private static final String EXTRA_HOSTNAME = "android.app.HOSTNAME"; private Handler mHandler; /** @@ -49,9 +50,29 @@ public abstract class EphemeralResolverService extends Service { * @param prefixMask A mask that was applied to each digest prefix. This should * be used when comparing against the digest prefixes as all bits might * not be set. + * @deprecated use {@link #onGetEphemeralResolveInfo(int[])} instead */ + @Deprecated public abstract List<EphemeralResolveInfo> onEphemeralResolveInfoList( - int digestPrefix[], int prefixMask); + int digestPrefix[], int prefix); + + /** + * Called to retrieve resolve info for ephemeral applications. + * + * @param digestPrefix The hash prefix of the ephemeral's domain. + */ + public List<EphemeralResolveInfo> onGetEphemeralResolveInfo(int digestPrefix[]) { + return onEphemeralResolveInfoList(digestPrefix, 0xFFFFF000); + } + + /** + * Called to retrieve intent filters for ephemeral applications. + * + * @param digestPrefix The hash prefix of the ephemeral's domain. + */ + public List<EphemeralResolveInfo> onGetEphemeralIntentFilter(int digestPrefix[]) { + throw new IllegalStateException("Must define"); + } @Override public final void attachBaseContext(Context base) { @@ -64,9 +85,20 @@ public abstract class EphemeralResolverService extends Service { return new IEphemeralResolver.Stub() { @Override public void getEphemeralResolveInfoList( - IRemoteCallback callback, int digestPrefix[], int prefixMask, int sequence) { + IRemoteCallback callback, int digestPrefix[], int sequence) { + final Message msg = mHandler.obtainMessage( + ServiceHandler.MSG_GET_EPHEMERAL_RESOLVE_INFO, sequence, 0, callback); + final Bundle data = new Bundle(); + data.putIntArray(EXTRA_PREFIX, digestPrefix); + msg.setData(data); + msg.sendToTarget(); + } + + @Override + public void getEphemeralIntentFilterList( + IRemoteCallback callback, int digestPrefix[], int sequence) { final Message msg = mHandler.obtainMessage( - ServiceHandler.MSG_GET_EPHEMERAL_RESOLVE_INFO, prefixMask, sequence, callback); + ServiceHandler.MSG_GET_EPHEMERAL_INTENT_FILTER, sequence, 0, callback); final Bundle data = new Bundle(); data.putIntArray(EXTRA_PREFIX, digestPrefix); msg.setData(data); @@ -77,6 +109,7 @@ public abstract class EphemeralResolverService extends Service { private final class ServiceHandler extends Handler { public static final int MSG_GET_EPHEMERAL_RESOLVE_INFO = 1; + public static final int MSG_GET_EPHEMERAL_INTENT_FILTER = 2; public ServiceHandler(Looper looper) { super(looper, null /*callback*/, true /*async*/); @@ -91,9 +124,23 @@ public abstract class EphemeralResolverService extends Service { final IRemoteCallback callback = (IRemoteCallback) message.obj; final int[] digestPrefix = message.getData().getIntArray(EXTRA_PREFIX); final List<EphemeralResolveInfo> resolveInfo = - onEphemeralResolveInfoList(digestPrefix, message.arg1); + onGetEphemeralResolveInfo(digestPrefix); + final Bundle data = new Bundle(); + data.putInt(EXTRA_SEQUENCE, message.arg1); + data.putParcelableList(EXTRA_RESOLVE_INFO, resolveInfo); + try { + callback.sendResult(data); + } catch (RemoteException e) { + } + } break; + + case MSG_GET_EPHEMERAL_INTENT_FILTER: { + final IRemoteCallback callback = (IRemoteCallback) message.obj; + final int[] digestPrefix = message.getData().getIntArray(EXTRA_PREFIX); + final List<EphemeralResolveInfo> resolveInfo = + onGetEphemeralIntentFilter(digestPrefix); final Bundle data = new Bundle(); - data.putInt(EXTRA_SEQUENCE, message.arg2); + data.putInt(EXTRA_SEQUENCE, message.arg1); data.putParcelableList(EXTRA_RESOLVE_INFO, resolveInfo); try { callback.sendResult(data); diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index 92d67b7d9f74..80267205de83 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -431,7 +431,8 @@ interface IActivityManager { * etc. */ void keyguardGoingAway(int flags) = 296; - void registerUidObserver(in IUidObserver observer, int which, String callingPackage) = 297; + void registerUidObserver(in IUidObserver observer, int which, int cutpoint, + String callingPackage) = 297; void unregisterUidObserver(in IUidObserver observer) = 298; boolean isAssistDataAllowedOnCurrentActivity() = 299; boolean showAssistFromActivity(in IBinder token, in Bundle args) = 300; diff --git a/core/java/android/app/IEphemeralResolver.aidl b/core/java/android/app/IEphemeralResolver.aidl index ee869eaa7936..e0cef83cb9c7 100644 --- a/core/java/android/app/IEphemeralResolver.aidl +++ b/core/java/android/app/IEphemeralResolver.aidl @@ -21,5 +21,8 @@ import android.os.IRemoteCallback; /** @hide */ oneway interface IEphemeralResolver { void getEphemeralResolveInfoList(IRemoteCallback callback, in int[] digestPrefix, - int prefixMask, int sequence); + int sequence); + + void getEphemeralIntentFilterList(IRemoteCallback callback, in int[] digestPrefix, + int sequence); } diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl index ee81c582cc5d..15b99c6e4f7f 100644 --- a/core/java/android/app/INotificationManager.aidl +++ b/core/java/android/app/INotificationManager.aidl @@ -94,8 +94,8 @@ interface INotificationManager void setOnNotificationPostedTrimFromListener(in INotificationListener token, int trim); void setInterruptionFilter(String pkg, int interruptionFilter); - void applyAdjustmentFromRankerService(in INotificationListener token, in Adjustment adjustment); - void applyAdjustmentsFromRankerService(in INotificationListener token, in List<Adjustment> adjustments); + void applyAdjustmentFromAssistantService(in INotificationListener token, in Adjustment adjustment); + void applyAdjustmentsFromAssistantService(in INotificationListener token, in List<Adjustment> adjustments); ComponentName getEffectsSuppressor(); boolean matchesCallFilter(in Bundle extras); diff --git a/core/java/android/app/usage/NetworkStatsManager.java b/core/java/android/app/usage/NetworkStatsManager.java index da5aa61f1f21..6cd4e92383b2 100644 --- a/core/java/android/app/usage/NetworkStatsManager.java +++ b/core/java/android/app/usage/NetworkStatsManager.java @@ -182,10 +182,10 @@ public class NetworkStatsManager { /** * Query network usage statistics summaries. Result filtered to include only uids belonging to * calling user. Result is aggregated over time, hence all buckets will have the same start and - * end timestamps. State is going to be {@link NetworkStats.Bucket#STATE_ALL}, - * uid {@link NetworkStats.Bucket#UID_ALL}, tag {@link NetworkStats.Bucket#TAG_NONE}, - * metered {@link NetworkStats.Bucket#METERED_ALL}, and roaming - * {@link NetworkStats.Bucket#ROAMING_ALL}. + * end timestamps. Not aggregated over state, uid, metered, or roaming. This means buckets' + * start and end timestamps are going to be the same as the 'startTime' and 'endTime' + * parameters. State, uid, metered, and roaming are going to vary, and tag is going to be the + * same. * * @param networkType As defined in {@link ConnectivityManager}, e.g. * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI} @@ -231,7 +231,9 @@ public class NetworkStatsManager { * belonging to calling user. Result is aggregated over state but not aggregated over time. * This means buckets' start and end timestamps are going to be between 'startTime' and * 'endTime' parameters. State is going to be {@link NetworkStats.Bucket#STATE_ALL}, uid the - * same as the 'uid' parameter and tag the same as 'tag' parameter. + * same as the 'uid' parameter and tag the same as 'tag' parameter. metered is going to be + * {@link NetworkStats.Bucket#METERED_ALL}, and roaming is going to be + * {@link NetworkStats.Bucket#ROAMING_ALL}. * <p>Only includes buckets that atomically occur in the inclusive time range. Doesn't * interpolate across partial buckets. Since bucket length is in the order of hours, this * method cannot be used to measure data usage on a fine grained time scale. diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 322cc7b9becc..3964e0a8bbd9 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -3338,6 +3338,14 @@ public abstract class Context { public static final String VOICE_INTERACTION_MANAGER_SERVICE = "voiceinteraction"; /** + * Official published name of the (internal) auto-fill service. + * + * @hide + * @see #getSystemService + */ + public static final String AUTO_FILL_MANAGER_SERVICE = "autofill"; + + /** * Use with {@link #getSystemService} to access the * {@link com.android.server.voiceinteraction.SoundTriggerService}. * diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 4eecd48df646..a9e987a45b2b 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -1713,6 +1713,16 @@ public class Intent implements Parcelable, Cloneable { public static final String EXTRA_PACKAGE_NAME = "android.intent.extra.PACKAGE_NAME"; /** + * Intent extra: An app split name. + * <p> + * Type: String + * </p> + * @hide + */ + @SystemApi + public static final String EXTRA_SPLIT_NAME = "android.intent.extra.SPLIT_NAME"; + + /** * Intent extra: An extra for specifying whether a result is needed. * <p> * Type: boolean @@ -3120,10 +3130,11 @@ public class Intent implements Parcelable, Cloneable { * URIs that can be opened with * {@link ContentResolver#openFileDescriptor(Uri, String)}. * <p> - * Callers can set a document URI through {@link #setData(Uri)} to indicate - * the initial location of documents navigator. System will do its best to - * launch the navigator in the specified document if it's a folder, or the - * folder that contains the specified document if not. + * Callers can set a document URI through + * {@link DocumentsContract#EXTRA_INITIAL_URI} to indicate the initial + * location of documents navigator. System will do its best to launch the + * navigator in the specified document if it's a folder, or the folder that + * contains the specified document if not. * <p> * Output: The URI of the item that was picked, returned in * {@link #getData()}. This must be a {@code content://} URI so that any @@ -3161,10 +3172,11 @@ public class Intent implements Parcelable, Cloneable { * URIs that can be opened with * {@link ContentResolver#openFileDescriptor(Uri, String)}. * <p> - * Callers can set a document URI through {@link #setData(Uri)} to indicate - * the initial location of documents navigator. System will do its best to - * launch the navigator in the specified document if it's a folder, or the - * folder that contains the specified document if not. + * Callers can set a document URI through + * {@link DocumentsContract#EXTRA_INITIAL_URI} to indicate the initial + * location of documents navigator. System will do its best to launch the + * navigator in the specified document if it's a folder, or the folder that + * contains the specified document if not. * <p> * Output: The URI of the item that was created. This must be a * {@code content://} URI so that any receiver can access it. @@ -3188,10 +3200,11 @@ public class Intent implements Parcelable, Cloneable { * {@link DocumentsContract#buildChildDocumentsUriUsingTree(Uri, String)} * with the returned URI. * <p> - * Callers can set a document URI through {@link #setData(Uri)} to indicate - * the initial location of documents navigator. System will do its best to - * initiate the navigator in the specified document if it's a folder, or - * the folder that contains the specified document if not. + * Callers can set a document URI through + * {@link DocumentsContract#EXTRA_INITIAL_URI} to indicate the initial + * location of documents navigator. System will do its best to launch the + * navigator in the specified document if it's a folder, or the folder that + * contains the specified document if not. * <p> * Output: The URI representing the selected directory tree. * diff --git a/core/java/android/content/pm/EphemeralIntentFilter.java b/core/java/android/content/pm/EphemeralIntentFilter.java new file mode 100644 index 000000000000..0674e7c21631 --- /dev/null +++ b/core/java/android/content/pm/EphemeralIntentFilter.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.content.pm; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.content.IntentFilter; +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.ArrayList; +import java.util.List; + +/** + * Information about an ephemeral application intent filter. + * @hide + */ +@SystemApi +public final class EphemeralIntentFilter implements Parcelable { + private final String mSplitName; + /** The filters used to match domain */ + private final List<IntentFilter> mFilters = new ArrayList<IntentFilter>(); + + public EphemeralIntentFilter(@Nullable String splitName, @NonNull List<IntentFilter> filters) { + if (filters == null || filters.size() == 0) { + throw new IllegalArgumentException(); + } + mSplitName = splitName; + mFilters.addAll(filters); + } + + EphemeralIntentFilter(Parcel in) { + mSplitName = in.readString(); + in.readList(mFilters, null /*loader*/); + } + + public String getSplitName() { + return mSplitName; + } + + public List<IntentFilter> getFilters() { + return mFilters; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeString(mSplitName); + out.writeList(mFilters); + } + + public static final Parcelable.Creator<EphemeralIntentFilter> CREATOR + = new Parcelable.Creator<EphemeralIntentFilter>() { + public EphemeralIntentFilter createFromParcel(Parcel in) { + return new EphemeralIntentFilter(in); + } + + public EphemeralIntentFilter[] newArray(int size) { + return new EphemeralIntentFilter[size]; + } + }; + + /** @hide */ + public static final class EphemeralResolveIntentInfo extends IntentFilter { + private final EphemeralIntentFilter mResolveInfo; + + public EphemeralResolveIntentInfo(@NonNull IntentFilter orig, + @NonNull EphemeralIntentFilter resolveInfo) { + super(orig); + this.mResolveInfo = resolveInfo; + } + + public EphemeralIntentFilter getEphemeralResolveInfo() { + return mResolveInfo; + } + } +} diff --git a/core/java/android/content/pm/EphemeralResolveInfo.java b/core/java/android/content/pm/EphemeralResolveInfo.java index fc3b95850d21..3bed06b4816f 100644 --- a/core/java/android/content/pm/EphemeralResolveInfo.java +++ b/core/java/android/content/pm/EphemeralResolveInfo.java @@ -17,6 +17,7 @@ package android.content.pm; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.SystemApi; import android.content.IntentFilter; import android.net.Uri; @@ -41,27 +42,54 @@ public final class EphemeralResolveInfo implements Parcelable { private final EphemeralDigest mDigest; private final String mPackageName; /** The filters used to match domain */ - private final List<IntentFilter> mFilters = new ArrayList<IntentFilter>(); + private final List<EphemeralIntentFilter> mFilters; + /** Filters only for legacy clients */ + @Deprecated + private List<IntentFilter> mLegacyFilters; + @Deprecated public EphemeralResolveInfo(@NonNull Uri uri, @NonNull String packageName, @NonNull List<IntentFilter> filters) { - // validate arguments - if (uri == null - || packageName == null - || filters == null - || filters.size() == 0) { + if (uri == null || packageName == null || filters == null || filters.isEmpty()) { throw new IllegalArgumentException(); } + mDigest = new EphemeralDigest(uri.getHost()); + mPackageName = packageName; + mFilters = new ArrayList<EphemeralIntentFilter>(); + mFilters.add(new EphemeralIntentFilter(packageName, filters)); + mLegacyFilters = new ArrayList<IntentFilter>(filters.size()); + mLegacyFilters.addAll(filters); + } - mDigest = new EphemeralDigest(uri, 0xFFFFFFFF, -1); - mFilters.addAll(filters); + public EphemeralResolveInfo(@NonNull EphemeralDigest digest, @Nullable String packageName, + @Nullable List<EphemeralIntentFilter> filters) { + // validate arguments + if ((packageName == null && (filters != null && filters.size() != 0)) + || (packageName != null && (filters == null || filters.size() == 0))) { + throw new IllegalArgumentException(); + } + mDigest = digest; + if (filters != null) { + mFilters = new ArrayList<EphemeralIntentFilter>(filters.size()); + mFilters.addAll(filters); + } else { + mFilters = null; + } mPackageName = packageName; } + public EphemeralResolveInfo(@NonNull String hostName, @Nullable String packageName, + @Nullable List<EphemeralIntentFilter> filters) { + this(new EphemeralDigest(hostName), packageName, filters); + } + EphemeralResolveInfo(Parcel in) { mDigest = in.readParcelable(null /*loader*/); mPackageName = in.readString(); + mFilters = new ArrayList<EphemeralIntentFilter>(); in.readList(mFilters, null /*loader*/); + mLegacyFilters = new ArrayList<IntentFilter>(); + in.readList(mLegacyFilters, null /*loader*/); } public byte[] getDigestBytes() { @@ -76,7 +104,12 @@ public final class EphemeralResolveInfo implements Parcelable { return mPackageName; } + @Deprecated public List<IntentFilter> getFilters() { + return mLegacyFilters; + } + + public List<EphemeralIntentFilter> getIntentFilters() { return mFilters; } @@ -90,6 +123,7 @@ public final class EphemeralResolveInfo implements Parcelable { out.writeParcelable(mDigest, flags); out.writeString(mPackageName); out.writeList(mFilters); + out.writeList(mLegacyFilters); } public static final Parcelable.Creator<EphemeralResolveInfo> CREATOR @@ -106,16 +140,23 @@ public final class EphemeralResolveInfo implements Parcelable { /** @hide */ public static final class EphemeralResolveIntentInfo extends IntentFilter { private final EphemeralResolveInfo mResolveInfo; + private final String mSplitName; public EphemeralResolveIntentInfo(@NonNull IntentFilter orig, - @NonNull EphemeralResolveInfo resolveInfo) { + @NonNull EphemeralResolveInfo resolveInfo, + @Nullable String splitName) { super(orig); - this.mResolveInfo = resolveInfo; + mResolveInfo = resolveInfo; + mSplitName = splitName; } public EphemeralResolveInfo getEphemeralResolveInfo() { return mResolveInfo; } + + public String getSplitName() { + return mSplitName; + } } /** @@ -129,17 +170,25 @@ public final class EphemeralResolveInfo implements Parcelable { * * @hide */ + @SystemApi public static final class EphemeralDigest implements Parcelable { + private static final int DIGEST_MASK = 0xfffff000; + private static final int DIGEST_PREFIX_COUNT = 5; /** Full digest of the domain hashes */ private final byte[][] mDigestBytes; /** The first 4 bytes of the domain hashes */ private final int[] mDigestPrefix; - public EphemeralDigest(@NonNull Uri uri, int digestMask, int maxDigests) { - if (uri == null) { + public EphemeralDigest(@NonNull String hostName) { + this(hostName, -1 /*maxDigests*/); + } + + /** @hide */ + public EphemeralDigest(@NonNull String hostName, int maxDigests) { + if (hostName == null) { throw new IllegalArgumentException(); } - mDigestBytes = generateDigest(uri, maxDigests); + mDigestBytes = generateDigest(hostName.toLowerCase(Locale.ENGLISH), maxDigests); mDigestPrefix = new int[mDigestBytes.length]; for (int i = 0; i < mDigestBytes.length; i++) { mDigestPrefix[i] = @@ -147,31 +196,32 @@ public final class EphemeralResolveInfo implements Parcelable { | (mDigestBytes[i][1] & 0xFF) << 16 | (mDigestBytes[i][2] & 0xFF) << 8 | (mDigestBytes[i][3] & 0xFF) << 0) - & digestMask; + & DIGEST_MASK; } } - private static byte[][] generateDigest(Uri uri, int maxDigests) { + private static byte[][] generateDigest(String hostName, int maxDigests) { ArrayList<byte[]> digests = new ArrayList<>(); try { - final String host = uri.getHost().toLowerCase(Locale.ENGLISH); final MessageDigest digest = MessageDigest.getInstance(SHA_ALGORITHM); if (maxDigests <= 0) { - final byte[] hostBytes = host.getBytes(); + final byte[] hostBytes = hostName.getBytes(); digests.add(digest.digest(hostBytes)); } else { - int prevDot = host.lastIndexOf('.'); - prevDot = host.lastIndexOf('.', prevDot - 1); + int prevDot = hostName.lastIndexOf('.'); + prevDot = hostName.lastIndexOf('.', prevDot - 1); // shortcut for short URLs if (prevDot < 0) { - digests.add(digest.digest(host.getBytes())); + digests.add(digest.digest(hostName.getBytes())); } else { - byte[] hostBytes = host.substring(prevDot + 1, host.length()).getBytes(); + byte[] hostBytes = + hostName.substring(prevDot + 1, hostName.length()).getBytes(); digests.add(digest.digest(hostBytes)); int digestCount = 1; while (prevDot >= 0 && digestCount < maxDigests) { - prevDot = host.lastIndexOf('.', prevDot - 1); - hostBytes = host.substring(prevDot + 1, host.length()).getBytes(); + prevDot = hostName.lastIndexOf('.', prevDot - 1); + hostBytes = + hostName.substring(prevDot + 1, hostName.length()).getBytes(); digests.add(digest.digest(hostBytes)); digestCount++; } diff --git a/core/java/android/content/pm/ResolveInfo.java b/core/java/android/content/pm/ResolveInfo.java index b5df4d75a238..86dbe8a64ed8 100644 --- a/core/java/android/content/pm/ResolveInfo.java +++ b/core/java/android/content/pm/ResolveInfo.java @@ -18,6 +18,7 @@ package android.content.pm; import android.content.ComponentName; import android.content.IntentFilter; +import android.content.pm.EphemeralResolveInfo.EphemeralResolveIntentInfo; import android.graphics.drawable.Drawable; import android.os.Parcel; import android.os.Parcelable; @@ -65,7 +66,7 @@ public class ResolveInfo implements Parcelable { * only be set in specific circumstances. * @hide */ - public EphemeralResolveInfo ephemeralResolveInfo; + public EphemeralResolveIntentInfo ephemeralIntentInfo; /** * The IntentFilter that was matched for this ResolveInfo. diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java index 8233ad2f6f63..c46fe29d07a5 100644 --- a/core/java/android/content/res/ResourcesImpl.java +++ b/core/java/android/content/res/ResourcesImpl.java @@ -553,6 +553,7 @@ public class ResourcesImpl { if (!mPreloading && useCache) { final Drawable cachedDrawable = caches.getInstance(key, wrapper, theme); if (cachedDrawable != null) { + cachedDrawable.setChangingConfigurations(value.changingConfigurations); return cachedDrawable; } } @@ -588,9 +589,11 @@ public class ResourcesImpl { // If we were able to obtain a drawable, store it in the appropriate // cache: preload, not themed, null theme, or theme-specific. Don't // pollute the cache with drawables loaded from a foreign density. - if (dr != null && useCache) { + if (dr != null) { dr.setChangingConfigurations(value.changingConfigurations); - cacheDrawable(value, isColorDrawable, caches, theme, canApplyTheme, key, dr); + if (useCache) { + cacheDrawable(value, isColorDrawable, caches, theme, canApplyTheme, key, dr); + } } return dr; diff --git a/core/java/android/net/metrics/IpManagerEvent.java b/core/java/android/net/metrics/IpManagerEvent.java index a5b4eb5aff86..e0a026ed678d 100644 --- a/core/java/android/net/metrics/IpManagerEvent.java +++ b/core/java/android/net/metrics/IpManagerEvent.java @@ -38,9 +38,15 @@ public final class IpManagerEvent implements Parcelable { public static final int PROVISIONING_OK = 1; public static final int PROVISIONING_FAIL = 2; public static final int COMPLETE_LIFECYCLE = 3; + /** @hide */ public static final int ERROR_STARTING_IPV4 = 4; + /** @hide */ public static final int ERROR_STARTING_IPV6 = 5; + /** @hide */ public static final int ERROR_STARTING_IPREACHABILITYMONITOR = 6; /** {@hide} */ - @IntDef(value = {PROVISIONING_OK, PROVISIONING_FAIL, COMPLETE_LIFECYCLE}) + @IntDef(value = { + PROVISIONING_OK, PROVISIONING_FAIL, COMPLETE_LIFECYCLE, + ERROR_STARTING_IPV4, ERROR_STARTING_IPV6, ERROR_STARTING_IPREACHABILITYMONITOR, + }) @Retention(RetentionPolicy.SOURCE) public @interface EventType {} @@ -95,6 +101,7 @@ public final class IpManagerEvent implements Parcelable { final static class Decoder { static final SparseArray<String> constants = MessageUtils.findMessageNames( - new Class[]{IpManagerEvent.class}, new String[]{"PROVISIONING_", "COMPLETE_"}); + new Class[]{IpManagerEvent.class}, + new String[]{"PROVISIONING_", "COMPLETE_", "ERROR_"}); } } diff --git a/core/java/android/os/HwBinder.java b/core/java/android/os/HwBinder.java index 0e7da63a2215..481b2dc096d5 100644 --- a/core/java/android/os/HwBinder.java +++ b/core/java/android/os/HwBinder.java @@ -16,6 +16,7 @@ package android.os; +import java.util.ArrayList; import libcore.util.NativeAllocationRegistry; /** @hide */ @@ -39,10 +40,12 @@ public abstract class HwBinder implements IHwBinder { int code, HwParcel request, HwParcel reply, int flags); public native final void registerService( - String serviceName, int versionMajor, int versionMinor); + ArrayList<String> interfaceChain, + String serviceName); public static native final IHwBinder getService( - String serviceName, int versionMajor, int versionMinor); + String iface, + String serviceName); // Returns address of the "freeFunction". private static native final long native_init(); diff --git a/core/java/android/os/RemoteCallbackList.java b/core/java/android/os/RemoteCallbackList.java index 3546e17698b9..819afb4806b0 100644 --- a/core/java/android/os/RemoteCallbackList.java +++ b/core/java/android/os/RemoteCallbackList.java @@ -77,6 +77,7 @@ public class RemoteCallbackList<E extends IInterface> { public boolean register(E callback) { return register(callback, null); } + /** * Add a new callback to the list. This callback will remain in the list * until a corresponding call to {@link #unregister} or its hosting process @@ -326,4 +327,27 @@ public class RemoteCallbackList<E extends IInterface> { return mCallbacks.size(); } } + + /** + * Return the cookies associated with a currently registered callback. Note that this is + * <em>not</em> the same as {@link #getBroadcastCookie} and should not be used + * interchangeably with it. This method returns the current cookied registered at the given + * index, not the current broadcast state. This means that it is not itself thread-safe: + * any call to {@link #register} or {@link #unregister} will change these indices, so you + * must do your own thread safety between these to protect from such changes. + * + * @param index Index of which registration cookie to return from 0 to + * {@link #getRegisteredCallbackCount()}. + * + * @return Returns whatever cookie object is associated with this index, or null if + * {@link #kill()} has been called. + */ + public Object getRegisteredCallbackCookie(int index) { + synchronized (mCallbacks) { + if (mKilled) { + return null; + } + return mCallbacks.valueAt(index).mCookie; + } + } } diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java index 2dcf220b8ac4..f86193ff1b7c 100644 --- a/core/java/android/provider/DocumentsContract.java +++ b/core/java/android/provider/DocumentsContract.java @@ -106,6 +106,22 @@ public final class DocumentsContract { public static final String EXTRA_TARGET_URI = "android.content.extra.TARGET_URI"; /** + * Sets the desired initial location visible to user when file chooser is shown. + * + * <p>Applicable to {@link Intent} with actions: + * <ul> + * <li>{@link Intent#ACTION_OPEN_DOCUMENT}</li> + * <li>{@link Intent#ACTION_CREATE_DOCUMENT}</li> + * <li>{@link Intent#ACTION_OPEN_DOCUMENT_TREE}</li> + * </ul> + * + * <p>Location should specify a document URI or a tree URI with document ID. If + * this URI identifies a non-directory, document navigator will attempt to use the parent + * of the document as the initial location. + */ + public static final String EXTRA_INITIAL_URI = "android.provider.extra.INITIAL_URI"; + + /** * Set this in a DocumentsUI intent to cause a package's own roots to be * excluded from the roots list. */ diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 1b905a0204a4..07538dd69c2a 100755 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -4715,6 +4715,13 @@ public final class Settings { public static final String VOICE_INTERACTION_SERVICE = "voice_interaction_service"; /** + * The currently selected auto-fill service flattened ComponentName. + * @hide + */ + @TestApi + public static final String AUTO_FILL_SERVICE = "auto_fill_service"; + + /** * bluetooth HCI snoop log configuration * @hide */ @@ -6114,6 +6121,15 @@ public final class Settings { public static final String ASSIST_DISCLOSURE_ENABLED = "assist_disclosure_enabled"; /** + * Name of the service components that the current user has explicitly allowed to + * see and assist with all of the user's notifications. + * + * @hide + */ + public static final String ENABLED_NOTIFICATION_ASSISTANT = + "enabled_notification_assistant"; + + /** * Names of the service components that the current user has explicitly allowed to * see all of the user's notifications, separated by ':'. * @@ -8956,24 +8972,6 @@ public final class Settings { public static final String ENABLE_EPHEMERAL_FEATURE = "enable_ephemeral_feature"; /** - * A mask applied to the ephemeral hash to generate the hash prefix. - * <p> - * Type: int - * - * @hide - */ - public static final String EPHEMERAL_HASH_PREFIX_MASK = "ephemeral_hash_prefix_mask"; - - /** - * Number of hash prefixes to send during ephemeral resolution. - * <p> - * Type: int - * - * @hide - */ - public static final String EPHEMERAL_HASH_PREFIX_COUNT = "ephemeral_hash_prefix_count"; - - /** * The duration for caching uninstalled ephemeral apps. * <p> * Type: long diff --git a/core/java/android/service/autofill/AutoFillService.java b/core/java/android/service/autofill/AutoFillService.java new file mode 100644 index 000000000000..14ce009bedc6 --- /dev/null +++ b/core/java/android/service/autofill/AutoFillService.java @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.service.autofill; + +import android.annotation.SdkConstant; +import android.app.Service; +import android.app.assist.AssistStructure; +import android.content.Intent; +import android.os.Bundle; +import android.os.IBinder; +import android.os.Looper; +import android.os.Message; +import android.util.Log; + +import com.android.internal.os.HandlerCaller; +import com.android.internal.os.SomeArgs; + +/** + * Top-level service of the current auto-fill service for a given user. + */ +// TODO: expand documentation +public abstract class AutoFillService extends Service { + + private static final String TAG = "AutoFillService"; + private static final boolean DEBUG = true; // TODO: set to false once stable + + /** + * The {@link Intent} that must be declared as handled by the service. + * To be supported, the service must also require the + * {@link android.Manifest.permission#BIND_AUTO_FILL} permission so + * that other applications can not abuse it. + */ + @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION) + public static final String SERVICE_INTERFACE = "android.service.autofill.AutoFillService"; + + private static final int MSG_READY = 1; + private static final int MSG_NEW_SESSION = 2; + private static final int MSG_SESSION_FINISHED = 3; + private static final int MSG_SHUTDOWN = 4; + + // TODO: add metadata? + + private final IAutoFillService mInterface = new IAutoFillService.Stub() { + @Override + public void ready() { + mHandlerCaller.sendMessage(mHandlerCaller.obtainMessage(MSG_READY)); + } + + @Override + public void newSession(String token, Bundle data, int flags, + AssistStructure structure) { + mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageIOOO(MSG_NEW_SESSION, + flags, token, data, structure)); + } + + @Override + public void finishSession(String token) { + mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageO(MSG_SESSION_FINISHED, token)); + } + + @Override + public void shutdown() { + mHandlerCaller.sendMessage(mHandlerCaller.obtainMessage(MSG_SHUTDOWN)); + } + }; + + private final HandlerCaller.Callback mHandlerCallback = new HandlerCaller.Callback() { + + @Override + public void executeMessage(Message msg) { + switch (msg.what) { + case MSG_READY: { + onReady(); + break; + } case MSG_NEW_SESSION: { + final SomeArgs args = (SomeArgs) msg.obj; + final int flags = args.argi1; + final String token = (String) args.arg1; + final Bundle data = (Bundle) args.arg2; + final AssistStructure assistStructure = (AssistStructure) args.arg3; + onNewSession(token, data, flags, assistStructure); + break; + } case MSG_SESSION_FINISHED: { + final String token = (String) msg.obj; + onSessionFinished(token); + break; + } case MSG_SHUTDOWN: { + onShutdown(); + break; + } default: { + Log.w(TAG, "MyCallbacks received invalid message type: " + msg); + } + } + } + }; + + private HandlerCaller mHandlerCaller; + + @Override + public void onCreate() { + super.onCreate(); + + mHandlerCaller = new HandlerCaller(null, Looper.getMainLooper(), mHandlerCallback, true); + } + + @Override + public final IBinder onBind(Intent intent) { + if (SERVICE_INTERFACE.equals(intent.getAction())) { + return mInterface.asBinder(); + } + return null; + } + + /** + * Called during service initialization to tell you when the system is ready + * to receive interaction from it. + * + * <p>You should generally do initialization here rather than in {@link #onCreate}. + * + * <p>Sub-classes should call it first, since it sets the reference to the sytem-server service. + */ + // TODO: rename to onConnected() / add onDisconnected()? + public void onReady() { + if (DEBUG) Log.d(TAG, "onReady()"); + } + + /** + * Called to receive data from the application that the user was requested auto-fill for. + * + * @param token unique token identifying the auto-fill session, it should be used when providing + * the auto-filled fields. + * @param data Arbitrary data supplied by the app through + * {@link android.app.Activity#onProvideAssistData Activity.onProvideAssistData}. + * May be {@code null} if data has been disabled by the user or device policy. + * @param startFlags currently always 0. + * @param structure If available, the structure definition of all windows currently + * displayed by the app. May be {@code null} if auto-fill data has been disabled by the user + * or device policy; will be an empty stub if the application has disabled auto-fill + * by marking its window as secure. + */ + @SuppressWarnings("unused") + // TODO: take the factory approach where this method return a session, and move the callback + // methods (like autofill()) to the session. + public void onNewSession(String token, Bundle data, int startFlags, AssistStructure structure) { + if (DEBUG) Log.d(TAG, "onNewSession(): token=" + token); + } + + /** + * Called when an auto-fill session is finished. + */ + @SuppressWarnings("unused") + public void onSessionFinished(String token) { + if (DEBUG) Log.d(TAG, "onSessionFinished(): token=" + token); + } + + /** + * Called during service de-initialization to tell you when the system is shutting the + * service down. + * + * <p> At this point this service may no longer be an active {@link AutoFillService}. + */ + public void onShutdown() { + if (DEBUG) Log.d(TAG, "onShutdown()"); + } +} diff --git a/core/java/android/service/autofill/AutoFillServiceInfo.java b/core/java/android/service/autofill/AutoFillServiceInfo.java new file mode 100644 index 000000000000..fe2161521b82 --- /dev/null +++ b/core/java/android/service/autofill/AutoFillServiceInfo.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.service.autofill; + +import android.Manifest; +import android.app.AppGlobals; +import android.content.ComponentName; +import android.content.pm.PackageManager; +import android.content.pm.ServiceInfo; +import android.os.RemoteException; + +/** @hide */ +public final class AutoFillServiceInfo { + + private static ServiceInfo getServiceInfoOrThrow(ComponentName comp, int userHandle) + throws PackageManager.NameNotFoundException { + try { + final ServiceInfo si = + AppGlobals.getPackageManager().getServiceInfo(comp, 0, userHandle); + if (si != null) { + return si; + } + } catch (RemoteException e) { + } + throw new PackageManager.NameNotFoundException(comp.toString()); + } + + private String mParseError; + + private ServiceInfo mServiceInfo; + + private AutoFillServiceInfo(ServiceInfo si) { + if (si == null) { + mParseError = "Service not available"; + return; + } + if (!Manifest.permission.BIND_AUTO_FILL.equals(si.permission)) { + mParseError = "Service does not require permission " + + Manifest.permission.BIND_AUTO_FILL; + return; + } + + mServiceInfo = si; + } + + public AutoFillServiceInfo(ComponentName comp, int userHandle) + throws PackageManager.NameNotFoundException { + this(getServiceInfoOrThrow(comp, userHandle)); + } + + public String getParseError() { + return mParseError; + } + + public ServiceInfo getServiceInfo() { + return mServiceInfo; + } +} diff --git a/core/java/android/service/autofill/IAutoFillManagerService.aidl b/core/java/android/service/autofill/IAutoFillManagerService.aidl new file mode 100644 index 000000000000..2c0623413be6 --- /dev/null +++ b/core/java/android/service/autofill/IAutoFillManagerService.aidl @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.service.autofill; + +import android.os.Bundle; + +/** + * Intermediator between apps being auto-filled and auto-fill service implementations. + * + * {@hide} + */ +interface IAutoFillManagerService { + + /** + * Starts an auto-fill session for the top activities for a given user. + * + * It's used to start a new session from system affordances. + * + * @param userId user handle. + * @param args the bundle to pass as arguments to the voice interaction session. + * @param flags flags indicating optional session behavior. + * @param activityToken optional token of activity that needs to be on top. + * + * @return session token, or null if session was not created (for example, if the activity's + * user does not have an auto-fill service associated with). + */ + // TODO: pass callback providing an onAutoFill() method + String startSession(int userId, in Bundle args, int flags, IBinder activityToken); + + /** + * Finishes an auto-fill session. + * + * @param userId user handle. + * @param token session token. + * + * @return true if session existed and was finished. + */ + boolean finishSession(int userId, String token); + +} diff --git a/core/java/android/service/autofill/IAutoFillService.aidl b/core/java/android/service/autofill/IAutoFillService.aidl new file mode 100644 index 000000000000..73d8d5db5004 --- /dev/null +++ b/core/java/android/service/autofill/IAutoFillService.aidl @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.service.autofill; + +import android.os.Bundle; +import android.app.assist.AssistStructure; + +/** + * @hide + */ +oneway interface IAutoFillService { + void ready(); + void newSession(String token, in Bundle data, int flags, in AssistStructure structure); + void finishSession(String token); + void shutdown(); +} diff --git a/core/java/android/service/notification/Adjustment.java b/core/java/android/service/notification/Adjustment.java index 4a956c6a1d72..4b272e95f315 100644 --- a/core/java/android/service/notification/Adjustment.java +++ b/core/java/android/service/notification/Adjustment.java @@ -22,11 +22,8 @@ import android.os.Parcel; import android.os.Parcelable; /** - * Ranking updates from the Ranker. - * - * @hide + * Ranking updates from the Assistant. */ -@SystemApi public final class Adjustment implements Parcelable { private final String mPackage; private final String mKey; diff --git a/core/java/android/service/notification/NotificationRankerService.java b/core/java/android/service/notification/NotificationAssistantService.java index 928d5d847365..fdf1b26aad62 100644 --- a/core/java/android/service/notification/NotificationRankerService.java +++ b/core/java/android/service/notification/NotificationAssistantService.java @@ -17,18 +17,12 @@ package android.service.notification; import android.annotation.SdkConstant; -import android.annotation.SystemApi; -import android.content.ComponentName; import android.content.Context; import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; -import android.os.Parcel; -import android.os.Parcelable; import android.os.RemoteException; import android.util.Log; import com.android.internal.os.SomeArgs; @@ -36,20 +30,17 @@ import com.android.internal.os.SomeArgs; import java.util.List; /** - * A service that helps the user manage notifications. This class is only used to - * extend the framework service and may not be implemented by non-framework components. - * @hide + * A service that helps the user manage notifications. */ -@SystemApi -public abstract class NotificationRankerService extends NotificationListenerService { - private static final String TAG = "NotificationRankers"; +public abstract class NotificationAssistantService extends NotificationListenerService { + private static final String TAG = "NotificationAssistants"; /** * The {@link Intent} that must be declared as handled by the service. */ @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION) public static final String SERVICE_INTERFACE - = "android.service.notification.NotificationRankerService"; + = "android.service.notification.NotificationAssistantService"; /** Notification was canceled by the status bar reporting a click. */ public static final int REASON_DELEGATE_CLICK = 1; @@ -107,19 +98,6 @@ public abstract class NotificationRankerService extends NotificationListenerServ private Handler mHandler; - /** @hide */ - @Override - public void registerAsSystemService(Context context, ComponentName componentName, - int currentUser) { - throw new UnsupportedOperationException("the ranker lifecycle is managed by the system."); - } - - /** @hide */ - @Override - public void unregisterAsSystemService() { - throw new UnsupportedOperationException("the ranker lifecycle is managed by the system."); - } - @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); @@ -129,7 +107,7 @@ public abstract class NotificationRankerService extends NotificationListenerServ @Override public final IBinder onBind(Intent intent) { if (mWrapper == null) { - mWrapper = new NotificationRankingServiceWrapper(); + mWrapper = new NotificationAssistantServiceWrapper(); } return mWrapper; } @@ -146,41 +124,6 @@ public abstract class NotificationRankerService extends NotificationListenerServ int importance, boolean user); /** - * The visibility of a notification has changed. - * - * @param key the notification key - * @param time milliseconds since midnight, January 1, 1970 UTC. - * @param visible true if the notification became visible, false if hidden. - */ - public void onNotificationVisibilityChanged(String key, long time, boolean visible) - { - // Do nothing, Override this to collect visibility statistics. - } - - /** - * The user clicked on a notification. - * - * @param key the notification key - * @param time milliseconds since midnight, January 1, 1970 UTC. - */ - public void onNotificationClick(String key, long time) - { - // Do nothing, Override this to collect click statistics - } - - /** - * The user clicked on a notification action. - * - * @param key the notification key - * @param time milliseconds since midnight, January 1, 1970 UTC. - * @param actionIndex the index of the action button that was pressed. - */ - public void onNotificationActionClick(String key, long time, int actionIndex) - { - // Do nothing, Override this to collect action button click statistics - } - - /** * A notification was removed. * @param key the notification key @@ -201,7 +144,7 @@ public abstract class NotificationRankerService extends NotificationListenerServ public final void adjustNotification(Adjustment adjustment) { if (!isBound()) return; try { - getNotificationInterface().applyAdjustmentFromRankerService(mWrapper, adjustment); + getNotificationInterface().applyAdjustmentFromAssistantService(mWrapper, adjustment); } catch (android.os.RemoteException ex) { Log.v(TAG, "Unable to contact notification manager", ex); } @@ -217,13 +160,13 @@ public abstract class NotificationRankerService extends NotificationListenerServ public final void adjustNotifications(List<Adjustment> adjustments) { if (!isBound()) return; try { - getNotificationInterface().applyAdjustmentsFromRankerService(mWrapper, adjustments); + getNotificationInterface().applyAdjustmentsFromAssistantService(mWrapper, adjustments); } catch (android.os.RemoteException ex) { Log.v(TAG, "Unable to contact notification manager", ex); } } - private class NotificationRankingServiceWrapper extends NotificationListenerWrapper { + private class NotificationAssistantServiceWrapper extends NotificationListenerWrapper { @Override public void onNotificationEnqueued(IStatusBarNotificationHolder sbnHolder, int importance, boolean user) { @@ -244,35 +187,6 @@ public abstract class NotificationRankerService extends NotificationListenerServ } @Override - public void onNotificationVisibilityChanged(String key, long time, boolean visible) { - SomeArgs args = SomeArgs.obtain(); - args.arg1 = key; - args.arg2 = time; - args.argi1 = visible ? 1 : 0; - mHandler.obtainMessage(MyHandler.MSG_ON_NOTIFICATION_VISIBILITY_CHANGED, - args).sendToTarget(); - } - - @Override - public void onNotificationClick(String key, long time) { - SomeArgs args = SomeArgs.obtain(); - args.arg1 = key; - args.arg2 = time; - mHandler.obtainMessage(MyHandler.MSG_ON_NOTIFICATION_CLICK, - args).sendToTarget(); - } - - @Override - public void onNotificationActionClick(String key, long time, int actionIndex) { - SomeArgs args = SomeArgs.obtain(); - args.arg1 = key; - args.arg2 = time; - args.argi1 = actionIndex; - mHandler.obtainMessage(MyHandler.MSG_ON_NOTIFICATION_ACTION_CLICK, - args).sendToTarget(); - } - - @Override public void onNotificationRemovedReason(String key, long time, int reason) { SomeArgs args = SomeArgs.obtain(); args.arg1 = key; @@ -285,9 +199,6 @@ public abstract class NotificationRankerService extends NotificationListenerServ private final class MyHandler extends Handler { public static final int MSG_ON_NOTIFICATION_ENQUEUED = 1; - public static final int MSG_ON_NOTIFICATION_VISIBILITY_CHANGED = 2; - public static final int MSG_ON_NOTIFICATION_CLICK = 3; - public static final int MSG_ON_NOTIFICATION_ACTION_CLICK = 4; public static final int MSG_ON_NOTIFICATION_REMOVED_REASON = 5; public MyHandler(Looper looper) { @@ -309,32 +220,6 @@ public abstract class NotificationRankerService extends NotificationListenerServ } } break; - case MSG_ON_NOTIFICATION_VISIBILITY_CHANGED: { - SomeArgs args = (SomeArgs) msg.obj; - final String key = (String) args.arg1; - final long time = (long) args.arg2; - final boolean visible = args.argi1 == 1; - args.recycle(); - onNotificationVisibilityChanged(key, time, visible); - } break; - - case MSG_ON_NOTIFICATION_CLICK: { - SomeArgs args = (SomeArgs) msg.obj; - final String key = (String) args.arg1; - final long time = (long) args.arg2; - args.recycle(); - onNotificationClick(key, time); - } break; - - case MSG_ON_NOTIFICATION_ACTION_CLICK: { - SomeArgs args = (SomeArgs) msg.obj; - final String key = (String) args.arg1; - final long time = (long) args.arg2; - final int actionIndex = args.argi1; - args.recycle(); - onNotificationActionClick(key, time, actionIndex); - } break; - case MSG_ON_NOTIFICATION_REMOVED_REASON: { SomeArgs args = (SomeArgs) msg.obj; final String key = (String) args.arg1; diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java index be0b47cc58ac..dfb6b8639912 100644 --- a/core/java/android/service/notification/StatusBarNotification.java +++ b/core/java/android/service/notification/StatusBarNotification.java @@ -17,6 +17,7 @@ package android.service.notification; import android.app.Notification; +import android.app.NotificationChannel; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; @@ -42,25 +43,21 @@ public class StatusBarNotification implements Parcelable { private final Notification notification; private final UserHandle user; private final long postTime; + private final NotificationChannel channel; private Context mContext; // used for inflation & icon expansion /** @hide */ - public StatusBarNotification(String pkg, String opPkg, int id, String tag, int uid, - int initialPid, int score, Notification notification, UserHandle user) { - this(pkg, opPkg, id, tag, uid, initialPid, score, notification, user, - System.currentTimeMillis()); - } - - /** @hide */ - public StatusBarNotification(String pkg, String opPkg, int id, String tag, int uid, - int initialPid, Notification notification, UserHandle user, String overrideGroupKey, - long postTime) { + public StatusBarNotification(String pkg, String opPkg, NotificationChannel channel, int id, + String tag, int uid, int initialPid, Notification notification, UserHandle user, + String overrideGroupKey, long postTime) { if (pkg == null) throw new NullPointerException(); if (notification == null) throw new NullPointerException(); + if (channel == null) throw new IllegalArgumentException(); this.pkg = pkg; this.opPkg = opPkg; + this.channel = channel; this.id = id; this.tag = tag; this.uid = uid; @@ -73,6 +70,7 @@ public class StatusBarNotification implements Parcelable { this.groupKey = groupKey(); } + @Deprecated public StatusBarNotification(String pkg, String opPkg, int id, String tag, int uid, int initialPid, int score, Notification notification, UserHandle user, long postTime) { @@ -90,6 +88,7 @@ public class StatusBarNotification implements Parcelable { this.postTime = postTime; this.key = key(); this.groupKey = groupKey(); + this.channel = null; } public StatusBarNotification(Parcel in) { @@ -113,6 +112,7 @@ public class StatusBarNotification implements Parcelable { } this.key = key(); this.groupKey = groupKey(); + this.channel = NotificationChannel.CREATOR.createFromParcel(in); } private String key() { @@ -182,6 +182,7 @@ public class StatusBarNotification implements Parcelable { } else { out.writeInt(0); } + this.channel.writeToParcel(out, flags); } public int describeContents() { @@ -208,14 +209,14 @@ public class StatusBarNotification implements Parcelable { public StatusBarNotification cloneLight() { final Notification no = new Notification(); this.notification.cloneInto(no, false); // light copy - return new StatusBarNotification(this.pkg, this.opPkg, + return new StatusBarNotification(this.pkg, this.opPkg, this.channel, this.id, this.tag, this.uid, this.initialPid, no, this.user, this.overrideGroupKey, this.postTime); } @Override public StatusBarNotification clone() { - return new StatusBarNotification(this.pkg, this.opPkg, + return new StatusBarNotification(this.pkg, this.opPkg, this.channel, this.id, this.tag, this.uid, this.initialPid, this.notification.clone(), this.user, this.overrideGroupKey, this.postTime); } @@ -335,6 +336,13 @@ public class StatusBarNotification implements Parcelable { } /** + * Returns the channel this notification was posted to. + */ + public NotificationChannel getNotificationChannel() { + return channel; + } + + /** * @hide */ public Context getPackageContext(Context context) { diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java index f9afcc7ac36c..fd6fc7dc0860 100644 --- a/core/java/android/text/Layout.java +++ b/core/java/android/text/Layout.java @@ -634,6 +634,17 @@ public abstract class Layout { } /** + * Return the total height of this layout. + * + * @param cap if true and max lines is set, returns the height of the layout at the max lines. + * + * @hide + */ + public int getHeight(boolean cap) { + return getHeight(); + } + + /** * Return the base alignment of this layout. */ public final Alignment getAlignment() { diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java index bdbe8b0f9a24..081be3afd6d3 100644 --- a/core/java/android/text/StaticLayout.java +++ b/core/java/android/text/StaticLayout.java @@ -836,7 +836,7 @@ public class StaticLayout extends Layout { here = endPos; breakIndex++; - if (mLineCount >= mMaximumVisibleLineCount) { + if (mLineCount >= mMaximumVisibleLineCount && mEllipsized) { return; } } @@ -920,7 +920,25 @@ public class StaticLayout extends Layout { boolean firstLine = (j == 0); boolean currentLineIsTheLastVisibleOne = (j + 1 == mMaximumVisibleLineCount); - boolean lastLine = currentLineIsTheLastVisibleOne || (end == bufEnd); + + if (ellipsize != null) { + // If there is only one line, then do any type of ellipsis except when it is MARQUEE + // if there are multiple lines, just allow END ellipsis on the last line + boolean forceEllipsis = moreChars && (mLineCount + 1 == mMaximumVisibleLineCount); + + boolean doEllipsis = + (((mMaximumVisibleLineCount == 1 && moreChars) || (firstLine && !moreChars)) && + ellipsize != TextUtils.TruncateAt.MARQUEE) || + (!firstLine && (currentLineIsTheLastVisibleOne || !moreChars) && + ellipsize == TextUtils.TruncateAt.END); + if (doEllipsis) { + calculateEllipsis(start, end, widths, widthStart, + ellipsisWidth, ellipsize, j, + textWidth, paint, forceEllipsis); + } + } + + boolean lastLine = mEllipsized || (end == bufEnd); if (firstLine) { if (trackPad) { @@ -944,7 +962,6 @@ public class StaticLayout extends Layout { } } - if (needMultiply && !lastLine) { double ex = (below - above) * (spacingmult - 1) + spacingadd; if (ex >= 0) { @@ -960,6 +977,15 @@ public class StaticLayout extends Layout { lines[off + TOP] = v; lines[off + DESCENT] = below + extra; + // special case for non-ellipsized last visible line when maxLines is set + // store the height as if it was ellipsized + if (!mEllipsized && currentLineIsTheLastVisibleOne) { + // below calculation as if it was the last line + int maxLineBelow = includePad ? bottom : below; + // similar to the calculation of v below, without the extra. + mMaxLineHeight = v + (maxLineBelow - above); + } + v += (below - above) + extra; lines[off + mColumns + START] = end; lines[off + mColumns + TOP] = v; @@ -981,23 +1007,6 @@ public class StaticLayout extends Layout { start - widthStart, end - start); } - if (ellipsize != null) { - // If there is only one line, then do any type of ellipsis except when it is MARQUEE - // if there are multiple lines, just allow END ellipsis on the last line - boolean forceEllipsis = moreChars && (mLineCount + 1 == mMaximumVisibleLineCount); - - boolean doEllipsis = - (((mMaximumVisibleLineCount == 1 && moreChars) || (firstLine && !moreChars)) && - ellipsize != TextUtils.TruncateAt.MARQUEE) || - (!firstLine && (currentLineIsTheLastVisibleOne || !moreChars) && - ellipsize == TextUtils.TruncateAt.END); - if (doEllipsis) { - calculateEllipsis(start, end, widths, widthStart, - ellipsisWidth, ellipsize, j, - textWidth, paint, forceEllipsis); - } - } - mLineCount++; return v; } @@ -1105,7 +1114,7 @@ public class StaticLayout extends Layout { } } } - + mEllipsized = true; mLines[mColumns * line + ELLIPSIS_START] = ellipsisStart; mLines[mColumns * line + ELLIPSIS_COUNT] = ellipsisCount; } @@ -1243,6 +1252,25 @@ public class StaticLayout extends Layout { return mEllipsizedWidth; } + /** + * Return the total height of this layout. + * + * @param cap if true and max lines is set, returns the height of the layout at the max lines. + * + * @hide + */ + public int getHeight(boolean cap) { + if (cap && mLineCount >= mMaximumVisibleLineCount && mMaxLineHeight == -1 && + Log.isLoggable(TAG, Log.WARN)) { + Log.w(TAG, "maxLineHeight should not be -1. " + + " maxLines:" + mMaximumVisibleLineCount + + " lineCount:" + mLineCount); + } + + return cap && mLineCount >= mMaximumVisibleLineCount && mMaxLineHeight != -1 ? + mMaxLineHeight : super.getHeight(); + } + private static native long nNewBuilder(); private static native void nFreeBuilder(long nativePtr); private static native void nFinishBuilder(long nativePtr); @@ -1281,6 +1309,21 @@ public class StaticLayout extends Layout { private int mColumns; private int mEllipsizedWidth; + /** + * Keeps track if ellipsize is applied to the text. + */ + private boolean mEllipsized; + + /** + * If maxLines is set, ellipsize is not set, and the actual line count of text is greater than + * or equal to maxLine, this variable holds the ideal visual height of the maxLine'th line + * starting from the top of the layout. If maxLines is not set its value will be -1. + * + * The value is the same as getLineTop(maxLines) for ellipsized version where structurally no + * more than maxLines is contained. + */ + private int mMaxLineHeight = -1; + private static final int COLUMNS_NORMAL = 4; private static final int COLUMNS_ELLIPSIZE = 6; private static final int START = 0; diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java index 03a2d6233967..c4118605b44c 100644 --- a/core/java/android/text/TextLine.java +++ b/core/java/android/text/TextLine.java @@ -850,6 +850,11 @@ class TextLine { int limit, boolean runIsRtl, Canvas c, float x, int top, int y, int bottom, FontMetricsInt fmi, boolean needWidth) { + if (measureLimit < start || measureLimit > limit) { + throw new IndexOutOfBoundsException("measureLimit (" + measureLimit + ") is out of " + + "start (" + start + ") and limit (" + limit + ") bounds"); + } + // Case of an empty line, make sure we update fmi according to mPaint if (start == measureLimit) { TextPaint wp = mWorkPaint; diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 5a6cf7dfaa23..cdd8b6a4a5c7 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -5611,6 +5611,13 @@ public final class ViewRootImpl implements ViewParent, } } + /** + * Notify that the window title changed + */ + public void onWindowTitleChanged() { + mAttachInfo.mForceReportNewAttributes = true; + } + public void handleDispatchWindowShown() { mAttachInfo.mTreeObserver.dispatchOnWindowShown(); } diff --git a/core/java/android/view/ViewStub.java b/core/java/android/view/ViewStub.java index ec852e88b17e..85d10f199218 100644 --- a/core/java/android/view/ViewStub.java +++ b/core/java/android/view/ViewStub.java @@ -142,11 +142,17 @@ public final class ViewStub extends View { * @see #getInflatedId() * @attr ref android.R.styleable#ViewStub_inflatedId */ - @android.view.RemotableViewMethod + @android.view.RemotableViewMethod(asyncImpl = "setInflatedIdAsync") public void setInflatedId(@IdRes int inflatedId) { mInflatedId = inflatedId; } + /** @hide **/ + public Runnable setInflatedIdAsync(@IdRes int inflatedId) { + mInflatedId = inflatedId; + return null; + } + /** * Returns the layout resource that will be used by {@link #setVisibility(int)} or * {@link #inflate()} to replace this StubbedView @@ -176,11 +182,17 @@ public final class ViewStub extends View { * @see #inflate() * @attr ref android.R.styleable#ViewStub_layout */ - @android.view.RemotableViewMethod + @android.view.RemotableViewMethod(asyncImpl = "setLayoutResourceAsync") public void setLayoutResource(@LayoutRes int layoutResource) { mLayoutResource = layoutResource; } + /** @hide **/ + public Runnable setLayoutResourceAsync(@LayoutRes int layoutResource) { + mLayoutResource = layoutResource; + return null; + } + /** * Set {@link LayoutInflater} to use in {@link #inflate()}, or {@code null} * to use the default. @@ -220,7 +232,7 @@ public final class ViewStub extends View { * @see #inflate() */ @Override - @android.view.RemotableViewMethod + @android.view.RemotableViewMethod(asyncImpl = "setVisibilityAsync") public void setVisibility(int visibility) { if (mInflatedViewRef != null) { View view = mInflatedViewRef.get(); @@ -237,6 +249,43 @@ public final class ViewStub extends View { } } + /** @hide **/ + public Runnable setVisibilityAsync(int visibility) { + if (visibility == VISIBLE || visibility == INVISIBLE) { + ViewGroup parent = (ViewGroup) getParent(); + return new ViewReplaceRunnable(inflateViewNoAdd(parent)); + } else { + return null; + } + } + + private View inflateViewNoAdd(ViewGroup parent) { + final LayoutInflater factory; + if (mInflater != null) { + factory = mInflater; + } else { + factory = LayoutInflater.from(mContext); + } + final View view = factory.inflate(mLayoutResource, parent, false); + + if (mInflatedId != NO_ID) { + view.setId(mInflatedId); + } + return view; + } + + private void replaceSelfWithView(View view, ViewGroup parent) { + final int index = parent.indexOfChild(this); + parent.removeViewInLayout(this); + + final ViewGroup.LayoutParams layoutParams = getLayoutParams(); + if (layoutParams != null) { + parent.addView(view, index, layoutParams); + } else { + parent.addView(view, index); + } + } + /** * Inflates the layout resource identified by {@link #getLayoutResource()} * and replaces this StubbedView in its parent by the inflated layout resource. @@ -250,31 +299,10 @@ public final class ViewStub extends View { if (viewParent != null && viewParent instanceof ViewGroup) { if (mLayoutResource != 0) { final ViewGroup parent = (ViewGroup) viewParent; - final LayoutInflater factory; - if (mInflater != null) { - factory = mInflater; - } else { - factory = LayoutInflater.from(mContext); - } - final View view = factory.inflate(mLayoutResource, parent, - false); - - if (mInflatedId != NO_ID) { - view.setId(mInflatedId); - } - - final int index = parent.indexOfChild(this); - parent.removeViewInLayout(this); - - final ViewGroup.LayoutParams layoutParams = getLayoutParams(); - if (layoutParams != null) { - parent.addView(view, index, layoutParams); - } else { - parent.addView(view, index); - } - - mInflatedViewRef = new WeakReference<View>(view); + final View view = inflateViewNoAdd(parent); + replaceSelfWithView(view, parent); + mInflatedViewRef = new WeakReference<>(view); if (mInflateListener != null) { mInflateListener.onInflate(this, view); } @@ -317,4 +345,18 @@ public final class ViewStub extends View { */ void onInflate(ViewStub stub, View inflated); } + + /** @hide **/ + public class ViewReplaceRunnable implements Runnable { + public final View view; + + ViewReplaceRunnable(View view) { + this.view = view; + } + + @Override + public void run() { + replaceSelfWithView(view, (ViewGroup) getParent()); + } + } } diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index b2a77d0051b3..18ce260e7136 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -58,6 +58,7 @@ import android.view.RemotableViewMethod; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; +import android.view.ViewStub; import android.widget.AdapterView.OnItemClickListener; import com.android.internal.R; @@ -1456,6 +1457,13 @@ public class RemoteViews implements Parcelable, Filter { if (endAction == null) { return ACTION_NOOP; } else { + // Special case view stub + if (endAction instanceof ViewStub.ViewReplaceRunnable) { + root.createTree(); + // Replace child tree + root.findViewTreeById(viewId).replaceView( + ((ViewStub.ViewReplaceRunnable) endAction).view); + } return new RunnableAction(endAction); } } @@ -1581,16 +1589,26 @@ public class RemoteViews implements Parcelable, Filter { if ((target == null) || !(target.mRoot instanceof ViewGroup)) { return ACTION_NOOP; } + final ViewGroup targetVg = (ViewGroup) target.mRoot; if (nestedViews == null) { // Clear all children when nested views omitted target.mChildren = null; - return this; + return new RuntimeAction() { + @Override + public void apply(View root, ViewGroup rootParent, OnClickHandler handler) + throws ActionException { + targetVg.removeAllViews(); + } + }; } else { // Inflate nested views and perform all the async tasks for the child remoteView. final Context context = root.mRoot.getContext(); final AsyncApplyTask task = nestedViews.getAsyncApplyTask( - context, (ViewGroup) target.mRoot, null, handler); + context, targetVg, null, handler); final ViewTree tree = task.doInBackground(); + if (tree == null) { + throw new ActionException(task.mError); + } // Update the global view tree, so that next call to findViewTreeById // goes through the subtree as well. @@ -1600,10 +1618,8 @@ public class RemoteViews implements Parcelable, Filter { @Override public void apply(View root, ViewGroup rootParent, OnClickHandler handler) throws ActionException { - // This view will exist as we have already made sure - final ViewGroup target = (ViewGroup) root.findViewById(viewId); task.onPostExecute(tree); - target.addView(task.mResult); + targetVg.addView(task.mResult); } }; } @@ -3360,7 +3376,7 @@ public class RemoteViews implements Parcelable, Filter { int count = mRV.mActions.size(); mActions = new Action[count]; for (int i = 0; i < count && !isCancelled(); i++) { - // TODO: check if isCanclled in nested views. + // TODO: check if isCancelled in nested views. mActions[i] = mRV.mActions.get(i).initActionAsync(mTree, mParent, mHandler); } } else { @@ -3629,7 +3645,7 @@ public class RemoteViews implements Parcelable, Filter { * and can be searched. */ private static class ViewTree { - private final View mRoot; + private View mRoot; private ArrayList<ViewTree> mChildren; @@ -3643,7 +3659,7 @@ public class RemoteViews implements Parcelable, Filter { } mChildren = new ArrayList<>(); - if (mRoot instanceof ViewGroup && mRoot.isRootNamespace()) { + if (mRoot instanceof ViewGroup) { ViewGroup vg = (ViewGroup) mRoot; int count = vg.getChildCount(); for (int i = 0; i < count; i++) { @@ -3668,6 +3684,12 @@ public class RemoteViews implements Parcelable, Filter { return null; } + public void replaceView(View v) { + mRoot = v; + mChildren = null; + createTree(); + } + public View findViewById(int id) { if (mChildren == null) { return mRoot.findViewById(id); @@ -3685,6 +3707,12 @@ public class RemoteViews implements Parcelable, Filter { } private void addViewChild(View v) { + // ViewTree only contains Views which can be found using findViewById. + // If isRootNamespace is true, this view is skipped. + // @see ViewGroup#findViewTraversal(int) + if (v.isRootNamespace()) { + return; + } final ViewTree target; // If the view has a valid id, i.e., if can be found using findViewById, add it to the @@ -3697,7 +3725,7 @@ public class RemoteViews implements Parcelable, Filter { target = this; } - if (v instanceof ViewGroup && v.isRootNamespace()) { + if (v instanceof ViewGroup) { if (target.mChildren == null) { target.mChildren = new ArrayList<>(); ViewGroup vg = (ViewGroup) v; diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 9c48cf8e8806..73af7558100f 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -5157,7 +5157,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * call {@link InputMethodManager#restartInput(View)}.</p> * @param hintLocales List of the languages that the user is supposed to switch to no matter * what input method subtype is currently used. Set {@code null} to clear the current "hint". - * @see #getImeHIntLocales() + * @see #getImeHintLocales() * @see android.view.inputmethod.EditorInfo#hintLocales */ public void setImeHintLocales(@Nullable LocaleList hintLocales) { @@ -7000,11 +7000,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener .setLineSpacing(mSpacingAdd, mSpacingMult) .setIncludePad(mIncludePad) .setBreakStrategy(mBreakStrategy) - .setHyphenationFrequency(mHyphenationFrequency); + .setHyphenationFrequency(mHyphenationFrequency) + .setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE); if (shouldEllipsize) { builder.setEllipsize(mEllipsize) - .setEllipsizedWidth(ellipsisWidth) - .setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE); + .setEllipsizedWidth(ellipsisWidth); } mHintLayout = builder.build(); } @@ -7091,11 +7091,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener .setLineSpacing(mSpacingAdd, mSpacingMult) .setIncludePad(mIncludePad) .setBreakStrategy(mBreakStrategy) - .setHyphenationFrequency(mHyphenationFrequency); + .setHyphenationFrequency(mHyphenationFrequency) + .setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE); if (shouldEllipsize) { builder.setEllipsize(effectiveEllipsize) - .setEllipsizedWidth(ellipsisWidth) - .setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE); + .setEllipsizedWidth(ellipsisWidth); } // TODO: explore always setting maxLines result = builder.build(); @@ -7367,9 +7367,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener return 0; } - int linecount = layout.getLineCount(); - int pad = getCompoundPaddingTop() + getCompoundPaddingBottom(); - int desired = layout.getLineTop(linecount); + /* + * Don't cap the hint to a certain number of lines. + * (Do cap it, though, if we have a maximum pixel height.) + */ + int desired = layout.getHeight(cap); final Drawables dr = mDrawables; if (dr != null) { @@ -7377,31 +7379,14 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener desired = Math.max(desired, dr.mDrawableHeightRight); } - desired += pad; - - if (mMaxMode == LINES) { - /* - * Don't cap the hint to a certain number of lines. - * (Do cap it, though, if we have a maximum pixel height.) - */ - if (cap) { - if (linecount > mMaximum) { - desired = layout.getLineTop(mMaximum); + desired += getCompoundPaddingTop() + getCompoundPaddingBottom(); - if (dr != null) { - desired = Math.max(desired, dr.mDrawableHeightLeft); - desired = Math.max(desired, dr.mDrawableHeightRight); - } - - desired += pad; - linecount = mMaximum; - } - } - } else { + if (mMaxMode != LINES) { desired = Math.min(desired, mMaximum); } if (mMinMode == LINES) { + int linecount = layout.getLineCount(); if (linecount < mMinimum) { desired += getLineHeight() * (mMinimum - linecount); } diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index 3b6073a6eacc..d8f7907524ee 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -70,7 +70,7 @@ import android.widget.ListView; import com.android.internal.R; import com.android.internal.app.ResolverActivity.TargetInfo; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.google.android.collect.Lists; import java.io.File; diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index 1e26c92dd764..72a40b7dcb45 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -71,7 +71,7 @@ import android.widget.TextView; import android.widget.Toast; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto; +import com.android.internal.logging.nano.MetricsProto; import com.android.internal.widget.ResolverDrawerLayout; import java.util.ArrayList; diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java index ef725da1e463..a94f30867e40 100644 --- a/core/java/com/android/internal/logging/MetricsLogger.java +++ b/core/java/com/android/internal/logging/MetricsLogger.java @@ -19,7 +19,7 @@ import android.content.Context; import android.os.Build; import android.view.View; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; /** * Log all the things. diff --git a/core/java/com/android/internal/os/AppFuseMount.java b/core/java/com/android/internal/os/AppFuseMount.java new file mode 100644 index 000000000000..b392186ccc77 --- /dev/null +++ b/core/java/com/android/internal/os/AppFuseMount.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.os; + +import android.os.Parcel; +import android.os.ParcelFileDescriptor; +import android.os.Parcelable; +import java.io.File; + +public class AppFuseMount implements Parcelable { + final public File mountPoint; + final public ParcelFileDescriptor fd; + + public AppFuseMount(File mountPoint, ParcelFileDescriptor fd) { + this.mountPoint = mountPoint; + this.fd = fd; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(this.mountPoint.getPath()); + dest.writeParcelable(fd, flags); + } + + public static final Parcelable.Creator<AppFuseMount> CREATOR = + new Parcelable.Creator<AppFuseMount>() { + @Override + public AppFuseMount createFromParcel(Parcel in) { + return new AppFuseMount(new File(in.readString()), in.readParcelable(null)); + } + + @Override + public AppFuseMount[] newArray(int size) { + return new AppFuseMount[size]; + } + }; +} diff --git a/core/java/com/android/internal/policy/EmergencyAffordanceManager.java b/core/java/com/android/internal/policy/EmergencyAffordanceManager.java index bed7c1ba4ed3..eb75bd497434 100644 --- a/core/java/com/android/internal/policy/EmergencyAffordanceManager.java +++ b/core/java/com/android/internal/policy/EmergencyAffordanceManager.java @@ -20,6 +20,7 @@ import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Build; +import android.os.UserHandle; import android.provider.Settings; /** @@ -72,7 +73,7 @@ public class EmergencyAffordanceManager { Intent intent = new Intent(Intent.ACTION_CALL_EMERGENCY); intent.setData(getPhoneUri(context)); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - context.startActivity(intent); + context.startActivityAsUser(intent, UserHandle.CURRENT); } /** diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java index 878f3a69a504..50621f482d4f 100644 --- a/core/java/com/android/internal/policy/PhoneWindow.java +++ b/core/java/com/android/internal/policy/PhoneWindow.java @@ -540,6 +540,13 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { WindowManager.LayoutParams params = getAttributes(); if (!TextUtils.equals(title, params.accessibilityTitle)) { params.accessibilityTitle = TextUtils.stringOrSpannedString(title); + if (mDecor != null) { + // ViewRootImpl will make sure the change propagates to WindowManagerService + ViewRootImpl vr = mDecor.getViewRootImpl(); + if (vr != null) { + vr.onWindowTitleChanged(); + } + } dispatchWindowAttributesChanged(getAttributes()); } } diff --git a/core/jni/Android.mk b/core/jni/Android.mk index 91e831074615..f5429a1c5082 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -211,6 +211,7 @@ LOCAL_C_INCLUDES += \ external/skia/include/private \ external/skia/src/core \ external/skia/src/effects \ + external/skia/src/image \ external/skia/src/images \ external/sqlite/dist \ external/sqlite/android \ diff --git a/core/jni/android/graphics/Shader.cpp b/core/jni/android/graphics/Shader.cpp index 657b1ef63043..0de46e6b4d04 100644 --- a/core/jni/android/graphics/Shader.cpp +++ b/core/jni/android/graphics/Shader.cpp @@ -95,15 +95,13 @@ static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jobject jbitmap, // we'll pass an empty SkBitmap to avoid crashing/excepting for compatibility. GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap); } - sk_sp<SkShader> s = SkMakeBitmapShader(bitmap, - (SkShader::TileMode)tileModeX, - (SkShader::TileMode)tileModeY, - nullptr, - kNever_SkCopyPixelsMode, - nullptr); - - ThrowIAE_IfNull(env, s.get()); - return reinterpret_cast<jlong>(s.release()); + + sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode); + sk_sp<SkShader> shader = image->makeShader((SkShader::TileMode)tileModeX, + (SkShader::TileMode)tileModeY); + + ThrowIAE_IfNull(env, shader.get()); + return reinterpret_cast<jlong>(shader.release()); } /////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/core/jni/android_os_HwBinder.cpp b/core/jni/android_os_HwBinder.cpp index 1a33d9111fdb..10090a1f6942 100644 --- a/core/jni/android_os_HwBinder.cpp +++ b/core/jni/android_os_HwBinder.cpp @@ -34,6 +34,8 @@ #include "core_jni_helpers.h" using android::AndroidRuntime; +using android::hardware::hidl_vec; +using android::hardware::hidl_string; #define PACKAGE_PATH "android/os" #define CLASS_NAME "HwBinder" @@ -41,10 +43,15 @@ using android::AndroidRuntime; namespace android { +static jclass gArrayListClass; +static struct { + jmethodID size; + jmethodID get; +} gArrayListMethods; + static struct fields_t { jfieldID contextID; jmethodID onTransactID; - } gFields; // static @@ -199,45 +206,46 @@ static void JHwBinder_native_transact( static void JHwBinder_native_registerService( JNIEnv *env, jobject thiz, - jstring serviceNameObj, - jint versionMajor, - jint versionMinor) { + jobject interfaceChainArrayList, + jstring serviceNameObj) { if (serviceNameObj == NULL) { jniThrowException(env, "java/lang/NullPointerException", NULL); return; } - if (versionMajor < 0 - || versionMajor > 65535 - || versionMinor < 0 - || versionMinor > 65535) { - jniThrowException(env, "java/lang/IllegalArgumentException", NULL); - return; - } - - const jchar *serviceName = env->GetStringCritical(serviceNameObj, NULL); - + const char *serviceName = env->GetStringUTFChars(serviceNameObj, NULL); if (serviceName == NULL) { return; // XXX exception already pending? } - using android::hidl::manager::V1_0::IServiceManager; + jint numInterfaces = env->CallIntMethod(interfaceChainArrayList, + gArrayListMethods.size); + hidl_string *strings = new hidl_string[numInterfaces]; + + for (jint i = 0; i < numInterfaces; i++) { + jstring strObj = static_cast<jstring>( + env->CallObjectMethod(interfaceChainArrayList, + gArrayListMethods.get, + i) + ); + const char * str = env->GetStringUTFChars(strObj, nullptr); + strings[i] = hidl_string(str); + env->ReleaseStringUTFChars(strObj, str); + } - const IServiceManager::Version kVersion { - .major = static_cast<uint16_t>(versionMajor), - .minor = static_cast<uint16_t>(versionMinor), - }; + hidl_vec<hidl_string> interfaceChain; + interfaceChain.setToExternal(strings, numInterfaces, true /* shouldOwn */); + + using android::hidl::manager::V1_0::IServiceManager; sp<hardware::IBinder> binder = JHwBinder::GetNativeContext(env, thiz); bool ok = hardware::defaultServiceManager()->add( - String8(String16( - reinterpret_cast<const char16_t *>(serviceName), - env->GetStringLength(serviceNameObj))).string(), - binder, - kVersion); + interfaceChain, + serviceName, + binder); - env->ReleaseStringCritical(serviceNameObj, serviceName); + env->ReleaseStringUTFChars(serviceNameObj, serviceName); serviceName = NULL; if (ok) { @@ -251,52 +259,43 @@ static void JHwBinder_native_registerService( static jobject JHwBinder_native_getService( JNIEnv *env, jclass /* clazzObj */, - jstring serviceNameObj, - jint versionMajor, - jint versionMinor) { - if (serviceNameObj == NULL) { + jstring ifaceNameObj, + jstring serviceNameObj) { + + if (ifaceNameObj == NULL) { jniThrowException(env, "java/lang/NullPointerException", NULL); return NULL; } - - if (versionMajor < 0 - || versionMajor > 65535 - || versionMinor < 0 - || versionMinor > 65535) { - jniThrowException(env, "java/lang/IllegalArgumentException", NULL); + if (serviceNameObj == NULL) { + jniThrowException(env, "java/lang/NullPointerException", NULL); return NULL; } - const jchar *serviceName = env->GetStringCritical(serviceNameObj, NULL); - + const char *ifaceName = env->GetStringUTFChars(ifaceNameObj, NULL); + if (ifaceName == NULL) { + return NULL; // XXX exception already pending? + } + const char *serviceName = env->GetStringUTFChars(serviceNameObj, NULL); if (serviceName == NULL) { - return NULL; // XXX exception already pending? + env->ReleaseStringUTFChars(ifaceNameObj, ifaceName); + return NULL; // XXX exception already pending? } - using android::hidl::manager::V1_0::IServiceManager; - - const IServiceManager::Version kVersion { - .major = static_cast<uint16_t>(versionMajor), - .minor = static_cast<uint16_t>(versionMinor), - }; - LOG(INFO) << "looking for service '" - << String8(String16( - reinterpret_cast<const char16_t *>(serviceName), - env->GetStringLength(serviceNameObj))).string() + << serviceName << "'"; sp<hardware::IBinder> service; hardware::defaultServiceManager()->get( - String8(String16( - reinterpret_cast<const char16_t *>(serviceName), - env->GetStringLength(serviceNameObj))).string(), - kVersion, + ifaceName, + serviceName, [&service](sp<hardware::IBinder> out) { service = out; }); - env->ReleaseStringCritical(serviceNameObj, serviceName); + env->ReleaseStringUTFChars(ifaceNameObj, ifaceName); + ifaceName = NULL; + env->ReleaseStringUTFChars(serviceNameObj, serviceName); serviceName = NULL; if (service == NULL) { @@ -318,16 +317,21 @@ static JNINativeMethod gMethods[] = { "(IL" PACKAGE_PATH "/HwParcel;L" PACKAGE_PATH "/HwParcel;I)V", (void *)JHwBinder_native_transact }, - { "registerService", "(Ljava/lang/String;II)V", + { "registerService", "(Ljava/util/ArrayList;Ljava/lang/String;)V", (void *)JHwBinder_native_registerService }, - { "getService", "(Ljava/lang/String;II)L" PACKAGE_PATH "/IHwBinder;", + { "getService", "(Ljava/lang/String;Ljava/lang/String;)L" PACKAGE_PATH "/IHwBinder;", (void *)JHwBinder_native_getService }, }; namespace android { int register_android_os_HwBinder(JNIEnv *env) { + jclass arrayListClass = FindClassOrDie(env, "java/util/ArrayList"); + gArrayListClass = MakeGlobalRefOrDie(env, arrayListClass); + gArrayListMethods.size = GetMethodIDOrDie(env, arrayListClass, "size", "()I"); + gArrayListMethods.get = GetMethodIDOrDie(env, arrayListClass, "get", "(I)Ljava/lang/Object;"); + return RegisterMethodsOrDie(env, CLASS_PATH, gMethods, NELEM(gMethods)); } diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp index a58bc9039881..d70fbb9d3915 100644 --- a/core/jni/android_util_AssetManager.cpp +++ b/core/jni/android_util_AssetManager.cpp @@ -178,7 +178,11 @@ static void verifySystemIdmaps() // Directories to scan for overlays: if OVERLAY_THEME_DIR_PROPERTY is defined, // use OVERLAY_DIR/<value of OVERLAY_THEME_DIR_PROPERTY> in addition to OVERLAY_DIR. char subdir[PROP_VALUE_MAX]; - int len = __system_property_get(AssetManager::OVERLAY_THEME_DIR_PROPERTY, subdir); + int len = __system_property_get(AssetManager::OVERLAY_THEME_DIR_PERSIST_PROPERTY, + subdir); + if (len == 0) { + len = __system_property_get(AssetManager::OVERLAY_THEME_DIR_PROPERTY, subdir); + } if (len > 0) { String8 overlayPath = String8(AssetManager::OVERLAY_DIR) + "/" + subdir; if (stat(overlayPath.string(), &st) == 0) { diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index af117d18bf45..fc85b4bd3734 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -449,6 +449,20 @@ static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArra jstring instructionSet, jstring dataDir) { SetSigChldHandler(); + sigset_t sigchld; + sigemptyset(&sigchld); + sigaddset(&sigchld, SIGCHLD); + + // Temporarily block SIGCHLD during forks. The SIGCHLD handler might + // log, which would result in the logging FDs we close being reopened. + // This would cause failures because the FDs are not whitelisted. + // + // Note that the zygote process is single threaded at this point. + if (sigprocmask(SIG_BLOCK, &sigchld, nullptr) == -1) { + ALOGE("sigprocmask(SIG_SETMASK, { SIGCHLD }) failed: %s", strerror(errno)); + RuntimeAbort(env, __LINE__, "Call to sigprocmask(SIG_BLOCK, { SIGCHLD }) failed."); + } + // Close any logging related FDs before we start evaluating the list of // file descriptors. __android_log_close(); @@ -482,6 +496,11 @@ static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArra RuntimeAbort(env, __LINE__, "Unable to reopen whitelisted descriptors."); } + if (sigprocmask(SIG_UNBLOCK, &sigchld, nullptr) == -1) { + ALOGE("sigprocmask(SIG_SETMASK, { SIGCHLD }) failed: %s", strerror(errno)); + RuntimeAbort(env, __LINE__, "Call to sigprocmask(SIG_UNBLOCK, { SIGCHLD }) failed."); + } + // Keep capabilities across UID change, unless we're staying root. if (uid != 0) { EnableKeepCapabilities(env); @@ -609,6 +628,12 @@ static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArra } } else if (pid > 0) { // the parent process + + // We blocked SIGCHLD prior to a fork, we unblock it here. + if (sigprocmask(SIG_UNBLOCK, &sigchld, nullptr) == -1) { + ALOGE("sigprocmask(SIG_SETMASK, { SIGCHLD }) failed: %s", strerror(errno)); + RuntimeAbort(env, __LINE__, "Call to sigprocmask(SIG_UNBLOCK, { SIGCHLD }) failed."); + } } return pid; } diff --git a/core/jni/fd_utils-inl.h b/core/jni/fd_utils-inl.h index b78b8ffa2d5d..2babe441a56d 100644 --- a/core/jni/fd_utils-inl.h +++ b/core/jni/fd_utils-inl.h @@ -260,11 +260,11 @@ class FileDescriptorInfo { } // Whitelist files needed for Runtime Resource Overlay, like these: - // /system/vendor/overlay/framework-res.apk - // /system/vendor/overlay/PG/android-framework-runtime-resource-overlay.apk + // /vendor/overlay/framework-res.apk + // /vendor/overlay/PG/android-framework-runtime-resource-overlay.apk // /data/resource-cache/system@vendor@overlay@framework-res.apk@idmap // /data/resource-cache/system@vendor@overlay@PG@framework-res.apk@idmap - static const char* kOverlayDir = "/system/vendor/overlay/"; + static const char* kOverlayDir = "/vendor/overlay/"; static const char* kApkSuffix = ".apk"; if (android::base::StartsWith(path, kOverlayDir) diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 4eebea6da46d..3dea051afb4e 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -2323,6 +2323,13 @@ <permission android:name="android.permission.BIND_VOICE_INTERACTION" android:protectionLevel="signature" /> + <!-- Must be required by a {@link android.service.autofill.AutoFillService}, + to ensure that only the system can bind to it. + <p>Protection level: signature + --> + <permission android:name="android.permission.BIND_AUTO_FILL" + android:protectionLevel="signature" /> + <!-- Must be required by hotword enrollment application, to ensure that only the system can interact with it. @hide <p>Not for use by third-party applications.</p> --> @@ -2937,11 +2944,11 @@ android:protectionLevel="signature" /> <!-- Must be required by an {@link - android.service.notification.NotificationRankerService to ensure that only the system can bind to it. + android.service.notification.NotificationAssistantService to ensure that only the system + can bind to it. <p>Protection level: signature - @hide This is not a third-party API (intended for system apps). --> --> - <permission android:name="android.permission.BIND_NOTIFICATION_RANKER_SERVICE" + <permission android:name="android.permission.BIND_NOTIFICATION_ASSISTANT_SERVICE" android:protectionLevel="signature" /> <!-- Must be required by a {@link @@ -3118,6 +3125,11 @@ <permission android:name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME" android:protectionLevel="signature|privileged" /> + <!-- @SystemApi Allows an application to manage auto-fill sessions. + @hide <p>Not for use by third-party applications.</p> --> + <permission android:name="android.permission.MANAGE_AUTO_FILL" + android:protectionLevel="signature" /> + <application android:process="system" android:persistent="true" android:hasCode="false" diff --git a/core/res/res/layout-notround-watch/alert_dialog_title_material.xml b/core/res/res/layout-notround-watch/alert_dialog_title_material.xml index 0ab56f95efbe..08eecef1da95 100644 --- a/core/res/res/layout-notround-watch/alert_dialog_title_material.xml +++ b/core/res/res/layout-notround-watch/alert_dialog_title_material.xml @@ -18,14 +18,14 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" + android:paddingTop="?attr/dialogPreferredPadding" + android:paddingBottom="8dp" android:orientation="vertical" - android:gravity="top|center_horizontal" - android:minHeight="@dimen/alert_dialog_title_height"> + android:gravity="center_horizontal|top"> <ImageView android:id="@+id/icon" android:adjustViewBounds="true" android:maxHeight="24dp" android:maxWidth="24dp" - android:layout_marginTop="8dp" android:layout_marginStart="8dp" android:layout_marginBottom="8dp" android:layout_width="wrap_content" @@ -33,7 +33,6 @@ android:src="@null" /> <TextView android:id="@+id/alertTitle" style="?android:attr/windowTitleStyle" - android:layout_marginBottom="8dp" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> diff --git a/core/res/res/layout-round-watch/alert_dialog_title_material.xml b/core/res/res/layout-round-watch/alert_dialog_title_material.xml index aefe28f7f359..dac1e324be81 100644 --- a/core/res/res/layout-round-watch/alert_dialog_title_material.xml +++ b/core/res/res/layout-round-watch/alert_dialog_title_material.xml @@ -18,6 +18,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" + android:paddingBottom="8dp" android:orientation="vertical" android:gravity="top|center_horizontal"> <FrameLayout @@ -30,7 +31,6 @@ android:maxHeight="24dp" android:maxWidth="24dp" android:layout_marginTop="@dimen/screen_percentage_10" - android:layout_marginBottom="8dp" android:layout_gravity="center_horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" @@ -38,7 +38,6 @@ </FrameLayout> <TextView android:id="@+id/alertTitle" style="?android:attr/windowTitleStyle" - android:layout_marginBottom="8dp" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> diff --git a/core/res/res/layout-watch/alert_dialog_material.xml b/core/res/res/layout-watch/alert_dialog_material.xml index 2fe13de2120a..960b927a0e64 100644 --- a/core/res/res/layout-watch/alert_dialog_material.xml +++ b/core/res/res/layout-watch/alert_dialog_material.xml @@ -50,7 +50,7 @@ <TextView android:id="@+id/message" android:layout_width="match_parent" android:layout_height="wrap_content" - android:gravity="@integer/config_dialogTextGravity" + android:gravity="center_horizontal|top" android:textAppearance="@style/TextAppearance.Material.Subhead" android:paddingStart="?dialogPreferredPadding" android:paddingEnd="?dialogPreferredPadding" @@ -80,7 +80,6 @@ android:layout_height="wrap_content" android:layout_gravity="bottom" android:orientation="vertical" - android:minHeight="@dimen/alert_dialog_button_bar_height" android:paddingBottom="?dialogPreferredPadding" style="?android:attr/buttonBarStyle" android:measureWithLargestChild="true"> diff --git a/core/res/res/layout-watch/preference_list_fragment_material.xml b/core/res/res/layout-watch/preference_list_fragment_material.xml index ae8f203a7ce6..22e66d513936 100644 --- a/core/res/res/layout-watch/preference_list_fragment_material.xml +++ b/core/res/res/layout-watch/preference_list_fragment_material.xml @@ -44,7 +44,7 @@ android:paddingEnd="@dimen/dialog_padding_material" android:paddingBottom="8dp" android:textAppearance="@style/TextAppearance.Material.Title" - android:gravity="center" /> + android:gravity="center_horizontal|top" /> </com.android.internal.widget.WatchHeaderListView> </FrameLayout> diff --git a/core/res/res/layout/select_dialog_multichoice_material.xml b/core/res/res/layout/select_dialog_multichoice_material.xml index 36e8e57b2988..731fe1619634 100644 --- a/core/res/res/layout/select_dialog_multichoice_material.xml +++ b/core/res/res/layout/select_dialog_multichoice_material.xml @@ -26,5 +26,5 @@ android:paddingStart="@dimen/select_dialog_padding_start_material" android:paddingEnd="?attr/dialogPreferredPadding" android:drawableStart="?attr/listChoiceIndicatorMultiple" - android:drawablePadding="20dp" + android:drawablePadding="@dimen/select_dialog_drawable_padding_start_material" android:ellipsize="marquee" /> diff --git a/core/res/res/layout/select_dialog_singlechoice_material.xml b/core/res/res/layout/select_dialog_singlechoice_material.xml index 995272ad80ef..77b693058e82 100644 --- a/core/res/res/layout/select_dialog_singlechoice_material.xml +++ b/core/res/res/layout/select_dialog_singlechoice_material.xml @@ -26,5 +26,5 @@ android:paddingStart="@dimen/select_dialog_padding_start_material" android:paddingEnd="?attr/dialogPreferredPadding" android:drawableStart="?attr/listChoiceIndicatorSingle" - android:drawablePadding="20dp" + android:drawablePadding="@dimen/select_dialog_drawable_padding_start_material" android:ellipsize="marquee" /> diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml index f873b1c3a038..993d49bebd08 100644 --- a/core/res/res/values-bn-rBD/strings.xml +++ b/core/res/res/values-bn-rBD/strings.xml @@ -1432,7 +1432,7 @@ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string> <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"সরান"</string> <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"প্রস্তাবিত স্তরের চেয়ে বেশি উঁচুতে ভলিউম বাড়াবেন?\n\nউঁচু ভলিউমে বেশি সময় ধরে কিছু শুনলে আপনার শ্রবনশক্তির ক্ষতি হতে পারে।"</string> - <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"অ্যাক্সেসযোগ্যতা সক্রিয় করতে দুইটি আঙ্গুলকে চেপে নীচে ধরে রাখুন৷"</string> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"অ্যাক্সেসযোগ্যতা সক্রিয় করতে দুইটি আঙ্গুলকে চেপে নিচে ধরে রাখুন৷"</string> <string name="accessibility_enabled" msgid="1381972048564547685">"অ্যাক্সেসযোগ্যতা সক্ষম করা হয়েছে৷"</string> <string name="enable_accessibility_canceled" msgid="3833923257966635673">"অ্যাক্সেসযোগ্যতা বাতিল করা হয়েছে৷"</string> <string name="user_switched" msgid="3768006783166984410">"বর্তমান ব্যবহারকারী <xliff:g id="NAME">%1$s</xliff:g>৷"</string> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index 07f6aa8ca72d..c63ec413f7d4 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -1246,7 +1246,7 @@ <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"La VPN sempre activada està desconnectada"</string> <string name="vpn_lockdown_error" msgid="6009249814034708175">"Error de la VPN sempre activada"</string> <string name="vpn_lockdown_config" msgid="5099330695245008680">"Toca per configurar"</string> - <string name="upload_file" msgid="2897957172366730416">"Trieu un fitxer"</string> + <string name="upload_file" msgid="2897957172366730416">"Tria un fitxer"</string> <string name="no_file_chosen" msgid="6363648562170759465">"No s\'ha escollit cap fitxer"</string> <string name="reset" msgid="2448168080964209908">"Restableix"</string> <string name="submit" msgid="1602335572089911941">"Envia"</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 05155ca23acf..9d8c98be596e 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -1226,7 +1226,7 @@ <string name="deny" msgid="2081879885755434506">"Ablehnen"</string> <string name="permission_request_notification_title" msgid="6486759795926237907">"Berechtigung angefordert"</string> <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Berechtigung angefordert\nfür Konto <xliff:g id="ACCOUNT">%s</xliff:g>"</string> - <string name="forward_intent_to_owner" msgid="1207197447013960896">"Sie verwenden diese App außerhalb Ihres Arbeitsprofils"</string> + <string name="forward_intent_to_owner" msgid="1207197447013960896">"Du verwendest diese App außerhalb deines Arbeitsprofils"</string> <string name="forward_intent_to_work" msgid="621480743856004612">"Du verwendest diese App in deinem Arbeitsprofil."</string> <string name="input_method_binding_label" msgid="1283557179944992649">"Eingabemethode"</string> <string name="sync_binding_label" msgid="3687969138375092423">"Synchronisieren"</string> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index f0cfd0be70f3..6e1012a3cbfc 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -254,7 +254,7 @@ <string name="permgrouplab_storage" msgid="1971118770546336966">"저장"</string> <string name="permgroupdesc_storage" msgid="637758554581589203">"기기 사진, 미디어, 파일 액세스"</string> <string name="permgrouplab_microphone" msgid="171539900250043464">"마이크"</string> - <string name="permgroupdesc_microphone" msgid="4988812113943554584">"오디오를 녹음할 수 있도록"</string> + <string name="permgroupdesc_microphone" msgid="4988812113943554584">"오디오 녹음"</string> <string name="permgrouplab_camera" msgid="4820372495894586615">"카메라"</string> <string name="permgroupdesc_camera" msgid="3250611594678347720">"사진 및 동영상 촬영"</string> <string name="permgrouplab_phone" msgid="5229115638567440675">"전화"</string> diff --git a/core/res/res/values-notround-watch/dimens_material.xml b/core/res/res/values-notround-watch/dimens_material.xml index 9cacb117cf7b..9fdf55b8a31d 100644 --- a/core/res/res/values-notround-watch/dimens_material.xml +++ b/core/res/res/values-notround-watch/dimens_material.xml @@ -15,12 +15,16 @@ --> <resources> <dimen name="dialog_padding_material">8dp</dimen> - <dimen name="preference_fragment_padding_vertical_material">0dp</dimen> + <dimen name="preference_fragment_padding_vertical_material">8dp</dimen> - <dimen name="list_item_padding_horizontal_material">16dp</dimen> - <dimen name="list_item_padding_start_material">16dp</dimen> - <dimen name="list_item_padding_end_material">16dp</dimen> + <dimen name="list_item_padding_horizontal_material">8dp</dimen> + <dimen name="list_item_padding_start_material">8dp</dimen> + <dimen name="list_item_padding_end_material">8dp</dimen> - <dimen name="dialog_list_padding_top_no_title">8dp</dimen> - <dimen name="dialog_list_padding_bottom_no_buttons">8dp</dimen> + <dimen name="dialog_list_padding_top_no_title">0dp</dimen> + <dimen name="dialog_list_padding_bottom_no_buttons">0dp</dimen> + + <!-- Dialog padding minus control padding, used to fix alignment. --> + <dimen name="select_dialog_padding_start_material">8dp</dimen> + <dimen name="select_dialog_drawable_padding_start_material">8dp</dimen> </resources> diff --git a/core/res/res/values-round-watch/config_material.xml b/core/res/res/values-round-watch/config_material.xml index 11798709f148..ae4a6eedf4fd 100644 --- a/core/res/res/values-round-watch/config_material.xml +++ b/core/res/res/values-round-watch/config_material.xml @@ -20,9 +20,6 @@ <!-- Don't clip on round screens so the list can scroll past the rounded edges. --> <bool name="config_preferenceFragmentClipToPadding">false</bool> - <!-- Gravity that should be used for dialog text styles. Equivalent to: Gravity.CENTER_HORIZONTAL | Gravity.TOP --> - <integer name="config_dialogTextGravity">0x00000031</integer> - <!-- The amount to offset when scrolling to a selection in an AlertDialog --> <dimen name="config_alertDialogSelectionScrollOffset">@dimen/screen_percentage_15</dimen> </resources> diff --git a/core/res/res/values-round-watch/dimens_material.xml b/core/res/res/values-round-watch/dimens_material.xml index f2de4e013a78..c8f27b1724e3 100644 --- a/core/res/res/values-round-watch/dimens_material.xml +++ b/core/res/res/values-round-watch/dimens_material.xml @@ -23,4 +23,8 @@ <dimen name="dialog_list_padding_top_no_title">@dimen/screen_percentage_15</dimen> <dimen name="dialog_list_padding_bottom_no_buttons">@dimen/screen_percentage_15</dimen> + + <!-- Dialog padding minus control padding, used to fix alignment. --> + <dimen name="select_dialog_padding_start_material">@dimen/screen_percentage_15</dimen> + <dimen name="select_dialog_drawable_padding_start_material">8dp</dimen> </resources> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 99831421eda4..12a5b7c1a025 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -773,7 +773,7 @@ <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Bu sayfada kal"</string> <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nBu sayfadan ayrılmak istediğinizden emin misiniz?"</string> <string name="save_password_label" msgid="6860261758665825069">"Onayla"</string> - <string name="double_tap_toast" msgid="4595046515400268881">"İpucu: Yakınlaştırmak ve uzaklaştırmak için iki kez hafifçe dokunun."</string> + <string name="double_tap_toast" msgid="4595046515400268881">"İpucu: Yakınlaştırmak ve uzaklaştırmak için iki kez dokunun."</string> <string name="autofill_this_form" msgid="4616758841157816676">"Otomatik Doldur"</string> <string name="setup_autofill" msgid="7103495070180590814">"Otomatik doldurma ayarla"</string> <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string> @@ -1133,7 +1133,7 @@ <string name="carrier_app_dialog_button" msgid="7900235513678617329">"UYGULAMAYI AL"</string> <string name="carrier_app_dialog_not_now" msgid="6361378684292268027">"ŞİMDİ DEĞİL"</string> <string name="carrier_app_notification_title" msgid="8921767385872554621">"Yeni SIM kart takıldı"</string> - <string name="carrier_app_notification_text" msgid="1132487343346050225">"Kurmak için hafifçe dokunun"</string> + <string name="carrier_app_notification_text" msgid="1132487343346050225">"Kurmak için dokunun"</string> <string name="time_picker_dialog_title" msgid="8349362623068819295">"Saati ayarlayın"</string> <string name="date_picker_dialog_title" msgid="5879450659453782278">"Tarihi ayarlayın"</string> <string name="date_time_set" msgid="5777075614321087758">"Ayarla"</string> @@ -1531,7 +1531,7 @@ <string name="reason_unknown" msgid="6048913880184628119">"bilinmiyor"</string> <string name="reason_service_unavailable" msgid="7824008732243903268">"Yazdırma hizmeti etkin değil"</string> <string name="print_service_installed_title" msgid="2246317169444081628">"<xliff:g id="NAME">%s</xliff:g> hizmeti yüklendi"</string> - <string name="print_service_installed_message" msgid="5897362931070459152">"Etkinleştirmek için hafifçe dokunun"</string> + <string name="print_service_installed_message" msgid="5897362931070459152">"Etkinleştirmek için dokunun"</string> <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Yönetici PIN\'ini girin"</string> <string name="restr_pin_enter_pin" msgid="3395953421368476103">"PIN\'i girin"</string> <string name="restr_pin_incorrect" msgid="8571512003955077924">"Yanlış"</string> @@ -1660,9 +1660,9 @@ <string name="user_encrypted_message" msgid="4923292604515744267">"Kilidi açmak için dokunun"</string> <string name="user_encrypted_detail" msgid="5708447464349420392">"Kullanıcı verileri kilitlendi"</string> <string name="profile_encrypted_detail" msgid="3700965619978314974">"İş profili kilitlendi"</string> - <string name="profile_encrypted_message" msgid="6964994232310195874">"İş profilinin kilidini açmak için hafifçe dokunun"</string> + <string name="profile_encrypted_message" msgid="6964994232310195874">"İş profilinin kilidini açmak için dokunun"</string> <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> cihazına bağlandı"</string> - <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Dosyaları görüntülemek için hafifçe dokunun"</string> + <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Dosyaları görüntülemek için dokunun"</string> <string name="pin_target" msgid="3052256031352291362">"Sabitle"</string> <string name="unpin_target" msgid="3556545602439143442">"Sabitlemeyi kaldır"</string> <string name="app_info" msgid="6856026610594615344">"Uygulama bilgileri"</string> diff --git a/core/res/res/values-notround-watch/config_material.xml b/core/res/res/values-watch/dimens.xml index a99674f3f060..4c8b39ca92a7 100644 --- a/core/res/res/values-notround-watch/config_material.xml +++ b/core/res/res/values-watch/dimens.xml @@ -13,13 +13,9 @@ See the License for the specific language governing permissions and limitations under the License. --> - -<!-- These resources are around just to allow their values to be customized - for different hardware and product builds, only for Material theme. Do not translate. - - NOTE: The naming convention is "config_camelCaseValue". --> - -<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- Gravity that should be used for dialog text styles. Equivalent to: Gravity.START | Gravity.TOP --> - <integer name="config_dialogTextGravity">0x00800033</integer> +<resources> + <!-- Dialog title height, not used in watch due to dynamically sized button bar --> + <dimen name="alert_dialog_title_height">0dp</dimen> + <!-- Dialog button bar height, not used in watch due to dynamically sized button bar --> + <dimen name="alert_dialog_button_bar_height">0dp</dimen> </resources> diff --git a/core/res/res/values-watch/styles_material.xml b/core/res/res/values-watch/styles_material.xml index af4207ed4e6f..0053c12d9d84 100644 --- a/core/res/res/values-watch/styles_material.xml +++ b/core/res/res/values-watch/styles_material.xml @@ -98,7 +98,7 @@ please see styles_device_defaults.xml. <item name="maxLines">@empty</item> <item name="scrollHorizontally">false</item> <item name="textAppearance">@style/TextAppearance.Material.DialogWindowTitle</item> - <item name="gravity">@integer/config_dialogTextGravity</item> + <item name="gravity">center_horizontal|top</item> <item name="ellipsize">end</item> </style> </resources> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index c3967e46c3e9..2d61e6ec3bc5 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -8335,4 +8335,15 @@ i <declare-styleable name="ShortcutCategories"> <attr name="name" /> </declare-styleable> + + <!-- Attributes that are read when parsing a <font> tag, which is a child of + <font-family>. --> + <declare-styleable name="FontFamilyFont"> + <attr name="fontStyle"> + <enum name="normal" value="0" /> + <enum name="italic" value="1" /> + </attr> + <attr name="font" format="reference" /> + <attr name="fontWeight" format="integer" /> + </declare-styleable> </resources> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index ff1d383ac3d7..52db0b9adc39 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -1919,6 +1919,12 @@ mirror the content of the default display. --> <bool name="config_localDisplaysMirrorContent">true</bool> + <!-- The default mode for the default display. One of the following values (See Display.java): + 0 - COLOR_MODE_DEFAULT + 7 - COLOR_MODE_SRGB + --> + <integer name="config_defaultDisplayDefaultColorMode">0</integer> + <!-- When true use the linux /dev/input/event subsystem to detect the switch changes on the headphone/microphone jack. When false use the older uevent framework. --> <bool name="config_useDevInputEventForAudioJack">false</bool> @@ -2238,6 +2244,9 @@ provisioning, availability etc --> <bool name="config_carrier_wfc_ims_available">false</bool> + <!-- Whether to use voip audio mode for ims call --> + <bool name="config_use_voip_mode_for_ims">false</bool> + <bool name="config_networkSamplingWakesDevice">true</bool> <string-array translatable="false" name="config_cdma_home_system" /> diff --git a/core/res/res/values/dimens_material.xml b/core/res/res/values/dimens_material.xml index 30e7b3137712..ebe577c73758 100644 --- a/core/res/res/values/dimens_material.xml +++ b/core/res/res/values/dimens_material.xml @@ -129,6 +129,7 @@ <!-- Dialog padding minus control padding, used to fix alignment. --> <dimen name="select_dialog_padding_start_material">20dp</dimen> + <dimen name="select_dialog_drawable_padding_start_material">20dp</dimen> <dimen name="seekbar_track_background_height_material">2dp</dimen> <dimen name="seekbar_track_progress_height_material">2dp</dimen> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index c06a93df4687..ed685822ee51 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2756,6 +2756,9 @@ <eat-comment /> <public-group type="attr" first-id="0x01010531"> + <public name="fontStyle" /> + <public name="font" /> + <public name="fontWeight" /> </public-group> <public-group type="style" first-id="0x010302e0"> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 92fff65efac8..9f7b1edb5683 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -309,6 +309,7 @@ <java-symbol type="bool" name="config_supportsMultiWindow" /> <java-symbol type="bool" name="config_guestUserEphemeral" /> <java-symbol type="bool" name="config_localDisplaysMirrorContent" /> + <java-symbol type="integer" name="config_defaultDisplayDefaultColorMode" /> <java-symbol type="bool" name="config_enableAppWidgetService" /> <java-symbol type="string" name="config_defaultPictureInPictureScreenEdgeInsets" /> <java-symbol type="string" name="config_defaultPictureInPictureSize" /> @@ -2228,6 +2229,7 @@ <java-symbol type="bool" name="config_carrier_vt_available" /> <java-symbol type="bool" name="config_device_wfc_ims_available" /> <java-symbol type="bool" name="config_carrier_wfc_ims_available" /> + <java-symbol type="bool" name="config_use_voip_mode_for_ims" /> <java-symbol type="attr" name="touchscreenBlocksFocus" /> <java-symbol type="layout" name="resolver_list_with_default" /> <java-symbol type="string" name="whichApplicationNamed" /> diff --git a/core/tests/coretests/res/layout/remote_view_host.xml b/core/tests/coretests/res/layout/remote_view_host.xml index 19d0a738decc..68095081a9d9 100644 --- a/core/tests/coretests/res/layout/remote_view_host.xml +++ b/core/tests/coretests/res/layout/remote_view_host.xml @@ -19,7 +19,7 @@ --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/container" android:orientation="vertical" android:layout_width="match_parent" - android:layout_height="match_parent"> -</LinearLayout> + android:layout_height="match_parent" /> diff --git a/core/tests/coretests/res/layout/remote_views_text.xml b/core/tests/coretests/res/layout/remote_views_text.xml new file mode 100644 index 000000000000..a265d2e4b21e --- /dev/null +++ b/core/tests/coretests/res/layout/remote_views_text.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2016 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License + --> + +<TextView xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/text" + android:layout_width="match_parent" + android:layout_height="match_parent" /> diff --git a/core/tests/coretests/res/layout/remote_views_viewstub.xml b/core/tests/coretests/res/layout/remote_views_viewstub.xml new file mode 100644 index 000000000000..d5327491ac5d --- /dev/null +++ b/core/tests/coretests/res/layout/remote_views_viewstub.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2016 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License + --> + +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1"> + + <ViewStub android:id="@+id/viewStub" + android:inflatedId="@+id/stub_inflated" + android:layout_width="match_parent" + android:layout_height="match_parent" /> +</FrameLayout> diff --git a/core/tests/coretests/src/android/widget/RemoteViewsTest.java b/core/tests/coretests/src/android/widget/RemoteViewsTest.java index 7ba46bed8b34..b6b0e68c7b89 100644 --- a/core/tests/coretests/src/android/widget/RemoteViewsTest.java +++ b/core/tests/coretests/src/android/widget/RemoteViewsTest.java @@ -20,11 +20,13 @@ import android.content.Context; import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; +import android.os.AsyncTask; import android.os.Parcel; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import android.view.View; +import android.view.ViewGroup; import com.android.frameworks.coretests.R; @@ -38,6 +40,10 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.concurrent.CountDownLatch; + /** * Tests for RemoteViews. */ @@ -166,4 +172,164 @@ public class RemoteViewsTest { parcel.recycle(); return size; } + + @Test + public void asyncApply_fail() throws Exception { + RemoteViews views = new RemoteViews(mPackage, R.layout.remote_view_test_bad_1); + ViewAppliedListener listener = new ViewAppliedListener(); + views.applyAsync(mContext, mContainer, AsyncTask.THREAD_POOL_EXECUTOR, listener); + + boolean exceptionThrown = false; + try { + listener.waitAndGetView(); + } catch (Exception e) { + exceptionThrown = true; + } + assertTrue(exceptionThrown); + } + + @Test + public void asyncApply() throws Exception { + RemoteViews views = new RemoteViews(mPackage, R.layout.remote_views_test); + views.setTextViewText(R.id.text, "Dummy"); + + View syncView = views.apply(mContext, mContainer); + + ViewAppliedListener listener = new ViewAppliedListener(); + views.applyAsync(mContext, mContainer, AsyncTask.THREAD_POOL_EXECUTOR, listener); + View asyncView = listener.waitAndGetView(); + + verifyViewTree(syncView, asyncView, "Dummy"); + } + + @Test + public void asyncApply_viewStub() throws Exception { + RemoteViews views = new RemoteViews(mPackage, R.layout.remote_views_viewstub); + views.setInt(R.id.viewStub, "setLayoutResource", R.layout.remote_views_text); + // This will cause the view to be inflated + views.setViewVisibility(R.id.viewStub, View.INVISIBLE); + views.setTextViewText(R.id.stub_inflated, "Dummy"); + + View syncView = views.apply(mContext, mContainer); + + ViewAppliedListener listener = new ViewAppliedListener(); + views.applyAsync(mContext, mContainer, AsyncTask.THREAD_POOL_EXECUTOR, listener); + View asyncView = listener.waitAndGetView(); + + verifyViewTree(syncView, asyncView, "Dummy"); + } + + @Test + public void asyncApply_nestedViews() throws Exception { + RemoteViews views = new RemoteViews(mPackage, R.layout.remote_view_host); + views.removeAllViews(R.id.container); + views.addView(R.id.container, createViewChained(1, "row1-c1", "row1-c2", "row1-c3")); + views.addView(R.id.container, createViewChained(5, "row2-c1", "row2-c2")); + views.addView(R.id.container, createViewChained(2, "row3-c1", "row3-c2")); + + View syncView = views.apply(mContext, mContainer); + + ViewAppliedListener listener = new ViewAppliedListener(); + views.applyAsync(mContext, mContainer, AsyncTask.THREAD_POOL_EXECUTOR, listener); + View asyncView = listener.waitAndGetView(); + + verifyViewTree(syncView, asyncView, + "row1-c1", "row1-c2", "row1-c3", "row2-c1", "row2-c2", "row3-c1", "row3-c2"); + } + + @Test + public void asyncApply_viewstub_nestedViews() throws Exception { + RemoteViews viewstub = new RemoteViews(mPackage, R.layout.remote_views_viewstub); + viewstub.setInt(R.id.viewStub, "setLayoutResource", R.layout.remote_view_host); + // This will cause the view to be inflated + viewstub.setViewVisibility(R.id.viewStub, View.INVISIBLE); + viewstub.addView(R.id.stub_inflated, createViewChained(1, "row1-c1", "row1-c2", "row1-c3")); + + RemoteViews views = new RemoteViews(mPackage, R.layout.remote_view_host); + views.removeAllViews(R.id.container); + views.addView(R.id.container, viewstub); + views.addView(R.id.container, createViewChained(5, "row2-c1", "row2-c2")); + + View syncView = views.apply(mContext, mContainer); + + ViewAppliedListener listener = new ViewAppliedListener(); + views.applyAsync(mContext, mContainer, AsyncTask.THREAD_POOL_EXECUTOR, listener); + View asyncView = listener.waitAndGetView(); + + verifyViewTree(syncView, asyncView, "row1-c1", "row1-c2", "row1-c3", "row2-c1", "row2-c2"); + } + + private RemoteViews createViewChained(int depth, String... texts) { + RemoteViews result = new RemoteViews(mPackage, R.layout.remote_view_host); + + // Create depth + RemoteViews parent = result; + while(depth > 0) { + depth--; + RemoteViews child = new RemoteViews(mPackage, R.layout.remote_view_host); + parent.addView(R.id.container, child); + parent = child; + } + + // Add texts + for (String text : texts) { + RemoteViews child = new RemoteViews(mPackage, R.layout.remote_views_text); + child.setTextViewText(R.id.text, text); + parent.addView(R.id.container, child); + } + return result; + } + + private void verifyViewTree(View v1, View v2, String... texts) { + ArrayList<String> expectedTexts = new ArrayList<>(Arrays.asList(texts)); + verifyViewTreeRecur(v1, v2, expectedTexts); + // Verify that all expected texts were found + assertEquals(0, expectedTexts.size()); + } + + private void verifyViewTreeRecur(View v1, View v2, ArrayList<String> expectedTexts) { + assertEquals(v1.getClass(), v2.getClass()); + + if (v1 instanceof TextView) { + String text = ((TextView) v1).getText().toString(); + assertEquals(text, ((TextView) v2).getText().toString()); + // Verify that the text was one of the expected texts and remove it from the list + assertTrue(expectedTexts.remove(text)); + } else if (v1 instanceof ViewGroup) { + ViewGroup vg1 = (ViewGroup) v1; + ViewGroup vg2 = (ViewGroup) v2; + assertEquals(vg1.getChildCount(), vg2.getChildCount()); + for (int i = vg1.getChildCount() - 1; i >= 0; i--) { + verifyViewTreeRecur(vg1.getChildAt(i), vg2.getChildAt(i), expectedTexts); + } + } + } + + private class ViewAppliedListener implements RemoteViews.OnViewAppliedListener { + + private final CountDownLatch mLatch = new CountDownLatch(1); + private View mView; + private Exception mError; + + @Override + public void onViewApplied(View v) { + mView = v; + mLatch.countDown(); + } + + @Override + public void onError(Exception e) { + mError = e; + mLatch.countDown(); + } + + public View waitAndGetView() throws Exception { + mLatch.await(); + + if (mError != null) { + throw new Exception(mError); + } + return mView; + } + } } diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp index ae789d649e72..e0689006d5dd 100644 --- a/libs/androidfw/AssetManager.cpp +++ b/libs/androidfw/AssetManager.cpp @@ -74,6 +74,7 @@ const char* AssetManager::RESOURCES_FILENAME = "resources.arsc"; const char* AssetManager::IDMAP_BIN = "/system/bin/idmap"; const char* AssetManager::OVERLAY_DIR = "/vendor/overlay"; const char* AssetManager::OVERLAY_THEME_DIR_PROPERTY = "ro.boot.vendor.overlay.theme"; +const char* AssetManager::OVERLAY_THEME_DIR_PERSIST_PROPERTY = "persist.vendor.overlay.theme"; const char* AssetManager::TARGET_PACKAGE_NAME = "android"; const char* AssetManager::TARGET_APK_PATH = "/system/framework/framework-res.apk"; const char* AssetManager::IDMAP_DIR = "/data/resource-cache"; diff --git a/libs/androidfw/include/androidfw/AssetManager.h b/libs/androidfw/include/androidfw/AssetManager.h index 0441b9d789e2..becd307d114d 100644 --- a/libs/androidfw/include/androidfw/AssetManager.h +++ b/libs/androidfw/include/androidfw/AssetManager.h @@ -66,6 +66,11 @@ public: * OVERLAY_DIR. */ static const char* OVERLAY_THEME_DIR_PROPERTY; + /** + * If OVERLAY_THEME_DIR_PERSIST_PROPERTY, use it to override + * OVERLAY_THEME_DIR_PROPERTY. + */ + static const char* OVERLAY_THEME_DIR_PERSIST_PROPERTY; static const char* TARGET_PACKAGE_NAME; static const char* TARGET_APK_PATH; static const char* IDMAP_DIR; diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp index 7c97e770b723..5e21dfc6db8a 100644 --- a/libs/hwui/SkiaCanvas.cpp +++ b/libs/hwui/SkiaCanvas.cpp @@ -738,7 +738,7 @@ void SkiaCanvas::drawGlyphs(const uint16_t* text, const float* positions, int co void SkiaCanvas::drawLayoutOnPath(const minikin::Layout& layout, float hOffset, float vOffset, const SkPaint& paint, const SkPath& path, size_t start, size_t end) { const int N = end - start; - SkAutoSMalloc<1024> storage(N * (sizeof(uint16_t) + sizeof(SkRSXform))); + SkAutoSTMalloc<1024, uint8_t> storage(N * (sizeof(uint16_t) + sizeof(SkRSXform))); SkRSXform* xform = (SkRSXform*)storage.get(); uint16_t* glyphs = (uint16_t*)(xform + N); SkPathMeasure meas(path, false); diff --git a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp index a204d5cb8f71..6973209c4626 100644 --- a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp +++ b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp @@ -215,7 +215,7 @@ static void DrawSpotShadowGeneral(SkCanvas* canvas, const Shape& shape, float ca static void DrawRRectShadows(const SkRect& casterRect, SkScalar casterCornerRadius, SkScalar ambientAlpha, SkScalar spotAlpha, SkScalar casterAlpha, SkScalar casterZValue, SkScalar scaleFactor, SkCanvas* canvas) { - SkASSERT(cornerRadius >= 0.0f); + SkASSERT(casterCornerRadius >= 0.0f); // For all of these, we need to ensure we have a rrect with radius >= 0.5f in device space const SkScalar minRadius = 0.5f / scaleFactor; @@ -387,7 +387,7 @@ static void DrawRRectShadows(const SkRect& casterRect, SkScalar casterCornerRadi static void DrawRRectShadowsWithClip(const SkRect& casterRect, SkScalar casterCornerRadius, SkScalar ambientAlpha, SkScalar spotAlpha, SkScalar casterZValue, SkScalar scaleFactor, const SkRRect& clipRR, SkCanvas* canvas) { - SkASSERT(cornerRadius >= 0.0f); + SkASSERT(casterCornerRadius >= 0.0f); const bool isOval = casterCornerRadius >= std::max(SkScalarHalf(casterRect.width()), SkScalarHalf(casterRect.height())); diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp index ca7ee8b7078e..f046e4b93db1 100644 --- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp +++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp @@ -95,6 +95,11 @@ bool SkiaOpenGLPipeline::draw(const Frame& frame, const SkRect& screenDirty, profileCanvas->flush(); } + // Log memory statistics + if (CC_UNLIKELY(Properties::debugLevel != kDebugDisabled)) { + dumpResourceCacheUsage(); + } + return true; } diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp index 69e603b6c927..a6612c96b8f3 100644 --- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp +++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp @@ -266,6 +266,20 @@ void SkiaPipeline::renderFrame(const LayerUpdateQueue& layers, const SkRect& cli canvas->flush(); } +void SkiaPipeline::dumpResourceCacheUsage() const { + int resources, maxResources; + size_t bytes, maxBytes; + mRenderThread.getGrContext()->getResourceCacheUsage(&resources, &bytes); + mRenderThread.getGrContext()->getResourceCacheLimits(&maxResources, &maxBytes); + + SkString log("Resource Cache Usage:\n"); + log.appendf("%8d items out of %d maximum items\n", resources, maxResources); + log.appendf("%8zu bytes (%.2f MB) out of %.2f MB maximum\n", + bytes, bytes * (1.0f / (1024.0f * 1024.0f)), maxBytes * (1.0f / (1024.0f * 1024.0f))); + + ALOGD("%s", log.c_str()); +} + } /* namespace skiapipeline */ } /* namespace uirenderer */ } /* namespace android */ diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.h b/libs/hwui/pipeline/skia/SkiaPipeline.h index 877a3538254c..c1c8cbef4d70 100644 --- a/libs/hwui/pipeline/skia/SkiaPipeline.h +++ b/libs/hwui/pipeline/skia/SkiaPipeline.h @@ -100,7 +100,10 @@ public: mSpotShadowAlpha = lightInfo.spotShadowAlpha; mLightCenter = lightGeometry.center; } + protected: + void dumpResourceCacheUsage() const; + renderthread::RenderThread& mRenderThread; private: diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp index 21f348892ccb..ba13ca586129 100644 --- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp +++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp @@ -81,6 +81,11 @@ bool SkiaVulkanPipeline::draw(const Frame& frame, const SkRect& screenDirty, profileCanvas->flush(); } + // Log memory statistics + if (CC_UNLIKELY(Properties::debugLevel != kDebugDisabled)) { + dumpResourceCacheUsage(); + } + return true; } diff --git a/media/jni/Android.mk b/media/jni/Android.mk index 9b217fbd1d24..8d4271f637a2 100644 --- a/media/jni/Android.mk +++ b/media/jni/Android.mk @@ -31,6 +31,7 @@ LOCAL_SHARED_LIBRARIES := \ libutils \ libbinder \ libmedia \ + libmediadrm \ libskia \ libui \ liblog \ diff --git a/packages/BackupRestoreConfirmation/res/values-bn-rBD/strings.xml b/packages/BackupRestoreConfirmation/res/values-bn-rBD/strings.xml index 440cb647c024..2b69d5bfd540 100644 --- a/packages/BackupRestoreConfirmation/res/values-bn-rBD/strings.xml +++ b/packages/BackupRestoreConfirmation/res/values-bn-rBD/strings.xml @@ -24,13 +24,13 @@ <string name="restore_confirm_text" msgid="7499866728030461776">"একটি সংযুক্ত ডেস্কটপ কম্পিউটার থেকে সমস্ত ডেটার সম্পূর্ণ ব্যাকআপ নেওয়ার অনুরোধ করা হয়েছে৷ আপনি কি এটি করার অনুমতি দিতে চান?\n\nযদি আপনি নিজের থেকে এই ব্যাকআপ নেওয়ার অনুরোধ না করে থাকেন, তবে এই প্রক্রিয়াটিতে অনুমতি প্রদান করবেন না৷ এটি বর্তমানে ডিভাইসটিতে থাকা সমস্ত ডেটাকে প্রতিস্থাপন করবে!"</string> <string name="allow_restore_button_label" msgid="3081286752277127827">"আমার ডেটা পুনরুদ্ধার করুন"</string> <string name="deny_restore_button_label" msgid="1724367334453104378">"পুনরুদ্ধার করবেন না"</string> - <string name="current_password_text" msgid="8268189555578298067">"দয়া করে নীচে আপনার বর্তমান ব্যাকআপের পাসওয়ার্ড দিন:"</string> - <string name="device_encryption_restore_text" msgid="1570864916855208992">"দয়া করে নীচে আপনার ডিভাইসের এনক্রিপশান পাসওয়ার্ড লিখুন৷"</string> - <string name="device_encryption_backup_text" msgid="5866590762672844664">"দয়া করে নীচে আপানার ডিভাইসের এনক্রিপশান পাসওয়ার্ড লিখুন৷ এছাড়াও ব্যাকআপ সংরক্ষণাগার এনক্রিপ্ট করতে এটি ব্যবহার করা হবে৷"</string> + <string name="current_password_text" msgid="8268189555578298067">"দয়া করে নিচে আপনার বর্তমান ব্যাকআপের পাসওয়ার্ড দিন:"</string> + <string name="device_encryption_restore_text" msgid="1570864916855208992">"দয়া করে নিচে আপনার ডিভাইসের এনক্রিপশান পাসওয়ার্ড লিখুন৷"</string> + <string name="device_encryption_backup_text" msgid="5866590762672844664">"দয়া করে নিচে আপানার ডিভাইসের এনক্রিপশান পাসওয়ার্ড লিখুন৷ এছাড়াও ব্যাকআপ সংরক্ষণাগার এনক্রিপ্ট করতে এটি ব্যবহার করা হবে৷"</string> <string name="backup_enc_password_text" msgid="4981585714795233099">"সম্পূর্ণ ব্যাকআপ ডেটা এনক্রিপ্ট করতে দয়া করে একটি পাসওয়ার্ড লিখুন৷ যদি এটি খালি রেখে দেওয়া হয় তবে আপনার বর্তমান ব্যাকআপ পাসওয়ার্ডটি ব্যবহার করা হবে:"</string> - <string name="backup_enc_password_optional" msgid="1350137345907579306">"আপনি যদি সম্পূর্ণ ব্যাকআপ ডেটা এনক্রিপ্ট করতে চান তাহলে নীচে একটি পাসওয়ার্ড লিখুন:"</string> - <string name="backup_enc_password_required" msgid="7889652203371654149">"আপনার ডিভাইস এনক্রিপ্ট হয়ে থাকার কারণে আপনার ব্যাকআপকে এনক্রিপ্ট করতে হবে। দয়া করে নীচে একটি পাসওয়ার্ড দিন:"</string> - <string name="restore_enc_password_text" msgid="6140898525580710823">"যদি পুনরুদ্ধার করা ডেটা এনক্রিপ্ট করা থাকে, তবে দয়া করে নীচে পাসওয়ার্ডটি লিখুন:"</string> + <string name="backup_enc_password_optional" msgid="1350137345907579306">"আপনি যদি সম্পূর্ণ ব্যাকআপ ডেটা এনক্রিপ্ট করতে চান তাহলে নিচে একটি পাসওয়ার্ড লিখুন:"</string> + <string name="backup_enc_password_required" msgid="7889652203371654149">"আপনার ডিভাইস এনক্রিপ্ট হয়ে থাকার কারণে আপনার ব্যাকআপকে এনক্রিপ্ট করতে হবে। দয়া করে নিচে একটি পাসওয়ার্ড দিন:"</string> + <string name="restore_enc_password_text" msgid="6140898525580710823">"যদি পুনরুদ্ধার করা ডেটা এনক্রিপ্ট করা থাকে, তবে দয়া করে নিচে পাসওয়ার্ডটি লিখুন:"</string> <string name="toast_backup_started" msgid="550354281452756121">"ব্যাকআপ নেওয়া শুরু হয়েছে..."</string> <string name="toast_backup_ended" msgid="3818080769548726424">"ব্যাকআপ নেওয়া সম্পূর্ণ হয়েছে"</string> <string name="toast_restore_started" msgid="7881679218971277385">"পুনরুদ্ধার করা শুরু হচ্ছে..."</string> diff --git a/packages/ExtServices/AndroidManifest.xml b/packages/ExtServices/AndroidManifest.xml index c2ca9989689c..f442219a2ffc 100644 --- a/packages/ExtServices/AndroidManifest.xml +++ b/packages/ExtServices/AndroidManifest.xml @@ -26,16 +26,6 @@ android:directBootAware="true"> <library android:name="android.ext.services"/> - - <service android:name=".notification.Ranker" - android:label="@string/notification_ranker" - android:permission="android.permission.BIND_NOTIFICATION_RANKER_SERVICE" - android:exported="true"> - <intent-filter> - <action android:name="android.service.notification.NotificationRankerService" /> - </intent-filter> - </service> - </application> </manifest> diff --git a/packages/ExtServices/res/values/strings.xml b/packages/ExtServices/res/values/strings.xml index b77ff1055cb1..531e5171dec8 100644 --- a/packages/ExtServices/res/values/strings.xml +++ b/packages/ExtServices/res/values/strings.xml @@ -16,6 +16,4 @@ <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_name">Android Services Library</string> - <string name="notification_ranker">Android Notification Ranking Service</string> - <string name="notification_ranker_autobundle_explanation">Auto-grouping updated by Ranking Service</string> </resources> diff --git a/packages/ExtServices/src/android/ext/services/notification/Ranker.java b/packages/ExtServices/src/android/ext/services/notification/Ranker.java deleted file mode 100644 index 2feb51f7a710..000000000000 --- a/packages/ExtServices/src/android/ext/services/notification/Ranker.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.ext.services.notification; - -import android.os.Bundle; -import android.os.UserHandle; -import android.service.notification.Adjustment; -import android.service.notification.NotificationRankerService; -import android.service.notification.StatusBarNotification; -import android.util.Log; -import android.util.Slog; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; - -import android.ext.services.R; - -/** - * Class that provides an updatable ranker module for the notification manager. - * TODO: delete - */ -public final class Ranker extends NotificationRankerService { - private static final String TAG = "RocketRanker"; - private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); - - @Override - public Adjustment onNotificationEnqueued(StatusBarNotification sbn, int importance, - boolean user) { - return null; - } -}
\ No newline at end of file diff --git a/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java b/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java index 0474df7bd89c..d12417b47fec 100644 --- a/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java +++ b/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java @@ -34,7 +34,7 @@ import android.view.ViewConfiguration; import android.widget.Button; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.telephony.IccCardConstants.State; import com.android.internal.widget.LockPatternUtils; import com.android.internal.policy.EmergencyAffordanceManager; diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java index 3fcc600e67f0..6b2c1eeef694 100644 --- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java +++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java @@ -485,6 +485,24 @@ public class MtpDocumentsProvider extends DocumentsProvider { } } + @Override + public boolean isChildDocument(String parentDocumentId, String documentId) { + try { + Identifier identifier = mDatabase.createIdentifier(documentId); + while (true) { + if (parentDocumentId.equals(identifier.mDocumentId)) { + return true; + } + if (identifier.mDocumentType == MtpDatabaseConstants.DOCUMENT_TYPE_DEVICE) { + return false; + } + identifier = mDatabase.getParentIdentifier(identifier.mDocumentId); + } + } catch (FileNotFoundException error) { + return false; + } + } + void openDevice(int deviceId) throws IOException { synchronized (mDeviceListLock) { if (mDeviceToolkits.containsKey(deviceId)) { diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java index 194e8c727c7a..ef2e0a58903c 100644 --- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java +++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java @@ -854,6 +854,18 @@ public class MtpDocumentsProviderTest extends AndroidTestCase { assertEquals("19", path.getPath().get(2)); } + public void testIsChildDocument() throws Exception { + setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY); + setupRoots(0, new MtpRoot[] { new MtpRoot(0, 0, "Storage", 1000, 1000, "") }); + setupHierarchyDocuments("1"); + assertTrue(mProvider.isChildDocument("1", "1")); + assertTrue(mProvider.isChildDocument("1", "14")); + assertTrue(mProvider.isChildDocument("2", "14")); + assertTrue(mProvider.isChildDocument("5", "14")); + assertFalse(mProvider.isChildDocument("3", "14")); + assertFalse(mProvider.isChildDocument("6", "14")); + } + private void setupProvider(int flag) { mDatabase = new MtpDatabase(getContext(), flag); mProvider = new MtpDocumentsProvider(); diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/AddPrinterActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/AddPrinterActivity.java index 1bebebc6fda0..7b0a291e2259 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/ui/AddPrinterActivity.java +++ b/packages/PrintSpooler/src/com/android/printspooler/ui/AddPrinterActivity.java @@ -48,7 +48,7 @@ import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.printspooler.R; import java.text.Collator; diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java index 23c6615e4715..4b519171b3eb 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java +++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java @@ -88,7 +88,7 @@ import android.widget.TextView; import android.widget.Toast; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.printspooler.R; import com.android.printspooler.model.MutexFileProvider; import com.android.printspooler.model.PrintSpoolerProvider; diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java index 74582f3da203..6f0caa244281 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java +++ b/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java @@ -63,7 +63,7 @@ import android.widget.TextView; import android.widget.Toast; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.printspooler.R; import java.util.ArrayList; diff --git a/packages/SettingsLib/src/com/android/settingslib/HelpUtils.java b/packages/SettingsLib/src/com/android/settingslib/HelpUtils.java index 381f903a9701..c3acf0b03ab5 100644 --- a/packages/SettingsLib/src/com/android/settingslib/HelpUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/HelpUtils.java @@ -35,7 +35,7 @@ import android.view.Menu; import android.view.MenuItem; import android.view.MenuItem.OnMenuItemClickListener; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import java.net.URISyntaxException; import java.util.Locale; diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java index b27aad94b0c1..e07856e46779 100644 --- a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java +++ b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java @@ -36,6 +36,9 @@ public final class CategoryKey { public static final String CATEGORY_SECURITY = "com.android.settings.category.ia.security"; public static final String CATEGORY_ACCOUNT = "com.android.settings.category.ia.accounts"; public static final String CATEGORY_SYSTEM = "com.android.settings.category.ia.system"; + public static final String CATEGORY_SYSTEM_INPUT = "com.android.settings.category.ia.input"; + public static final String CATEGORY_SYSTEM_LANGUAGE = + "com.android.settings.category.ia.language"; public static final Map<String, String> KEY_COMPAT_MAP; diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java index f93c56607ced..a0254cd94923 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java @@ -56,9 +56,11 @@ public class CategoryKeyTest { allKeys.add(CategoryKey.CATEGORY_SECURITY); allKeys.add(CategoryKey.CATEGORY_ACCOUNT); allKeys.add(CategoryKey.CATEGORY_SYSTEM); + allKeys.add(CategoryKey.CATEGORY_SYSTEM_INPUT); + allKeys.add(CategoryKey.CATEGORY_SYSTEM_LANGUAGE); // DO NOT REMOVE ANYTHING ABOVE - assertThat(allKeys.size()).isEqualTo(11); + assertThat(allKeys.size()).isEqualTo(13); } } diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index 227d0e944e6e..d4c7c7ad8cb1 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -112,6 +112,7 @@ <uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" /> <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" /> <uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" /> + <uses-permission android:name="android.permission.MANAGE_AUTO_FILL" /> <!-- Permission needed to rename bugreport notifications (so they're not shown as Shell) --> <uses-permission android:name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME" /> <!-- Permission needed to hold a wakelock in dumpstate.cpp (drop_root_user()) --> diff --git a/packages/Shell/res/values-tr/strings.xml b/packages/Shell/res/values-tr/strings.xml index b33da1993cee..9bef2db637d8 100644 --- a/packages/Shell/res/values-tr/strings.xml +++ b/packages/Shell/res/values-tr/strings.xml @@ -22,7 +22,7 @@ <string name="bugreport_updating_title" msgid="4423539949559634214">"Hata raporuna ayrıntılar ekleniyor"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Lütfen bekleyin…"</string> <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"Hata raporu kısa süre içinde telefonda görüntülenecektir"</string> - <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Hata raporunuzu paylaşmak için hafifçe dokunun"</string> + <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Hata raporunuzu paylaşmak için dokunun"</string> <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Hata raporunu ekran görüntüsüz paylaşmak için dokunun veya bitirmek için ekran görüntüsünü bekleyin"</string> <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Hata raporunu ekran görüntüsüz paylaşmak için dokunun veya bitirmek için ekran görüntüsünü bekleyin"</string> <string name="bugreport_confirm" msgid="5917407234515812495">"Hata raporları, sistemin çeşitli günlük dosyalarından veriler içerir. Bu günlükler, hassas olarak kabul ettiğiniz verileri (uygulama kullanımı ve konum verileri gibi) içerebilir. Hata raporlarını yalnızca güvendiğiniz kişiler ve uygulamalarla paylaşın."</string> diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java index 772c344fbfdb..dedb9ac8c51d 100644 --- a/packages/Shell/src/com/android/shell/BugreportProgressService.java +++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java @@ -44,7 +44,7 @@ import libcore.io.Streams; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.google.android.collect.Lists; diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 2adb26159622..e07d8650591a 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -285,6 +285,22 @@ </intent-filter> </activity> + <activity android:name=".recents.grid.RecentsGridActivity" + android:label="@string/accessibility_desc_recent_apps" + android:exported="false" + android:launchMode="singleInstance" + android:excludeFromRecents="true" + android:stateNotNeeded="true" + android:resumeWhilePausing="true" + android:screenOrientation="behind" + android:resizeableActivity="true" + android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout" + android:theme="@style/RecentsTheme.Wallpaper"> + <intent-filter> + <action android:name="com.android.systemui.recents.TOGGLE_RECENTS" /> + </intent-filter> + </activity> + <activity android:name=".recents.tv.RecentsTvActivity" android:label="@string/accessibility_desc_recent_apps" android:exported="false" diff --git a/packages/SystemUI/res/layout-sw600dp/recents_grid.xml b/packages/SystemUI/res/layout-sw600dp/recents_grid.xml new file mode 100644 index 000000000000..c8b4fd0b70a5 --- /dev/null +++ b/packages/SystemUI/res/layout-sw600dp/recents_grid.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2016 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + android:id="@+id/recents_container"> + <include layout="@layout/recents_stack_action_button" /> + <FrameLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:id="@+id/recents_view" + android:layout_marginLeft="12dp" + android:layout_marginTop="10dp" + android:layout_marginRight="12dp" + android:layout_marginBottom="5dp" + android:gravity="center"> + </FrameLayout> +</LinearLayout>
\ No newline at end of file diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index 1131b2aeec06..ea070b3e811b 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Maak <xliff:g id="ID_1">%s</xliff:g>-instellings oop."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Wysig volgorde van instellings."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Bladsy <xliff:g id="ID_1">%1$d</xliff:g> van <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index 0dc05e619190..837d67794729 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"የ<xliff:g id="ID_1">%s</xliff:g> ቅንብሮችን ክፈት።"</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"የቅንብሮድ ቅደም-ተከተል አርትዕ።"</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"ገጽ <xliff:g id="ID_1">%1$d</xliff:g> ከ <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index 755438edf0fd..f207dbc124a7 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -656,4 +656,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"فتح إعدادات <xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"تعديل ترتيب الإعدادات."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"الصفحة <xliff:g id="ID_1">%1$d</xliff:g> من <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-az-rAZ/strings.xml b/packages/SystemUI/res/values-az-rAZ/strings.xml index 87b4433d9761..c4b0f73eefe9 100644 --- a/packages/SystemUI/res/values-az-rAZ/strings.xml +++ b/packages/SystemUI/res/values-az-rAZ/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> ayarlarını açın."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Ayarların sıralanmasını redaktə edin."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_2">%2$d</xliff:g> səhifədən <xliff:g id="ID_1">%1$d</xliff:g> səhifə"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index e1738900354f..e70e4855a805 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -650,4 +650,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Otvori podešavanja za <xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Izmeni redosled podešavanja."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_1">%1$d</xliff:g>. strana od <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-be-rBY/strings.xml b/packages/SystemUI/res/values-be-rBY/strings.xml index 207e223e8766..7f7a67ff789f 100644 --- a/packages/SystemUI/res/values-be-rBY/strings.xml +++ b/packages/SystemUI/res/values-be-rBY/strings.xml @@ -654,4 +654,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Адкрыць налады <xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Змяніць парадак налад."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Старонка <xliff:g id="ID_1">%1$d</xliff:g> з <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index 16c94d7e962a..16dfeebbf9fc 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Отваряне на настройките за <xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Редактиране на подредбата на настройките."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Страница <xliff:g id="ID_1">%1$d</xliff:g> от <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-bn-rBD/strings.xml b/packages/SystemUI/res/values-bn-rBD/strings.xml index feaa453ff6a6..f8ee362540be 100644 --- a/packages/SystemUI/res/values-bn-rBD/strings.xml +++ b/packages/SystemUI/res/values-bn-rBD/strings.xml @@ -528,7 +528,7 @@ <string name="keyboard_key_home" msgid="2243500072071305073">"হোম"</string> <string name="keyboard_key_back" msgid="2337450286042721351">"ফিরুন"</string> <string name="keyboard_key_dpad_up" msgid="5584144111755734686">"উপরে"</string> - <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"নীচে"</string> + <string name="keyboard_key_dpad_down" msgid="7331518671788337815">"নিচে"</string> <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"বাম"</string> <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"ডান"</string> <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"কেন্দ্র"</string> @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> সেটিংস খুলুন৷"</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"ক্রম বা সেটিংস সম্পাদনা করুন৷"</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_2">%2$d</xliff:g>টির মধ্যে <xliff:g id="ID_1">%1$d</xliff:g> নং পৃষ্ঠা"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-bs-rBA/strings.xml b/packages/SystemUI/res/values-bs-rBA/strings.xml index f361b936981b..0e91713f2571 100644 --- a/packages/SystemUI/res/values-bs-rBA/strings.xml +++ b/packages/SystemUI/res/values-bs-rBA/strings.xml @@ -652,4 +652,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Otvori postavke za: <xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Urediti raspored postavki."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Stranica <xliff:g id="ID_1">%1$d</xliff:g> od <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 8bedecd6226d..d258943d46e9 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Obre la configuració per a <xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Edita l\'ordre de la configuració."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Pàgina <xliff:g id="ID_1">%1$d</xliff:g> (<xliff:g id="ID_2">%2$d</xliff:g> en total)"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index 0ff0f936e192..845c8b527ecf 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -654,4 +654,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Otevřít nastavení aplikace <xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Upravit pořadí nastavení."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Stránka <xliff:g id="ID_1">%1$d</xliff:g> z <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index b1124056c6f9..bb340a678b17 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Åbn <xliff:g id="ID_1">%s</xliff:g>-indstillinger."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Rediger rækkefølgen af indstillinger."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Side <xliff:g id="ID_1">%1$d</xliff:g> af <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index 9721362526f9..faabbfa60ac0 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -650,4 +650,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Einstellungen für <xliff:g id="ID_1">%s</xliff:g> öffnen."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Reihenfolge der Einstellungen bearbeiten."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Seite <xliff:g id="ID_1">%1$d</xliff:g> von <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index 276b856b1707..0f5f44711581 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Άνοιγμα ρυθμίσεων <xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Επεξεργασία σειράς ρυθμίσεων."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Σελίδα <xliff:g id="ID_1">%1$d</xliff:g> από <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index ca2e5b33d523..14d2a19ceae2 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Open <xliff:g id="ID_1">%s</xliff:g> settings."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Edit order of settings."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Page <xliff:g id="ID_1">%1$d</xliff:g> of <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index ca2e5b33d523..14d2a19ceae2 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Open <xliff:g id="ID_1">%s</xliff:g> settings."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Edit order of settings."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Page <xliff:g id="ID_1">%1$d</xliff:g> of <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index ca2e5b33d523..14d2a19ceae2 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Open <xliff:g id="ID_1">%s</xliff:g> settings."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Edit order of settings."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Page <xliff:g id="ID_1">%1$d</xliff:g> of <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index 81696f69771e..3b92a3acf05a 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -650,4 +650,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Abrir configuración de <xliff:g id="ID_1">%s</xliff:g>"</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Editar orden de configuración"</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Página <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index aa9578aa1978..600d7d504dbf 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -650,4 +650,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Abrir ajustes de <xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Cambiar el orden de los ajustes."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Página <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml index ab81af59c821..884eac5ddb3b 100644 --- a/packages/SystemUI/res/values-et-rEE/strings.xml +++ b/packages/SystemUI/res/values-et-rEE/strings.xml @@ -650,4 +650,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Ava teenuse <xliff:g id="ID_1">%s</xliff:g> seaded."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Muuda seadete järjestust."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Leht <xliff:g id="ID_1">%1$d</xliff:g>/<xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-eu-rES/strings.xml b/packages/SystemUI/res/values-eu-rES/strings.xml index 36170744b416..b5e6696bef58 100644 --- a/packages/SystemUI/res/values-eu-rES/strings.xml +++ b/packages/SystemUI/res/values-eu-rES/strings.xml @@ -650,4 +650,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Ireki <xliff:g id="ID_1">%s</xliff:g> ezarpenak."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Editatu ezarpenen ordena."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_1">%1$d</xliff:g>/<xliff:g id="ID_2">%2$d</xliff:g> orria"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index 48f0b954d4fc..866904cf9a51 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"باز کردن تنظیمات <xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"ویرایش ترتیب تنظیمات."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"صفحه <xliff:g id="ID_1">%1$d</xliff:g> از <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index 5e1ca4bc7d88..144704dce8b5 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Avaa kohteen <xliff:g id="ID_1">%s</xliff:g> asetukset."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Muokkaa asetusten järjestystä."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Sivu <xliff:g id="ID_1">%1$d</xliff:g>/<xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index 765e0aa92714..b5c227ebf01f 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -650,4 +650,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Ouvrir les paramètres <xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Modifier l\'ordre des paramètres."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Page <xliff:g id="ID_1">%1$d</xliff:g> sur <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index e66d342bd63e..008d06180e98 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -650,4 +650,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Ouvrir les paramètres <xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Modifier l\'ordre des paramètres."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Page <xliff:g id="ID_1">%1$d</xliff:g> sur <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-gl-rES/strings.xml b/packages/SystemUI/res/values-gl-rES/strings.xml index 5ccf4a0bbab3..cca60a86b3a9 100644 --- a/packages/SystemUI/res/values-gl-rES/strings.xml +++ b/packages/SystemUI/res/values-gl-rES/strings.xml @@ -650,4 +650,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Abrir a configuración de <xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Editar a orde das opcións de configuración."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Páxina <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-gu-rIN/strings.xml b/packages/SystemUI/res/values-gu-rIN/strings.xml index 84f9105d2917..558a90a884bd 100644 --- a/packages/SystemUI/res/values-gu-rIN/strings.xml +++ b/packages/SystemUI/res/values-gu-rIN/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> સેટિંગ્સ ખોલો."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"સેટિંગ્સનો ક્રમ સંપાદિત કરો."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_2">%2$d</xliff:g> માંથી <xliff:g id="ID_1">%1$d</xliff:g> પૃષ્ઠ"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index 89b5a6f3bde2..1fff05172bcb 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> सेटिंग खोलें."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"सेटिंग का क्रम संपादित करें."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"पृष्ठ <xliff:g id="ID_2">%2$d</xliff:g> में से <xliff:g id="ID_1">%1$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index 3c5812f89d1f..ae7e0c4360e3 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -650,4 +650,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Otvaranje postavki za <xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Uređivanje redoslijeda postavki."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Stranica <xliff:g id="ID_1">%1$d</xliff:g> od <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index f83ba28f9970..ec62e1c44b40 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"A(z) <xliff:g id="ID_1">%s</xliff:g> beállításainak megnyitása."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Beállítások sorrendjének szerkesztése."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_1">%1$d</xliff:g>. oldal, összesen: <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml index 4ce22e435b15..80cb9770b217 100644 --- a/packages/SystemUI/res/values-hy-rAM/strings.xml +++ b/packages/SystemUI/res/values-hy-rAM/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Բացել <xliff:g id="ID_1">%s</xliff:g> կարգավորումները:"</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Խմբագրել կարգավորումների հերթականությունը:"</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Էջ <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index 4efffc565f73..93960e81b3c9 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Buka setelan <xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Edit urutan setelan."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Halaman <xliff:g id="ID_1">%1$d</xliff:g> dari <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-is-rIS/strings.xml b/packages/SystemUI/res/values-is-rIS/strings.xml index 4875888ae0c9..71ef4bbf8fff 100644 --- a/packages/SystemUI/res/values-is-rIS/strings.xml +++ b/packages/SystemUI/res/values-is-rIS/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Opna <xliff:g id="ID_1">%s</xliff:g> stillingar."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Breyta röð stillinga."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Blaðsíða <xliff:g id="ID_1">%1$d</xliff:g> af <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index 98a24248a9ed..12d0ed6069ea 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -650,4 +650,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Apri le impostazioni <xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Modifica l\'ordine delle impostazioni."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Pagina <xliff:g id="ID_1">%1$d</xliff:g> di <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index ce73705cdb63..f5656030e13c 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -652,4 +652,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"פתיחת הגדרות של <xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"עריכת סדר ההגדרות."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"דף <xliff:g id="ID_1">%1$d</xliff:g> מתוך <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index c45fa4f958d8..37bea17f79b9 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -650,4 +650,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> の設定を開きます。"</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"設定の順序を編集します。"</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"ページ <xliff:g id="ID_1">%1$d</xliff:g>/<xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml index a151b8f292e4..15f5d638b5e0 100644 --- a/packages/SystemUI/res/values-ka-rGE/strings.xml +++ b/packages/SystemUI/res/values-ka-rGE/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> პარამეტრების გახსნა."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"პარამეტრების მიმდევრობის რედაქტირება."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"გვერდი <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>-დან"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-kk-rKZ/strings.xml b/packages/SystemUI/res/values-kk-rKZ/strings.xml index 6c0c967b4ad6..477ab821767c 100644 --- a/packages/SystemUI/res/values-kk-rKZ/strings.xml +++ b/packages/SystemUI/res/values-kk-rKZ/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> параметрлерін ашу."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Параметрлер тәртібін өзгерту."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_2">%2$d</xliff:g> ішінен <xliff:g id="ID_1">%1$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml index d3e97ccba0a6..45771d9ec5fa 100644 --- a/packages/SystemUI/res/values-km-rKH/strings.xml +++ b/packages/SystemUI/res/values-km-rKH/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"បើការកំណត់ <xliff:g id="ID_1">%s</xliff:g>"</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"កែលំដាប់ការកំណត់"</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"ទំព័រ <xliff:g id="ID_1">%1$d</xliff:g> នៃ <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-kn-rIN/strings.xml b/packages/SystemUI/res/values-kn-rIN/strings.xml index cbd71f9cc2fc..87c48dd185db 100644 --- a/packages/SystemUI/res/values-kn-rIN/strings.xml +++ b/packages/SystemUI/res/values-kn-rIN/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ತೆರೆಯಿರಿ."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"ಸೆಟ್ಟಿಂಗ್ಗಳ ಕ್ರಮವನ್ನು ಎಡಿಟ್ ಮಾಡಿ."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_2">%2$d</xliff:g> ರಲ್ಲಿ <xliff:g id="ID_1">%1$d</xliff:g> ಪುಟ"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index 3827dba5d8be..3e0cdfef4ff6 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -650,4 +650,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> 설정 열기"</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"설정 순서 수정"</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_2">%2$d</xliff:g>페이지 중 <xliff:g id="ID_1">%1$d</xliff:g>페이지"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ky-rKG/strings.xml b/packages/SystemUI/res/values-ky-rKG/strings.xml index 56c836003017..2d8be38513e5 100644 --- a/packages/SystemUI/res/values-ky-rKG/strings.xml +++ b/packages/SystemUI/res/values-ky-rKG/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> жөндөөлөрүн ачуу."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Жөндөөлөрдүн иретин өзгөртүү."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_2">%2$d</xliff:g> ичинен <xliff:g id="ID_1">%1$d</xliff:g>-бет"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml index 47a49da4db60..93098ade4fce 100644 --- a/packages/SystemUI/res/values-lo-rLA/strings.xml +++ b/packages/SystemUI/res/values-lo-rLA/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"ເປີດການຕັ້ງຄ່າ <xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"ແກ້ໄຂລຳດັບການຕັ້ງຄ່າ."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_1">%1$d</xliff:g> ຈາກທັງໝົດ <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index c4676fa5c631..02e614c06b12 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -652,4 +652,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Atidaryti „<xliff:g id="ID_1">%s</xliff:g>“ nustatymus."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Redaguoti nustatymų tvarką."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_1">%1$d</xliff:g> psl. iš <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index a8266dddb5b4..82f5f22e8270 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -650,4 +650,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Atvērt <xliff:g id="ID_1">%s</xliff:g> iestatījumus."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Rediģēt iestatījumu secību."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_1">%1$d</xliff:g>. lpp. no <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-mk-rMK/strings.xml b/packages/SystemUI/res/values-mk-rMK/strings.xml index c5e2500e9504..fcaa26f39cb8 100644 --- a/packages/SystemUI/res/values-mk-rMK/strings.xml +++ b/packages/SystemUI/res/values-mk-rMK/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Отворете ги поставките на <xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Уредете го редоследот на поставките."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Страница <xliff:g id="ID_1">%1$d</xliff:g> од <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ml-rIN/strings.xml b/packages/SystemUI/res/values-ml-rIN/strings.xml index a1a3b31f105b..44d76d5d4c8c 100644 --- a/packages/SystemUI/res/values-ml-rIN/strings.xml +++ b/packages/SystemUI/res/values-ml-rIN/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> ക്രമീകരണം തുറക്കുക."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"ക്രമീകരണ ക്രമം എഡിറ്റുചെയ്യുക."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"പേജ് <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml index 9b830589dedd..1c7bc381cb47 100644 --- a/packages/SystemUI/res/values-mn-rMN/strings.xml +++ b/packages/SystemUI/res/values-mn-rMN/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> тохиргоог нээнэ үү."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Тохиргооны дарааллыг өөрчилнө үү."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_2">%2$d</xliff:g>-н <xliff:g id="ID_1">%1$d</xliff:g>-р хуудас"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-mr-rIN/strings.xml b/packages/SystemUI/res/values-mr-rIN/strings.xml index 800389080a2a..71d6677dc817 100644 --- a/packages/SystemUI/res/values-mr-rIN/strings.xml +++ b/packages/SystemUI/res/values-mr-rIN/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> सेटिंग्ज उघडा."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"सेटिंग्जचा क्रम संपादित करा."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"पृष्ठ <xliff:g id="ID_2">%2$d</xliff:g> पैकी <xliff:g id="ID_1">%1$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml index 1a1696767973..bc9d79fe61a8 100644 --- a/packages/SystemUI/res/values-ms-rMY/strings.xml +++ b/packages/SystemUI/res/values-ms-rMY/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Buka tetapan <xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Edit susunan tetapan."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Halaman <xliff:g id="ID_1">%1$d</xliff:g> daripada <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-my-rMM/strings.xml b/packages/SystemUI/res/values-my-rMM/strings.xml index 17b68029c737..37c002ca7d18 100644 --- a/packages/SystemUI/res/values-my-rMM/strings.xml +++ b/packages/SystemUI/res/values-my-rMM/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> ဆက်တင်များကို ဖွင့်ပါ။"</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"ဆက်တင်များ၏ အစီအစဉ်ကို တည်းဖြတ်ပါ။"</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"စာမျက်နှာ <xliff:g id="ID_2">%2$d</xliff:g> အနက်မှ စာမျက်နှာ <xliff:g id="ID_1">%1$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index cb691c511fe7..025c270dc33c 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Åpne <xliff:g id="ID_1">%s</xliff:g>-innstillingene."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Endre rekkefølgen på innstillingene."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Side <xliff:g id="ID_1">%1$d</xliff:g> av <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml index 97f5f5e849e6..3ed57827e512 100644 --- a/packages/SystemUI/res/values-ne-rNP/strings.xml +++ b/packages/SystemUI/res/values-ne-rNP/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> सम्बन्धी सेटिङहरूलाई खोल्नुहोस्।"</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"सेटिङहरूको क्रमलाई सम्पादन गर्नुहोस्।"</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_2">%2$d</xliff:g> मध्ये पृष्ठ <xliff:g id="ID_1">%1$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index 43c577dcf597..13ef0f61e80f 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g>-instellingen openen."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Volgorde van instellingen bewerken."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Pagina <xliff:g id="ID_1">%1$d</xliff:g> van <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-pa-rIN/strings.xml b/packages/SystemUI/res/values-pa-rIN/strings.xml index 6ef867434ff5..553b6048c7a8 100644 --- a/packages/SystemUI/res/values-pa-rIN/strings.xml +++ b/packages/SystemUI/res/values-pa-rIN/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹੋ।"</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"ਸੈਟਿੰਗਾਂ ਦੇ ਕ੍ਰਮ ਦਾ ਸੰਪਾਦਨ ਕਰੋ।"</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_2">%2$d</xliff:g> ਦਾ <xliff:g id="ID_1">%1$d</xliff:g> ਪੰਨਾ"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index 03e599c9f545..cc5b693643c6 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -652,4 +652,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Otwórz ustawienia: <xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Edytuj kolejność ustawień."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Strona <xliff:g id="ID_1">%1$d</xliff:g> z <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index 0ae421d1ca5b..ef07edc5b8e8 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -650,4 +650,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Abrir configurações de <xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Editar ordem das configurações."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Página <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index 6ad19f9f37cc..5c7ea4fd25c5 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Abrir as definições de <xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Editar a ordem das definições."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Página <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index 0ae421d1ca5b..ef07edc5b8e8 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -650,4 +650,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Abrir configurações de <xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Editar ordem das configurações."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Página <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index 70ef6ea72291..0d42645df5c8 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -652,4 +652,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Deschideți setările <xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Editați ordinea setărilor."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Pagina <xliff:g id="ID_1">%1$d</xliff:g> din <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index 41ec36777e5f..9adc9fe8abca 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -654,4 +654,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Открыть настройки <xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Изменить порядок быстрых настроек."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Страница <xliff:g id="ID_1">%1$d</xliff:g> из <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-si-rLK/strings.xml b/packages/SystemUI/res/values-si-rLK/strings.xml index 8f6553192f2b..6739ea110d77 100644 --- a/packages/SystemUI/res/values-si-rLK/strings.xml +++ b/packages/SystemUI/res/values-si-rLK/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> සැකසීම් විවෘත කරන්න."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"සැකසීම්වල අනුපිළිවෙළ සංංස්කරණය කරන්න."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_2">%2$d</xliff:g> න් <xliff:g id="ID_1">%1$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index 276c266d2f39..44881bd0eef0 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -654,4 +654,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Otvoriť nastavenia <xliff:g id="ID_1">%s</xliff:g>"</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Upraviť poradie nastavení"</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Strana <xliff:g id="ID_1">%1$d</xliff:g> z <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index cda2ac91a892..cc11704358bc 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -654,4 +654,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Odpri nastavitve za <xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Uredi vrstni red nastavitev."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_1">%1$d</xliff:g>. stran od <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-sq-rAL/strings.xml b/packages/SystemUI/res/values-sq-rAL/strings.xml index 33b2d5b81c14..55598bd91cc6 100644 --- a/packages/SystemUI/res/values-sq-rAL/strings.xml +++ b/packages/SystemUI/res/values-sq-rAL/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Hap cilësimet e <xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Modifiko rendin e cilësimeve."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Faqja <xliff:g id="ID_1">%1$d</xliff:g> nga <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index 11d05b748e71..22bd8530e73e 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -650,4 +650,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Отвори подешавања за <xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Измени редослед подешавања."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_1">%1$d</xliff:g>. страна од <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index 46e3f054bd05..87acdb3a33b9 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Öppna <xliff:g id="ID_1">%s</xliff:g>-inställningarna."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Ändra ordning på inställningarna."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Sida <xliff:g id="ID_1">%1$d</xliff:g> av <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 43aa36d2b3dd..cc4391cee9cd 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Fungua mipangilio ya <xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Badilisha orodha ya mipangilio."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Ukurasa wa <xliff:g id="ID_1">%1$d</xliff:g> kati ya <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ta-rIN/strings.xml b/packages/SystemUI/res/values-ta-rIN/strings.xml index 364173e8e84a..2d3c27f81bb7 100644 --- a/packages/SystemUI/res/values-ta-rIN/strings.xml +++ b/packages/SystemUI/res/values-ta-rIN/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> அமைப்புகளைத் திற."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"அமைப்புகளின் வரிசை முறையைத் திருத்து."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"பக்கம் <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-te-rIN/strings.xml b/packages/SystemUI/res/values-te-rIN/strings.xml index c1e55c8f5172..9fa3f8635089 100644 --- a/packages/SystemUI/res/values-te-rIN/strings.xml +++ b/packages/SystemUI/res/values-te-rIN/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> సెట్టింగ్లను తెరవండి."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"సెట్టింగ్ల క్రమాన్ని సవరించండి."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_2">%2$d</xliff:g>లో <xliff:g id="ID_1">%1$d</xliff:g>వ పేజీ"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index f2b1772c19fd..f59e69bdce58 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"เปิดการตั้งค่า <xliff:g id="ID_1">%s</xliff:g>"</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"แก้ไขลำดับการตั้งค่า"</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"หน้า <xliff:g id="ID_1">%1$d</xliff:g> จาก <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index f58ed174ff5a..2d978c463df3 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Buksan ang mga setting ng <xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"I-edit ang pagkakasunud-sunod ng mga setting."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Page <xliff:g id="ID_1">%1$d</xliff:g> ng <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index e7b1abb751fb..e3827f7f43e0 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> ayarlarını aç."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Ayarların sırasını düzenle."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Sayfa <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index 886a138717fe..fd627cc3f60a 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -654,4 +654,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Відкрити налаштування <xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Змінити порядок налаштувань."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Сторінка <xliff:g id="ID_1">%1$d</xliff:g> з <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-ur-rPK/strings.xml b/packages/SystemUI/res/values-ur-rPK/strings.xml index 31d90e2551e3..415c5b613b9c 100644 --- a/packages/SystemUI/res/values-ur-rPK/strings.xml +++ b/packages/SystemUI/res/values-ur-rPK/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> ترتیبات کھولیں۔"</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"ترتیبات کی ترتیب میں ترمیم کریں۔"</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"صفحہ <xliff:g id="ID_1">%1$d</xliff:g> از <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-uz-rUZ/strings.xml b/packages/SystemUI/res/values-uz-rUZ/strings.xml index 78ad14837904..aaea5e533b22 100644 --- a/packages/SystemUI/res/values-uz-rUZ/strings.xml +++ b/packages/SystemUI/res/values-uz-rUZ/strings.xml @@ -650,4 +650,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> sozlamalarini ochish."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Sozlamalar tartibini o‘zgartirish."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_1">%1$d</xliff:g>-sahifa, jami: <xliff:g id="ID_2">%2$d</xliff:g> ta sahifa"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index ba490552dcbd..4ae3370aabdd 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -650,4 +650,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Mở cài đặt <xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Chỉnh sửa thứ tự cài đặt."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Trang <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index 7a7991f7c45a..7c7bc4a9aec3 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"打开<xliff:g id="ID_1">%s</xliff:g>设置。"</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"修改设置顺序。"</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"第 <xliff:g id="ID_1">%1$d</xliff:g> 页,共 <xliff:g id="ID_2">%2$d</xliff:g> 页"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index 4f7ffe53479d..e41a24b7064a 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -650,4 +650,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"開啟<xliff:g id="ID_1">%s</xliff:g>設定頁面。"</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"編輯設定次序。"</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"第 <xliff:g id="ID_1">%1$d</xliff:g> 頁 (共 <xliff:g id="ID_2">%2$d</xliff:g> 頁)"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index 2de07e3e68bc..51e27a396c40 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"開啟「<xliff:g id="ID_1">%s</xliff:g>」設定。"</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"編輯設定順序。"</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"第 <xliff:g id="ID_1">%1$d</xliff:g> 頁,共 <xliff:g id="ID_2">%2$d</xliff:g> 頁"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index 6be736ad84bc..887da2e2f15d 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -648,4 +648,6 @@ <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Vula izilungiselelo ze-<xliff:g id="ID_1">%s</xliff:g>."</string> <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Hlela uhlelo lwezilungiselelo."</string> <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Ikhasi <xliff:g id="ID_1">%1$d</xliff:g> kwangu-<xliff:g id="ID_2">%2$d</xliff:g>"</string> + <!-- no translation found for pip_phone_expand (5889780005575693909) --> + <skip /> </resources> diff --git a/packages/SystemUI/src/com/android/systemui/analytics/DataCollector.java b/packages/SystemUI/src/com/android/systemui/analytics/DataCollector.java index b1f454e5e3d0..965ded5beaff 100644 --- a/packages/SystemUI/src/com/android/systemui/analytics/DataCollector.java +++ b/packages/SystemUI/src/com/android/systemui/analytics/DataCollector.java @@ -35,8 +35,8 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; -import static com.android.systemui.statusbar.phone.TouchAnalyticsProto.Session; -import static com.android.systemui.statusbar.phone.TouchAnalyticsProto.Session.PhoneEvent; +import static com.android.systemui.statusbar.phone.nano.TouchAnalyticsProto.Session; +import static com.android.systemui.statusbar.phone.nano.TouchAnalyticsProto.Session.PhoneEvent; /** * Tracks touch, sensor and phone events when the lockscreen is on. If the phone is unlocked diff --git a/packages/SystemUI/src/com/android/systemui/analytics/SensorLoggerSession.java b/packages/SystemUI/src/com/android/systemui/analytics/SensorLoggerSession.java index b39803a01783..f8b73a172516 100644 --- a/packages/SystemUI/src/com/android/systemui/analytics/SensorLoggerSession.java +++ b/packages/SystemUI/src/com/android/systemui/analytics/SensorLoggerSession.java @@ -22,10 +22,10 @@ import android.view.MotionEvent; import java.util.ArrayList; -import static com.android.systemui.statusbar.phone.TouchAnalyticsProto.Session; -import static com.android.systemui.statusbar.phone.TouchAnalyticsProto.Session.PhoneEvent; -import static com.android.systemui.statusbar.phone.TouchAnalyticsProto.Session.SensorEvent; -import static com.android.systemui.statusbar.phone.TouchAnalyticsProto.Session.TouchEvent; +import static com.android.systemui.statusbar.phone.nano.TouchAnalyticsProto.Session; +import static com.android.systemui.statusbar.phone.nano.TouchAnalyticsProto.Session.PhoneEvent; +import static com.android.systemui.statusbar.phone.nano.TouchAnalyticsProto.Session.SensorEvent; +import static com.android.systemui.statusbar.phone.nano.TouchAnalyticsProto.Session.TouchEvent; /** * Collects touch, sensor and phone events and converts the data to diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java index b3038b96fe04..870d4d1c6a9d 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java @@ -78,10 +78,10 @@ public class DozeLog { log("pulseFinish"); } - public static void traceNotificationPulse(Context context, long instance) { + public static void traceNotificationPulse(Context context) { if (!ENABLED) return; init(context); - log("notificationPulse instance=" + instance); + log("notificationPulse"); sNotificationPulseStats.append(); } diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java index bb4ea2d7ee02..9cc927d1fb3a 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java @@ -34,7 +34,7 @@ import android.util.Log; import com.android.internal.hardware.AmbientDisplayConfiguration; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto; +import com.android.internal.logging.nano.MetricsProto; import com.android.systemui.statusbar.phone.DozeParameters; import java.io.PrintWriter; diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java index 9df8113b7ba6..9f26b0c57dbe 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java @@ -87,6 +87,7 @@ public class DozeTriggers implements DozeMachine.Part { mNotificationPulseTime = SystemClock.elapsedRealtime(); if (!mConfig.pulseOnNotificationEnabled(UserHandle.USER_CURRENT)) return; requestPulse(DozeLog.PULSE_REASON_NOTIFICATION, false /* performedProxCheck */); + DozeLog.traceNotificationPulse(mContext); } private void onWhisper() { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java index 816d70d3baef..fe9f55f9a1ee 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java @@ -136,7 +136,7 @@ public class KeyguardService extends Service { @Override // Binder interface public void onScreenTurnedOn() { - Trace.beginSection("KeyguardService.mBinder#onScreenTurningOn"); + Trace.beginSection("KeyguardService.mBinder#onScreenTurnedOn"); checkPermission(); mKeyguardViewMediator.onScreenTurnedOn(); Trace.endSection(); diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java index c699e275ac11..49307d80f139 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java @@ -28,7 +28,7 @@ import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.R; import com.android.systemui.plugins.qs.QSContainer; import com.android.systemui.plugins.qs.QSContainer.DetailAdapter; diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java index 39ce324365a7..6856575ad9c1 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java @@ -29,7 +29,7 @@ import android.util.Log; import android.util.SparseArray; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settingslib.RestrictedLockUtils; import com.android.systemui.plugins.qs.QSContainer.DetailAdapter; import com.android.systemui.qs.QSTile.State; diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java index cf2c16dd8664..f663c751ebf5 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java +++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java @@ -35,7 +35,7 @@ import android.widget.Toolbar; import android.widget.Toolbar.OnMenuItemClickListener; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto; +import com.android.internal.logging.nano.MetricsProto; import com.android.systemui.R; import com.android.systemui.plugins.qs.QSContainer; import com.android.systemui.qs.QSDetailClipper; diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java index 8d7f6ee72850..f2c3e61cfe02 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java @@ -40,7 +40,7 @@ import android.widget.FrameLayout; import android.widget.TextView; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto; +import com.android.internal.logging.nano.MetricsProto; import com.android.systemui.R; import com.android.systemui.qs.QSIconView; import com.android.systemui.qs.customize.TileAdapter.Holder; diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java index dc68112c6bbc..28530d7b0cfb 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java @@ -37,7 +37,7 @@ import android.view.IWindowManager; import android.view.WindowManager; import android.view.WindowManagerGlobal; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.R; import com.android.systemui.qs.QSTile; import com.android.systemui.qs.external.TileLifecycleManager.TileChangeListener; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java index a980a7f87405..e57cd58fe8fe 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java @@ -26,7 +26,7 @@ import android.provider.Settings.Global; import android.widget.Switch; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.R; import com.android.systemui.qs.GlobalSetting; import com.android.systemui.qs.QSTile; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java index d89fbfd3c8df..e5a555ac6942 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java @@ -35,7 +35,7 @@ import android.widget.Button; import android.widget.Checkable; import android.widget.ImageView; import android.widget.TextView; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settingslib.BatteryInfo; import com.android.settingslib.graph.UsageView; import com.android.systemui.BatteryMeterDrawable; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java index 18bde27fc6b4..53010afceaf0 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java @@ -29,7 +29,7 @@ import android.widget.Button; import android.widget.Switch; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.systemui.R; import com.android.systemui.plugins.qs.QSContainer.DetailAdapter; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java index 61bad771b6e0..4abd84a64517 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java @@ -26,7 +26,7 @@ import android.view.ViewGroup; import android.widget.Button; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.R; import com.android.systemui.plugins.qs.QSContainer.DetailAdapter; import com.android.systemui.qs.QSDetailItems; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java index 7de883e2505d..2183565502f3 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java @@ -26,7 +26,7 @@ import android.view.ViewGroup; import android.widget.Button; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settingslib.net.DataUsageController; import com.android.systemui.R; import com.android.systemui.plugins.qs.QSContainer.DetailAdapter; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java index 5ae7a767aaea..77f063dfc2eb 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java @@ -22,7 +22,7 @@ import android.provider.Settings.Secure; import android.widget.Switch; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.R; import com.android.systemui.qs.QSTile; import com.android.systemui.qs.SecureSetting; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java index aabafe162f0c..0ff81e5f8e52 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java @@ -19,7 +19,7 @@ import android.content.Intent; import android.widget.Switch; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.Prefs; import com.android.systemui.R; import com.android.systemui.qs.QSTile; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java index ec4ab51e0d1e..544ee910c228 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java @@ -33,7 +33,7 @@ import android.widget.Switch; import android.widget.Toast; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.Prefs; import com.android.systemui.R; import com.android.systemui.SysUIToast; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java index 0aa723edfb31..8fdce65b1973 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java @@ -25,7 +25,7 @@ import android.text.style.ForegroundColorSpan; import android.widget.Switch; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.R; import com.android.systemui.qs.QSTile; import com.android.systemui.statusbar.policy.FlashlightController; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java index 016c4b70f485..b888fc866bb5 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java @@ -29,7 +29,7 @@ import android.text.style.ForegroundColorSpan; import android.widget.Switch; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.R; import com.android.systemui.qs.GlobalSetting; import com.android.systemui.qs.QSTile; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java index 2a2cc46cb98c..f9688169d795 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java @@ -30,7 +30,7 @@ import android.text.TextUtils; import android.util.Log; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.qs.QSTile; import java.util.Arrays; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java index 5b5ecae3d423..4b890754eb84 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java @@ -23,7 +23,7 @@ import android.provider.Settings; import android.widget.Switch; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.R; import com.android.systemui.qs.QSTile; import com.android.systemui.statusbar.policy.KeyguardMonitor; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java index c02e5aee9ccf..10fde3042ce4 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java @@ -23,7 +23,7 @@ import android.widget.Switch; import com.android.internal.app.NightDisplayController; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.R; import com.android.systemui.qs.QSTile; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java index 499eb50e9992..eb4c5109f253 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java @@ -24,7 +24,7 @@ import android.provider.Settings; import android.widget.Switch; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.R; import com.android.systemui.qs.QSTile; import com.android.systemui.statusbar.policy.RotationLockController; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java index cd09231ca002..91d38bd075bf 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java @@ -24,7 +24,7 @@ import android.view.View; import android.view.ViewGroup; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settingslib.RestrictedLockUtils; import com.android.systemui.R; import com.android.systemui.qs.PseudoGridView; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java index b5fbfe05d368..e79e51916a98 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java @@ -21,7 +21,7 @@ import android.graphics.drawable.Drawable; import android.provider.Settings; import android.util.Pair; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.plugins.qs.QSContainer.DetailAdapter; import com.android.systemui.qs.QSTile; import com.android.systemui.statusbar.policy.UserInfoController; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java index 27306fcfcd00..9ce748f69e1c 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java @@ -28,7 +28,7 @@ import android.widget.Button; import android.widget.Switch; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settingslib.wifi.AccessPoint; import com.android.systemui.R; import com.android.systemui.plugins.qs.QSContainer.DetailAdapter; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java index 459e8ece569e..ce7fbd368cba 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java @@ -21,7 +21,7 @@ import android.provider.Settings; import android.widget.Switch; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.R; import com.android.systemui.qs.QSTile; import com.android.systemui.statusbar.phone.ManagedProfileController; diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java index 27fcf2a5aba7..7655e6cee85b 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java +++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java @@ -41,7 +41,7 @@ import android.view.Display; import android.widget.Toast; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.EventLogConstants; import com.android.systemui.EventLogTags; import com.android.systemui.R; @@ -57,6 +57,7 @@ import com.android.systemui.recents.events.component.ShowUserToastEvent; import com.android.systemui.recents.events.ui.RecentsDrawnEvent; import com.android.systemui.recents.misc.SystemServicesProxy; import com.android.systemui.recents.model.RecentsTaskLoader; +import com.android.systemui.recents.grid.RecentsGridImpl; import com.android.systemui.recents.tv.RecentsTvImpl; import com.android.systemui.stackdivider.Divider; @@ -83,6 +84,7 @@ public class Recents extends SystemUI static { RECENTS_ACTIVITIES.add(RecentsImpl.RECENTS_ACTIVITY); RECENTS_ACTIVITIES.add(RecentsTvImpl.RECENTS_TV_ACTIVITY); + RECENTS_ACTIVITIES.add(RecentsGridImpl.RECENTS_MOSAIC_ACTIVITY); } // Purely for experimentation @@ -205,6 +207,8 @@ public class Recents extends SystemUI getSystemService(Context.UI_MODE_SERVICE); if (uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION) { mImpl = new RecentsTvImpl(mContext); + } else if (SystemProperties.getBoolean("ro.recents.grid", false) == true) { + mImpl = new RecentsGridImpl(mContext); } else { mImpl = new RecentsImpl(mContext); } diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java index ec99d20ffdb3..af1823c88da0 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java @@ -40,7 +40,7 @@ import android.view.WindowManager; import android.view.WindowManager.LayoutParams; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.DejankUtils; import com.android.systemui.Interpolators; import com.android.keyguard.LatencyTracker; diff --git a/packages/SystemUI/src/com/android/systemui/recents/grid/RecentsGridActivity.java b/packages/SystemUI/src/com/android/systemui/recents/grid/RecentsGridActivity.java new file mode 100644 index 000000000000..b88ee7672cfa --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/recents/grid/RecentsGridActivity.java @@ -0,0 +1,316 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.systemui.recents.grid; + +import android.app.Activity; +import android.content.Intent; +import android.content.res.Configuration; +import android.graphics.Rect; +import android.os.Bundle; +import android.util.Log; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewTreeObserver; +import android.widget.FrameLayout; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.android.internal.logging.MetricsLogger; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.systemui.R; +import com.android.systemui.recents.Recents; +import com.android.systemui.recents.RecentsActivity; +import com.android.systemui.recents.RecentsActivityLaunchState; +import com.android.systemui.recents.RecentsConfiguration; +import com.android.systemui.recents.RecentsImpl; +import com.android.systemui.recents.events.EventBus; +import com.android.systemui.recents.events.activity.ConfigurationChangedEvent; +import com.android.systemui.recents.events.activity.HideRecentsEvent; +import com.android.systemui.recents.events.activity.LaunchNextTaskRequestEvent; +import com.android.systemui.recents.events.activity.LaunchTaskEvent; +import com.android.systemui.recents.events.activity.ToggleRecentsEvent; +import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent; +import com.android.systemui.recents.events.ui.AllTaskViewsDismissedEvent; +import com.android.systemui.recents.events.ui.DeleteTaskDataEvent; +import com.android.systemui.recents.events.ui.DismissAllTaskViewsEvent; +import com.android.systemui.recents.events.ui.DismissTaskViewEvent; +import com.android.systemui.recents.events.ui.TaskViewDismissedEvent; +import com.android.systemui.recents.misc.SystemServicesProxy; +import com.android.systemui.recents.misc.Utilities; +import com.android.systemui.recents.model.RecentsTaskLoadPlan; +import com.android.systemui.recents.model.RecentsTaskLoader; +import com.android.systemui.recents.model.Task; +import com.android.systemui.recents.model.TaskStack; +import com.android.systemui.recents.views.TaskView; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * The main grid recents activity started by the RecentsImpl. + */ +public class RecentsGridActivity extends Activity implements ViewTreeObserver.OnPreDrawListener { + private final static String TAG = "RecentsGridActivity"; + + private TaskStack mTaskStack; + private List<Task> mTasks = new ArrayList<>(); + private List<View> mTaskViews = new ArrayList<>(); + private FrameLayout mRecentsView; + private TextView mEmptyView; + private View mClearAllButton; + private int mDisplayOrientation = Configuration.ORIENTATION_UNDEFINED; + private Rect mDisplayRect = new Rect(); + private LayoutInflater mInflater; + private boolean mTouchExplorationEnabled; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.recents_grid); + SystemServicesProxy ssp = Recents.getSystemServices(); + + mInflater = LayoutInflater.from(this); + mDisplayOrientation = Utilities.getAppConfiguration(this).orientation; + mDisplayRect = ssp.getDisplayRect(); + mTouchExplorationEnabled = ssp.isTouchExplorationEnabled(); + + mRecentsView = (FrameLayout) findViewById(R.id.recents_view); + LinearLayout recentsContainer = (LinearLayout) findViewById(R.id.recents_container); + mEmptyView = (TextView) mInflater.inflate(R.layout.recents_empty, recentsContainer, false); + mClearAllButton = findViewById(R.id.button); + + FrameLayout.LayoutParams emptyViewLayoutParams = new FrameLayout.LayoutParams( + FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT); + emptyViewLayoutParams.gravity = Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL; + mEmptyView.setLayoutParams(emptyViewLayoutParams); + mRecentsView.addView(mEmptyView); + + mClearAllButton.setVisibility(View.VISIBLE); + LinearLayout.LayoutParams lp = + (LinearLayout.LayoutParams) mClearAllButton.getLayoutParams(); + lp.gravity = Gravity.END; + + mClearAllButton.setOnClickListener(v -> { + EventBus.getDefault().send(new DismissAllTaskViewsEvent()); + }); + + mRecentsView.setOnClickListener(v -> { + EventBus.getDefault().send(new HideRecentsEvent( + false /* triggeredFromAltTab */, false /* triggeredFromHomeKey */)); + }); + + EventBus.getDefault().register(this, RecentsActivity.EVENT_BUS_PRIORITY); + } + + private TaskView createView() { + return (TaskView) mInflater.inflate(R.layout.recents_task_view, mRecentsView, false); + } + + private void clearTaskViews() { + for (View taskView : mTaskViews) { + ViewGroup parent = (ViewGroup) taskView.getParent(); + if (parent != null) { + parent.removeView(taskView); + } + } + mTaskViews.clear(); + } + + private void updateControlVisibility() { + boolean empty = (mTasks.size() == 0); + mClearAllButton.setVisibility(empty ? View.INVISIBLE : View.VISIBLE); + mEmptyView.setVisibility(empty ? View.VISIBLE : View.INVISIBLE); + if (empty) { + mEmptyView.bringToFront(); + } + } + + private void updateRecentsTasks() { + RecentsTaskLoader loader = Recents.getTaskLoader(); + RecentsTaskLoadPlan plan = RecentsImpl.consumeInstanceLoadPlan(); + if (plan == null) { + plan = loader.createLoadPlan(this); + } + RecentsConfiguration config = Recents.getConfiguration(); + RecentsActivityLaunchState launchState = config.getLaunchState(); + if (!plan.hasTasks()) { + loader.preloadTasks(plan, -1, !launchState.launchedFromHome); + } + int numVisibleTasks = 9; + mTaskStack = plan.getTaskStack(); + RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options(); + loadOpts.runningTaskId = launchState.launchedToTaskId; + loadOpts.numVisibleTasks = numVisibleTasks; + loadOpts.numVisibleTaskThumbnails = numVisibleTasks; + loader.loadTasks(this, plan, loadOpts); + + List<Task> stackTasks = mTaskStack.getStackTasks(); + Collections.reverse(stackTasks); + mTasks = stackTasks; + + updateControlVisibility(); + + clearTaskViews(); + for (int i = 0; i < mTasks.size(); i++) { + Task task = mTasks.get(i); + TaskView taskView = createView(); + taskView.onTaskBound(task, mTouchExplorationEnabled, mDisplayOrientation, mDisplayRect); + Recents.getTaskLoader().loadTaskData(task); + taskView.setTouchEnabled(true); + // Show dismiss button right away. + taskView.startNoUserInteractionAnimation(); + mTaskViews.add(taskView); + } + } + + @Override + protected void onStart() { + super.onStart(); + EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, true)); + mRecentsView.getViewTreeObserver().addOnPreDrawListener(this); + } + + @Override + public void onResume() { + super.onResume(); + updateRecentsTasks(); + } + + @Override + protected void onStop() { + super.onStop(); + EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, false)); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + EventBus.getDefault().unregister(this); + } + + @Override + public void onBackPressed() { + // Back behaves like the recents button so just trigger a toggle event. + EventBus.getDefault().send(new ToggleRecentsEvent()); + } + + @Override + public boolean onPreDraw() { + mRecentsView.getViewTreeObserver().removeOnPreDrawListener(this); + int width = mRecentsView.getWidth(); + int height = mRecentsView.getHeight(); + + List<Rect> rects = TaskGridLayoutAlgorithm.getRectsForTaskCount( + mTasks.size(), width, height, false /* allowLineOfThree */, 30 /* padding */); + for (int i = 0; i < rects.size(); i++) { + Rect rect = rects.get(i); + View taskView = mTaskViews.get(i); + taskView.setLayoutParams(new FrameLayout.LayoutParams(rect.width(), rect.height())); + taskView.setTranslationX(rect.left); + taskView.setTranslationY(rect.top); + mRecentsView.addView(taskView); + } + return true; + } + + void dismissRecentsToHome() { + Intent startMain = new Intent(Intent.ACTION_MAIN); + startMain.addCategory(Intent.CATEGORY_HOME); + startActivity(startMain); + } + + /**** EventBus events ****/ + + public final void onBusEvent(HideRecentsEvent event) { + if (event.triggeredFromAltTab) { + // Do nothing for now. + } else if (event.triggeredFromHomeKey) { + dismissRecentsToHome(); + } + } + + public final void onBusEvent(ToggleRecentsEvent event) { + // Always go back home for simplicity for now. If recents is entered from another app, this + // code will eventually need to go back to the original app. + dismissRecentsToHome(); + } + + public final void onBusEvent(DismissTaskViewEvent event) { + int taskIndex = mTaskViews.indexOf(event.taskView); + if (taskIndex != -1) { + mTasks.remove(taskIndex); + ((ViewGroup) event.taskView.getParent()).removeView(event.taskView); + mTaskViews.remove(taskIndex); + EventBus.getDefault().send( + new TaskViewDismissedEvent(event.taskView.getTask(), event.taskView, null)); + } + } + + public final void onBusEvent(TaskViewDismissedEvent event) { + mRecentsView.announceForAccessibility(this.getString( + R.string.accessibility_recents_item_dismissed, event.task.title)); + updateControlVisibility(); + + EventBus.getDefault().send(new DeleteTaskDataEvent(event.task)); + + MetricsLogger.action(this, MetricsEvent.OVERVIEW_DISMISS, + event.task.key.getComponent().toString()); + } + + public final void onBusEvent(DeleteTaskDataEvent event) { + // Remove any stored data from the loader. + RecentsTaskLoader loader = Recents.getTaskLoader(); + loader.deleteTaskData(event.task, false); + + // Remove the task from activity manager. + SystemServicesProxy ssp = Recents.getSystemServices(); + ssp.removeTask(event.task.key.id); + } + + public final void onBusEvent(final DismissAllTaskViewsEvent event) { + // Keep track of the tasks which will have their data removed. + ArrayList<Task> tasks = new ArrayList<>(mTaskStack.getStackTasks()); + mRecentsView.announceForAccessibility(this.getString( + R.string.accessibility_recents_all_items_dismissed)); + mTaskStack.removeAllTasks(); + for (int i = tasks.size() - 1; i >= 0; i--) { + EventBus.getDefault().send(new DeleteTaskDataEvent(tasks.get(i))); + } + mTasks = new ArrayList<>(); + updateRecentsTasks(); + + MetricsLogger.action(this, MetricsEvent.OVERVIEW_DISMISS_ALL); + } + + public final void onBusEvent(AllTaskViewsDismissedEvent event) { + SystemServicesProxy ssp = Recents.getSystemServices(); + if (!ssp.hasDockedTask()) { + dismissRecentsToHome(); + } + } + + public final void onBusEvent(LaunchNextTaskRequestEvent event) { + // Always go back home for simplicity for now. Quick switch will be supported soon. + EventBus.getDefault().send(new HideRecentsEvent(false, true)); + } + + public final void onBusEvent(LaunchTaskEvent event) { + startActivity(event.task.key.baseIntent); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/recents/grid/RecentsGridImpl.java b/packages/SystemUI/src/com/android/systemui/recents/grid/RecentsGridImpl.java new file mode 100644 index 000000000000..41acaa0a619a --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/recents/grid/RecentsGridImpl.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.systemui.recents.grid; + +import android.app.ActivityManager; +import android.content.Context; +import android.content.Intent; +import android.os.UserHandle; + +import com.android.systemui.recents.RecentsImpl; +import com.android.systemui.recents.events.EventBus; +import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent; + +public class RecentsGridImpl extends RecentsImpl { + public static final String RECENTS_MOSAIC_ACTIVITY = + "com.android.systemui.recents.grid.RecentsGridActivity"; + + public RecentsGridImpl(Context context) { + super(context); + } + + @Override + protected void startRecentsActivity(ActivityManager.RunningTaskInfo runningTask, + boolean isHomeStackVisible, boolean animate, int growTarget) { + Intent intent = new Intent(); + intent.setClassName(RECENTS_PACKAGE, RECENTS_MOSAIC_ACTIVITY); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS + | Intent.FLAG_ACTIVITY_TASK_ON_HOME); + + mContext.startActivityAsUser(intent, UserHandle.CURRENT); + EventBus.getDefault().send(new RecentsActivityStartingEvent()); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/recents/grid/TaskGridLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/grid/TaskGridLayoutAlgorithm.java new file mode 100644 index 000000000000..057aa5497bf4 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/recents/grid/TaskGridLayoutAlgorithm.java @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.systemui.recents.grid; + +import android.graphics.Rect; +import android.util.Log; + +import java.util.ArrayList; +import java.util.List; + +class TaskGridLayoutAlgorithm { + + private static final String TAG = "TaskGridLayoutAlgorithm"; + + static List<Rect> getRectsForTaskCount(int count, int containerWidth, int containerHeight, + boolean allowLineOfThree, int padding) { + return getRectsForTaskCount(count, containerWidth, containerHeight, allowLineOfThree, + padding, null); + } + + static List<Rect> getRectsForTaskCount(int count, int containerWidth, int containerHeight, + boolean allowLineOfThree, int padding, Rect preCalculatedTile) { + int singleLineMaxCount = allowLineOfThree ? 3 : 2; + List<Rect> rects = new ArrayList<>(count); + boolean landscape = (containerWidth > containerHeight); + + // We support at most 9 tasks in this layout. + count = Math.min(count, 9); + + if (count == 0) { + return rects; + } + if (count <= singleLineMaxCount) { + if (landscape) { + // Single line. + int taskWidth = 0; + int emptySpace = 0; + if (preCalculatedTile != null) { + taskWidth = preCalculatedTile.width(); + emptySpace = containerWidth - (count * taskWidth) - (count - 1) * padding; + } else { + // Divide available space in equal parts. + taskWidth = (containerWidth - (count - 1) * padding) / count; + } + for (int i = 0; i < count; i++) { + int left = emptySpace / 2 + i * taskWidth + i * padding; + rects.add(new Rect(left, 0, left + taskWidth, containerHeight)); + } + } else { + // Single column. Divide available space in equal parts. + int taskHeight = (containerHeight - (count - 1) * padding) / count; + for (int i = 0; i < count; i++) { + int top = i * taskHeight + i * padding; + rects.add(new Rect(0, top, containerWidth, top + taskHeight)); + } + } + } else if (count < 7) { + // Two lines. + int lineHeight = (containerHeight - padding) / 2; + int lineTaskCount = (int) Math.ceil((double) count / 2); + List<Rect> rectsA = getRectsForTaskCount( + lineTaskCount, containerWidth, lineHeight, true /* allowLineOfThree */, padding, + null); + List<Rect> rectsB = getRectsForTaskCount( + count - lineTaskCount, containerWidth, lineHeight, true /* allowLineOfThree */, + padding, rectsA.get(0)); + for (Rect rect : rectsB) { + rect.offset(0, lineHeight + padding); + } + rects.addAll(rectsA); + rects.addAll(rectsB); + } else { + // Three lines. + int lineHeight = (containerHeight - 2 * padding) / 3; + int lineTaskCount = (int) Math.ceil((double) count / 3); + List<Rect> rectsA = getRectsForTaskCount( + lineTaskCount, containerWidth, lineHeight, true /* allowLineOfThree */, padding, null); + List<Rect> rectsB = getRectsForTaskCount( + lineTaskCount, containerWidth, lineHeight, true /* allowLineOfThree */, padding, + rectsA.get(0)); + List<Rect> rectsC = getRectsForTaskCount( + count - (2 * lineTaskCount), containerWidth, lineHeight, + true /* allowLineOfThree */, padding, rectsA.get(0)); + for (Rect rect : rectsB) { + rect.offset(0, lineHeight + padding); + } + for (Rect rect : rectsC) { + rect.offset(0, 2 * (lineHeight + padding)); + } + rects.addAll(rectsA); + rects.addAll(rectsB); + rects.addAll(rectsC); + } + return rects; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java index 11a4f64726b9..ea9714f697ff 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java +++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java @@ -85,7 +85,6 @@ import com.android.systemui.recents.Recents; import com.android.systemui.recents.RecentsDebugFlags; import com.android.systemui.recents.RecentsImpl; import com.android.systemui.recents.model.Task; -import com.android.systemui.recents.tv.RecentsTvImpl; import com.android.systemui.recents.model.ThumbnailData; import java.io.IOException; diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java index febeacb3bcf0..3c7012a16dfc 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java @@ -43,7 +43,7 @@ import android.widget.FrameLayout; import android.widget.TextView; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.recents.Recents; diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java index 936354e98998..77c61f8bc526 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java @@ -47,7 +47,7 @@ import android.widget.FrameLayout; import android.widget.ScrollView; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.recents.Recents; diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java index d44aa844003f..71f559be6775 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java @@ -34,7 +34,7 @@ import android.view.ViewParent; import android.view.animation.Interpolator; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.SwipeHelper; diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java index 99d98bcd3f1d..de7def6c95c9 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java @@ -39,7 +39,7 @@ import android.widget.TextView; import android.widget.Toast; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.recents.Recents; @@ -362,12 +362,12 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks } /** Enables/disables handling touch on this task view. */ - void setTouchEnabled(boolean enabled) { + public void setTouchEnabled(boolean enabled) { setOnClickListener(enabled ? this : null); } /** Animates this task view if the user does not interact with the stack after a certain time. */ - void startNoUserInteractionAnimation() { + public void startNoUserInteractionAnimation() { mHeaderView.startNoUserInteractionAnimation(); } @@ -668,10 +668,16 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks @Override public boolean onLongClick(View v) { SystemServicesProxy ssp = Recents.getSystemServices(); - // Since we are clipping the view to the bounds, manually do the hit test + boolean inBounds = false; Rect clipBounds = new Rect(mViewBounds.mClipBounds); - clipBounds.scale(getScaleX()); - boolean inBounds = clipBounds.contains(mDownTouchPos.x, mDownTouchPos.y); + if (!clipBounds.isEmpty()) { + // If we are clipping the view to the bounds, manually do the hit test. + clipBounds.scale(getScaleX()); + inBounds = clipBounds.contains(mDownTouchPos.x, mDownTouchPos.y); + } else { + // Otherwise just make sure we're within the view's bounds. + inBounds = mDownTouchPos.x <= getWidth() && mDownTouchPos.y <= getHeight(); + } if (v == this && inBounds && !ssp.hasDockedTask()) { // Start listening for drag events setClipViewInStack(false); diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java index 3ed26984c809..e8039c35bb4f 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java +++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java @@ -33,7 +33,7 @@ import android.provider.Settings; import android.widget.ImageView; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import java.util.ArrayList; diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java index 803fe4809322..901d47d6cde8 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java +++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java @@ -25,7 +25,7 @@ import android.view.WindowManager; import android.widget.ImageView; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.R; /** A dialog that provides controls for adjusting the screen brightness. */ diff --git a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java index 15d26f9a7a0c..2684722a9d84 100644 --- a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java +++ b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java @@ -35,7 +35,7 @@ import android.view.WindowManager; import android.view.WindowManagerGlobal; import android.view.accessibility.AccessibilityManager; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.policy.DividerSnapAlgorithm; import com.android.settingslib.accessibility.AccessibilityUtils; import com.android.systemui.R; diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java index 4e34bbc11453..47d2def0cf63 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java @@ -54,7 +54,7 @@ import android.view.animation.PathInterpolator; import android.widget.FrameLayout; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.policy.DividerSnapAlgorithm; import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget; import com.android.internal.policy.DockedDividerUtils; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index 23acb1b1ce41..93ddd177c270 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -87,7 +87,7 @@ import android.widget.TextView; import android.widget.Toast; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.StatusBarIcon; import com.android.internal.widget.LockPatternUtils; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java index caf5447d9d26..5173176ffa8f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java @@ -43,7 +43,7 @@ import android.widget.Chronometer; import android.widget.ImageView; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.util.NotificationColorUtil; import com.android.systemui.R; import com.android.systemui.classifier.FalsingManager; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java index f4387629b8b3..f43fc4065766 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java @@ -59,7 +59,7 @@ import android.widget.TextView; import com.android.internal.app.AssistUtils; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto; +import com.android.internal.logging.nano.MetricsProto; import com.android.settingslib.Utils; import com.android.systemui.R; import com.android.systemui.recents.Recents; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java index b10fb3133d98..bb327eff5c40 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java @@ -43,7 +43,7 @@ import android.widget.SeekBar; import android.widget.TextView; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settingslib.Utils; import com.android.systemui.Interpolators; import com.android.systemui.R; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java index 0f800bb61de7..228e8ea843b5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java @@ -27,7 +27,7 @@ import android.view.View; import android.view.ViewConfiguration; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget; import com.android.systemui.R; import com.android.systemui.RecentsComponent; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index c33d91a9a29d..599fcba068e0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -118,7 +118,7 @@ import android.widget.ImageView; import android.widget.TextView; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.statusbar.NotificationVisibility; import com.android.internal.statusbar.StatusBarIcon; import com.android.keyguard.KeyguardHostView.OnDismissAction; @@ -1649,9 +1649,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, newNotification.headsUpContentView = sbn.getNotification().headsUpContentView; StatusBarNotification newSbn = new StatusBarNotification(sbn.getPackageName(), - sbn.getOpPkg(), + sbn.getOpPkg(), sbn.getNotificationChannel(), sbn.getId(), sbn.getTag(), sbn.getUid(), sbn.getInitialPid(), - 0, newNotification, sbn.getUser(), sbn.getPostTime()); + newNotification, sbn.getUser(), sbn.getOverrideGroupKey(), sbn.getPostTime()); updateNotification(newSbn, null); mKeysKeptForRemoteInput.add(entry.key); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java index a8b0122a9470..65c634727293 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java @@ -33,7 +33,7 @@ import android.widget.TextView; import android.widget.Toast; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto; +import com.android.internal.logging.nano.MetricsProto; import com.android.keyguard.KeyguardStatusView; import com.android.systemui.FontSizeUtils; import com.android.systemui.R; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java index 7b1f7071b5c7..44ec2831dd9b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java @@ -50,7 +50,7 @@ import android.widget.ProgressBar; import android.widget.TextView; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto; +import com.android.internal.logging.nano.MetricsProto; import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.statusbar.ExpandableView; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java index 30d1c54b4096..eda46c55bf74 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java @@ -48,7 +48,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.util.UserIcons; import com.android.settingslib.RestrictedLockUtils; import com.android.systemui.GuestResumeSessionReceiver; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java index da58d9e98a6b..72a0e5929a17 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -57,7 +57,7 @@ import android.widget.OverScroller; import android.widget.ScrollView; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.ExpandHelper; import com.android.systemui.Interpolators; import com.android.systemui.R; diff --git a/packages/SystemUI/src/com/android/systemui/tuner/BatteryPreference.java b/packages/SystemUI/src/com/android/systemui/tuner/BatteryPreference.java index 6e08139267ef..9998283e1a05 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/BatteryPreference.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/BatteryPreference.java @@ -21,7 +21,7 @@ import android.text.TextUtils; import android.util.ArraySet; import android.util.AttributeSet; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.statusbar.phone.StatusBarIconController; import static com.android.systemui.BatteryMeterDrawable.SHOW_PERCENT_SETTING; diff --git a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java index 0a3197c039cf..0a962f1f2519 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java @@ -31,7 +31,7 @@ import android.support.v7.preference.PreferenceScreen; import android.view.MenuItem; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.DemoMode; import com.android.systemui.R; diff --git a/packages/SystemUI/src/com/android/systemui/tuner/PowerNotificationControlsFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/PowerNotificationControlsFragment.java index 14fccf21af43..8740a3c2f45a 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/PowerNotificationControlsFragment.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/PowerNotificationControlsFragment.java @@ -16,7 +16,7 @@ package com.android.systemui.tuner; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.R; import android.annotation.Nullable; diff --git a/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java b/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java index f2f0382060c7..dea2f5060c3a 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java @@ -24,7 +24,7 @@ import android.text.TextUtils; import android.util.AttributeSet; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.statusbar.phone.StatusBarIconController; import com.android.systemui.tuner.TunerService.Tunable; diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java index 7f63418de324..fd6500fd1eec 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java @@ -27,7 +27,7 @@ import android.view.MenuInflater; import android.view.MenuItem; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.R; import com.android.systemui.plugins.PluginPrefs; diff --git a/packages/SystemUI/src/com/android/systemui/volume/Events.java b/packages/SystemUI/src/com/android/systemui/volume/Events.java index 8e0f9b88af3e..ca53bc4f7928 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/Events.java +++ b/packages/SystemUI/src/com/android/systemui/volume/Events.java @@ -23,7 +23,7 @@ import android.provider.Settings.Global; import android.util.Log; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.volume.VolumeDialogController.State; import java.util.Arrays; diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java index 22d130941f47..87f6138da15d 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java +++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java @@ -52,7 +52,7 @@ import android.widget.RadioGroup; import android.widget.TextView; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.Prefs; import com.android.systemui.R; import com.android.systemui.statusbar.policy.ZenModeController; diff --git a/packages/SystemUI/tests/src/com/android/systemui/recents/grid/TaskGridLayoutAlgorithmTest.java b/packages/SystemUI/tests/src/com/android/systemui/recents/grid/TaskGridLayoutAlgorithmTest.java new file mode 100644 index 000000000000..74b612744870 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/recents/grid/TaskGridLayoutAlgorithmTest.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +package com.android.systemui.recents.grid; + +import android.graphics.Rect; +import android.test.suitebuilder.annotation.SmallTest; +import com.android.systemui.SysuiTestCase; + +import java.util.List; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertTrue; + +@SmallTest +public class TaskGridLayoutAlgorithmTest extends SysuiTestCase { + + public void testMethodName_ExpectedBehavior() { + assertTrue(true); + } + + public void testOneTile() { + List<Rect> rects = TaskGridLayoutAlgorithm.getRectsForTaskCount( + 1, 1000, 500, false /* allowLineOfThree */, 0 /* padding */); + assertEquals(1, rects.size()); + Rect singleRect = rects.get(0); + assertEquals(1000, singleRect.width()); + } + + public void testTwoTilesLandscape() { + List<Rect> rects = TaskGridLayoutAlgorithm.getRectsForTaskCount( + 2, 1200, 500, false /* allowLineOfThree */, 0 /* padding */); + assertEquals(2, rects.size()); + for (Rect rect : rects) { + assertEquals(600, rect.width()); + assertEquals(500, rect.height()); + } + } + + public void testTwoTilesLandscapeWithPadding() { + List<Rect> rects = TaskGridLayoutAlgorithm.getRectsForTaskCount( + 2, 1200, 500, false /* allowLineOfThree */, 10 /* padding */); + assertEquals(2, rects.size()); + Rect rectA = rects.get(0); + Rect rectB = rects.get(1); + assertEquals(595, rectA.width()); + assertEquals(595, rectB.width()); + assertEquals(605, rectB.left); + } + + public void testTwoTilesPortrait() { + List<Rect> rects = TaskGridLayoutAlgorithm.getRectsForTaskCount( + 2, 500, 1200, false /* allowLineOfThree */, 0 /* padding */); + assertEquals(2, rects.size()); + for (Rect rect : rects) { + assertEquals(500, rect.width()); + assertEquals(600, rect.height()); + } + } + + public void testThreeTiles() { + List<Rect> rects = TaskGridLayoutAlgorithm.getRectsForTaskCount( + 3, 1200, 500, false /* allowLineOfThree */, 0 /* padding */); + assertEquals(3, rects.size()); + for (Rect rect : rects) { + assertEquals(600, rect.width()); + assertEquals(250, rect.height()); + } + // The third tile should be on the second line, in the middle. + Rect rectC = rects.get(2); + assertEquals(300, rectC.left); + assertEquals(250, rectC.top); + } + + public void testFourTiles() { + List<Rect> rects = TaskGridLayoutAlgorithm.getRectsForTaskCount( + 4, 1200, 500, false /* allowLineOfThree */, 0 /* padding */); + assertEquals(4, rects.size()); + for (Rect rect : rects) { + assertEquals(600, rect.width()); + assertEquals(250, rect.height()); + } + Rect rectD = rects.get(3); + assertEquals(600, rectD.left); + assertEquals(250, rectD.top); + } + + public void testNineTiles() { + List<Rect> rects = TaskGridLayoutAlgorithm.getRectsForTaskCount( + 9, 1200, 600, false /* allowLineOfThree */, 0 /* padding */); + assertEquals(9, rects.size()); + for (Rect rect : rects) { + assertEquals(400, rect.width()); + assertEquals(200, rect.height()); + } + Rect rectE = rects.get(4); + assertEquals(400, rectE.left); + assertEquals(200, rectE.top); + Rect rectI = rects.get(8); + assertEquals(800, rectI.left); + assertEquals(400, rectI.top); + }} + diff --git a/services/Android.mk b/services/Android.mk index 3385bed0ba8b..291198303548 100644 --- a/services/Android.mk +++ b/services/Android.mk @@ -22,6 +22,7 @@ services := \ core \ accessibility \ appwidget \ + autofill \ backup \ devicepolicy \ midi \ diff --git a/services/autofill/Android.mk b/services/autofill/Android.mk new file mode 100644 index 000000000000..a1f19fd4c72d --- /dev/null +++ b/services/autofill/Android.mk @@ -0,0 +1,12 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := services.autofill + +LOCAL_SRC_FILES += \ + $(call all-java-files-under,java) + +LOCAL_JAVA_LIBRARIES := services.core + +include $(BUILD_STATIC_JAVA_LIBRARY) diff --git a/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java b/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java new file mode 100644 index 000000000000..3b41877bd36a --- /dev/null +++ b/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java @@ -0,0 +1,310 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.autofill; + +import static android.Manifest.permission.MANAGE_AUTO_FILL; +import static android.content.Context.AUTO_FILL_MANAGER_SERVICE; + +import android.Manifest; +import android.app.ActivityManager; +import android.app.AppGlobals; +import android.content.ComponentName; +import android.content.ContentResolver; +import android.content.Context; +import android.content.pm.PackageManager; +import android.content.pm.ServiceInfo; +import android.database.ContentObserver; +import android.net.Uri; +import android.os.Binder; +import android.os.Bundle; +import android.os.Handler; +import android.os.IBinder; +import android.os.Parcel; +import android.os.RemoteException; +import android.os.ResultReceiver; +import android.os.ShellCallback; +import android.os.UserHandle; +import android.provider.Settings; +import android.service.autofill.IAutoFillManagerService; +import android.text.TextUtils; +import android.util.Slog; +import android.util.SparseArray; + +import com.android.internal.annotations.GuardedBy; +import com.android.internal.os.BackgroundThread; +import com.android.server.FgThread; +import com.android.server.SystemService; + +import java.io.FileDescriptor; +import java.io.PrintWriter; + +/** + * Entry point service for auto-fill management. + * + * <p>This service provides the {@link IAutoFillManagerService} implementation and keeps a list of + * {@link AutoFillManagerServiceImpl} per user; the real work is done by + * {@link AutoFillManagerServiceImpl} itself. + */ +public final class AutoFillManagerService extends SystemService { + + private static final String TAG = "AutoFillManagerService"; + private static final boolean DEBUG = true; // TODO: change to false once stable + + private final AutoFillManagerServiceStub mServiceStub; + private final Context mContext; + private final ContentResolver mResolver; + + private final Object mLock = new Object(); + + @GuardedBy("mLock") + private boolean mSafeMode; + + /** + * Map of {@link AutoFillManagerServiceImpl} per user id. + * <p> + * It has to be mapped by user id because the same current user could have simultaneous sessions + * associated to different user profiles (for example, in a multi-window environment). + * <p> + * This map is filled on demand in the following scenarios: + * <ol> + * <li>On start, it sets the value for the default user. + * <li>When an auto-fill service app is removed, its entries are removed. + * <li>When the current user changes. + * <li>When the {@link android.provider.Settings.Secure#AUTO_FILL_SERVICE} changes. + * </ol> + */ + // TODO: make sure all cases listed above are handled + // TODO: should entries be removed when there is no section and have not be used for a while? + @GuardedBy("mLock") + private SparseArray<AutoFillManagerServiceImpl> mImplByUser = new SparseArray<>(); + + // TODO: should disable it on low-memory devices? if not, this attribute should be removed... + private final boolean mEnableService = true; + + public AutoFillManagerService(Context context) { + super(context); + + mContext = context; + mResolver = context.getContentResolver(); + mServiceStub = new AutoFillManagerServiceStub(); + } + + @Override + public void onStart() { + if (DEBUG) + Slog.d(TAG, "onStart(): binding as " + AUTO_FILL_MANAGER_SERVICE); + publishBinderService(AUTO_FILL_MANAGER_SERVICE, mServiceStub); + } + + // TODO: refactor so it's bound on demand, in which case it can use isSafeMode() from PM. + @Override + public void onBootPhase(int phase) { + if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) { + systemRunning(isSafeMode()); + } + } + + // TODO: refactor so it's bound on demand, in which case it can use isSafeMode() from PM. + @Override + public void onStartUser(int userHandle) { + if (DEBUG) Slog.d(TAG, "onStartUser(): userHandle=" + userHandle); + + updateImplementationIfNeeded(userHandle, false); + } + + @Override + public void onUnlockUser(int userHandle) { + if (DEBUG) Slog.d(TAG, "onUnlockUser(): userHandle=" + userHandle); + + updateImplementationIfNeeded(userHandle, false); + } + + @Override + public void onSwitchUser(int userHandle) { + if (DEBUG) Slog.d(TAG, "onSwitchUser(): userHandle=" + userHandle); + + updateImplementationIfNeeded(userHandle, false); + } + + private void systemRunning(boolean safeMode) { + if (DEBUG) Slog.d(TAG, "systemRunning(): safeMode=" + safeMode); + + // TODO: register a PackageMonitor + new SettingsObserver(BackgroundThread.getHandler()); + + synchronized (mLock) { + mSafeMode = safeMode; + updateImplementationIfNeededLocked(ActivityManager.getCurrentUser(), false); + } + } + + private void updateImplementationIfNeeded(int user, boolean force) { + synchronized (mLock) { + updateImplementationIfNeededLocked(user, force); + } + } + + private void updateImplementationIfNeededLocked(int user, boolean force) { + if (DEBUG) + Slog.d(TAG, "updateImplementationIfNeededLocked(" + user + ", " + force + ")"); + + if (mSafeMode) { + if (DEBUG) Slog.d(TAG, "skipping on safe mode"); + return; + } + + final String curService = Settings.Secure.getStringForUser( + mResolver, Settings.Secure.AUTO_FILL_SERVICE, user); + if (DEBUG) + Slog.d(TAG, "Current service settings for user " + user + ": " + curService); + ComponentName serviceComponent = null; + ServiceInfo serviceInfo = null; + if (!TextUtils.isEmpty(curService)) { + try { + serviceComponent = ComponentName.unflattenFromString(curService); + serviceInfo = + AppGlobals.getPackageManager().getServiceInfo(serviceComponent, 0, user); + } catch (RuntimeException | RemoteException e) { + Slog.wtf(TAG, "Bad auto-fill service name " + curService, e); + serviceComponent = null; + serviceInfo = null; + } + } + + final AutoFillManagerServiceImpl impl = mImplByUser.get(user); + if (DEBUG) Slog.d(TAG, "Current impl: " + impl + " component: " + serviceComponent + + " info: " + serviceInfo); + + if (force || impl == null || !impl.mComponent.equals(serviceComponent)) { + if (impl != null) { + impl.shutdownLocked(); + } + if (serviceInfo != null) { + final AutoFillManagerServiceImpl newImpl = new AutoFillManagerServiceImpl(mContext, + mLock, mServiceStub, FgThread.getHandler(), user, serviceComponent); + if (DEBUG) Slog.d(TAG, "Setting impl for user " + user + " as: " + newImpl); + mImplByUser.put(user, newImpl); + newImpl.startLocked(); + } else { + if (DEBUG) Slog.d(TAG, "Removing impl for user " + user + ": " + impl); + mImplByUser.remove(user); + } + } + } + + // TODO: might need to return null instead of throw exception + private AutoFillManagerServiceImpl getImplOrThrowLocked(int userId) { + final AutoFillManagerServiceImpl impl = mImplByUser.get(userId); + if (impl == null) { + throw new IllegalStateException("no auto-fill service for user " + userId); + } + return impl; + } + + final class AutoFillManagerServiceStub extends IAutoFillManagerService.Stub { + + @Override + public String startSession(int userId, Bundle args, int flags, IBinder activityToken) { + mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG); + + synchronized (mLock) { + return getImplOrThrowLocked(userId).startSession(args, flags, activityToken); + } + } + + @Override + public boolean finishSession(int userId, String token) { + mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG); + + synchronized (mLock) { + return getImplOrThrowLocked(userId).finishSessionLocked(token); + } + } + + @Override + public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + if (mContext.checkCallingPermission( + Manifest.permission.DUMP) != PackageManager.PERMISSION_GRANTED) { + pw.println("Permission Denial: can't dump autofill from from pid=" + + Binder.getCallingPid() + + ", uid=" + Binder.getCallingUid()); + return; + } + if (args.length > 0) { + if ("--sessions".equals(args[0])) { + dumpSessions(pw); + return; + } + } + synchronized (mLock) { + pw.print("mEnableService: "); pw.println(mEnableService); + pw.print("mSafeMode: "); pw.println(mSafeMode); + final int size = mImplByUser.size(); + pw.print("Number of implementations: "); + if (size == 0) { + pw.println("none"); + } else { + pw.println(size); + for (int i = 0; i < size; i++) { + pw.print("\nImplementation at index "); pw.println(i); + final AutoFillManagerServiceImpl impl = mImplByUser.valueAt(i); + impl.dumpLocked(" ", pw); + } + } + } + } + + private void dumpSessions(PrintWriter pw) { + boolean foundOne = false; + synchronized (mLock) { + final int size = mImplByUser.size(); + for (int i = 0; i < size; i++) { + final AutoFillManagerServiceImpl impl = mImplByUser.valueAt(i); + foundOne |= impl.dumpSessionsLocked("", pw); + } + } + if (!foundOne) { + pw.println("No active sessions"); + } + } + + @Override + public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, + String[] args, ShellCallback callback, ResultReceiver resultReceiver) { + (new AutoFillManagerServiceShellCommand(this)).exec( + this, in, out, err, args, callback, resultReceiver); + } + + } + + private final class SettingsObserver extends ContentObserver { + SettingsObserver(Handler handler) { + super(handler); + ContentResolver resolver = mContext.getContentResolver(); + resolver.registerContentObserver(Settings.Secure.getUriFor( + Settings.Secure.AUTO_FILL_SERVICE), false, this, + UserHandle.USER_ALL); + } + + @Override + public void onChange(boolean selfChange, Uri uri, int userId) { + synchronized (mLock) { + updateImplementationIfNeededLocked(userId, false); + } + } + } +} diff --git a/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java new file mode 100644 index 000000000000..c780062c567c --- /dev/null +++ b/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java @@ -0,0 +1,280 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.autofill; + +import android.app.ActivityManagerInternal; +import android.content.BroadcastReceiver; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.ServiceConnection; +import android.content.pm.PackageManager; +import android.os.Bundle; +import android.os.Handler; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.UserHandle; +import android.service.autofill.AutoFillService; +import android.service.autofill.AutoFillServiceInfo; +import android.service.autofill.IAutoFillService; +import android.util.Log; +import android.util.PrintWriterPrinter; +import android.util.Slog; + +import com.android.internal.annotations.GuardedBy; +import com.android.server.LocalServices; +import com.android.server.autofill.AutoFillManagerService.AutoFillManagerServiceStub; + +import java.io.PrintWriter; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +/** + * Bridge between the {@code system_server}'s {@link AutoFillManagerService} and the + * app's {@link IAutoFillService} implementation. + * + * <p>It keeps a list of auto-fill sessions for a specifc user. + */ +final class AutoFillManagerServiceImpl { + + private static final String TAG = "AutoFillManagerServiceImpl"; + private static final boolean DEBUG = true; // TODO: change to false once stable + + final int mUser; + final ComponentName mComponent; + + private final Context mContext; + private final Object mLock; + private final AutoFillManagerServiceStub mServiceStub; + private final AutoFillServiceInfo mInfo; + + // Map of sessions keyed by session tokens. + @GuardedBy("mLock") + private Map<String, AutoFillSession> mSessions = new HashMap<>(); + + private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) { + final String reason = intent.getStringExtra("reason"); + if (DEBUG) Slog.d(TAG, "close system dialogs: " + reason); + // TODO: close any pending UI like account selection + } + } + }; + + private final ServiceConnection mConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + if (DEBUG) Log.d(TAG, "onServiceConnected():" + name); + synchronized (mLock) { + mService = IAutoFillService.Stub.asInterface(service); + try { + mService.ready(); + } catch (RemoteException e) { + Slog.w(TAG, "Exception on service.ready(): " + e); + } + } + } + + @Override + public void onServiceDisconnected(ComponentName name) { + if (DEBUG) Log.d(TAG, name + " disconnected"); + mService = null; + } + }; + + @GuardedBy("mLock") + private IAutoFillService mService; + private boolean mBound; + private boolean mValid; + + AutoFillManagerServiceImpl(Context context, Object lock, AutoFillManagerServiceStub stub, + Handler handler, int user, ComponentName component) { + mContext = context; + mLock = lock; + mServiceStub = stub; + mUser = user; + mComponent = component; + + AutoFillServiceInfo info; + try { + info = new AutoFillServiceInfo(component, mUser); + } catch (PackageManager.NameNotFoundException e) { + Slog.w(TAG, "Auto-fill service not found: " + component, e); + mInfo = null; + mValid = false; + return; + } + mInfo = info; + if (mInfo.getParseError() != null) { + Slog.w(TAG, "Bad auto-fill service: " + mInfo.getParseError()); + mValid = false; + return; + } + + mValid = true; + IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); + mContext.registerReceiver(mBroadcastReceiver, filter, null, handler); + } + + void startLocked() { + if (DEBUG) Slog.d(TAG, "startLocked()"); + + final Intent intent = new Intent(AutoFillService.SERVICE_INTERFACE); + intent.setComponent(mComponent); + mBound = mContext.bindServiceAsUser(intent, mConnection, + Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE, new UserHandle(mUser)); + if (!mBound) { + Slog.w(TAG, "Failed binding to auto-fill service " + mComponent); + return; + } + if (DEBUG) Slog.d(TAG, "Bound to " + mComponent); + } + + String startSession(Bundle args, int flags, IBinder activityToken) { + + if (!mBound) { + // TODO: should it bind on demand? Or perhaps always run when on on low-memory? + Slog.w(TAG, "startSession() failed because it's not bound to service"); + return null; + } + + // TODO: session should have activity ids, so same session is reused when called again + // for the same activity. + + // TODO: activityToken should probably not be null, but we need to wait until the UI is + // triggering the call (for now it's trough 'adb shell cmd autofill start session' + if (activityToken == null) { + // Let's get top activities from all visible stacks. + + // TODO: overload getTopVisibleActivities() to take userId, otherwise it could return + // activities for different users when a work profile app is displayed in another + // window (in a multi-window environment). + final List<IBinder> topActivities = LocalServices + .getService(ActivityManagerInternal.class).getTopVisibleActivities(); + if (DEBUG) + Slog.d(TAG, "Top activities (" + topActivities.size() + "): " + topActivities); + if (topActivities.isEmpty()) { + Slog.w(TAG, "Could not get top activity"); + return null; + } + activityToken = topActivities.get(0); + } + + synchronized (mLock) { + return startSessionLocked(args, flags, activityToken); + } + } + + // TODO: remove args and flags if not needed? + private String startSessionLocked(Bundle args, int flags, IBinder activityToken) { + + final String sessionToken = UUID.randomUUID().toString(); + + if (DEBUG) Slog.d(TAG, "Starting session for user " + mUser + + ": sessionToken=" + sessionToken + ", activityToken=" + activityToken); + + final AutoFillSession session = + new AutoFillSession(mService, mLock, sessionToken, activityToken); + session.startLocked(); + mSessions.put(sessionToken, session); + + return sessionToken; + } + + // TODO: need a way to automatically call it when the activity is destroyed. + boolean finishSessionLocked(String token) { + if (DEBUG) Slog.d(TAG, "Removing session " + token + " for user " + mUser); + final AutoFillSession session = mSessions.remove(token); + if (session != null) { + session.finishLocked(); + } + return session != null; + } + + void shutdownLocked() { + if (DEBUG) Slog.d(TAG, "shutdownLocked()"); + + try { + if (mService != null) { + mService.shutdown(); + } + } catch (RemoteException e) { + Slog.w(TAG, "RemoteException in shutdown", e); + } + + if (mBound) { + mContext.unbindService(mConnection); + mBound = false; + } + if (mValid) { + mContext.unregisterReceiver(mBroadcastReceiver); + } + } + + void dumpLocked(String prefix, PrintWriter pw) { + if (!mValid) { + pw.print(" NOT VALID: "); + if (mInfo == null) { + pw.println("no info"); + } else { + pw.println(mInfo.getParseError()); + } + return; + } + + pw.print(prefix); pw.print("mUser="); pw.println(mUser); + pw.print(prefix); pw.print("mComponent="); pw.println(mComponent.flattenToShortString()); + pw.print(prefix); pw.print("mBound="); pw.println(mBound); + pw.print(prefix); pw.print("mService="); pw.println(mService); + + if (DEBUG) { + // ServiceInfo dump is too noisy and redundant (it can be obtained through other dumps) + pw.print(prefix); pw.println("Service info:"); + mInfo.getServiceInfo().dump(new PrintWriterPrinter(pw), prefix + prefix); + } + + if (!dumpSessionsLocked(prefix, pw)) { + pw.print(prefix); pw.print("No active sessions for user "); pw.println(mUser); + } + } + + boolean dumpSessionsLocked(String prefix, PrintWriter pw) { + if (mSessions.isEmpty()) { + return false; + } + + pw.print(mSessions.size());pw.println(" active sessions:"); + final String sessionPrefix = prefix + prefix; + for (AutoFillSession session : mSessions.values()) { + pw.println(); + session.dumpLocked(sessionPrefix, pw); + } + return true; + } + + @Override + public String toString() { + return "[AutoFillManagerServiceImpl: user=" + mUser + + ", component=" + mComponent.flattenToShortString() + "]"; + } +} diff --git a/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceShellCommand.java b/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceShellCommand.java new file mode 100644 index 000000000000..4e08ed6c7653 --- /dev/null +++ b/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceShellCommand.java @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.autofill; + +import android.app.ActivityManager; +import android.os.RemoteException; +import android.os.ShellCommand; +import android.os.UserHandle; +import android.service.autofill.IAutoFillManagerService; + +import java.io.PrintWriter; + +public final class AutoFillManagerServiceShellCommand extends ShellCommand { + + private final IAutoFillManagerService.Stub mService; + + public AutoFillManagerServiceShellCommand(IAutoFillManagerService.Stub service) { + mService = service; + } + + @Override + public int onCommand(String cmd) { + if (cmd == null) { + return handleDefaultCommands(cmd); + } + final PrintWriter pw = getOutPrintWriter(); + try { + switch (cmd) { + case "start": + return runStart(pw); + case "finish": + return runFinish(pw); + default: + return handleDefaultCommands(cmd); + } + } catch (RemoteException e) { + pw.println("error: " + e); + } + return -1; + } + + @Override + public void onHelp() { + try (final PrintWriter pw = getOutPrintWriter();) { + pw.println("AutoFill Service (autofill) commands:"); + pw.println(" help"); + pw.println(" Prints this help text."); + pw.println(""); + pw.println(" start session [--user USER_ID]"); + pw.println(" Starts an auto-fill session. " + + "Prints 'token:SESSION_TOKEN if successful, or error message"); + pw.println(""); + pw.println(" finish session <TOKEN> [--user USER_ID]"); + pw.println(" Finishes a session with the given TOKEN. " + + "Prints empty string if successful, or error message."); + pw.println(""); + } + } + + private int runStart(PrintWriter pw) throws RemoteException { + final String type = getNextArg(); + if (type == null) { + pw.println("Error: didn't specify type of data to start"); + return -1; + } + switch (type) { + case "session": + return startAutoFillSession(pw); + } + pw.println("Error: unknown start type '" + type + "'"); + return -1; + } + + private int runFinish(PrintWriter pw) throws RemoteException { + final String type = getNextArg(); + if (type == null) { + pw.println("Error: didn't specify type of data to finish"); + return -1; + } + switch (type) { + case "session": + return finishAutoFillSession(pw); + } + pw.println("Error: unknown finish type '" + type + "'"); + return -1; + } + + private int startAutoFillSession(PrintWriter pw) throws RemoteException { + final int userId = getUserIdFromArgs(); + final String token = mService.startSession(userId, null, 0, null); + pw.print("token:"); pw.println(token); + return 0; + } + + private int finishAutoFillSession(PrintWriter pw) throws RemoteException { + final String token = getNextArgRequired(); + final int userId = getUserIdFromArgs(); + + boolean finished = mService.finishSession(userId, token); + if (!finished) { + pw.println("No such session"); + return 1; + } + return 0; + } + + private int getUserIdFromArgs() { + if ("--user".equals(getNextArg())) { + return UserHandle.parseUserArg(getNextArgRequired()); + } + return ActivityManager.getCurrentUser(); + } +} diff --git a/services/autofill/java/com/android/server/autofill/AutoFillSession.java b/services/autofill/java/com/android/server/autofill/AutoFillSession.java new file mode 100644 index 000000000000..44637c3f5f46 --- /dev/null +++ b/services/autofill/java/com/android/server/autofill/AutoFillSession.java @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.autofill; + +import android.app.ActivityManager; +import android.app.ActivityManagerNative; +import android.app.IActivityManager; +import android.app.assist.AssistStructure; +import android.os.Bundle; +import android.os.IBinder; +import android.os.RemoteException; +import android.service.autofill.AutoFillService; +import android.service.autofill.IAutoFillService; +import android.service.voice.VoiceInteractionSession; +import android.util.Slog; + +import com.android.internal.annotations.GuardedBy; +import com.android.internal.os.IResultReceiver; + +import java.io.PrintWriter; + +/** + * An auto-fill session between the system's {@link AutoFillManagerServiceImpl} and the provider's + * {@link AutoFillService} implementation. + */ +final class AutoFillSession { + + private static final String TAG = "AutoFillSession"; + + private static final boolean FOCUSED = true; + private static final boolean NEW_SESSION_ID = true; + + private final IAutoFillService mService; + private final String mSessionToken; + private final IBinder mActivityToken; + private final Object mLock; + private final IActivityManager mAm; + + private final IResultReceiver mAssistReceiver = new IResultReceiver.Stub() { + @Override + public void send(int resultCode, Bundle resultData) throws RemoteException { + synchronized (mLock) { + mPendingResponse = false; + mAssistResponse = resultData; + deliverSessionDataLocked(); + } + } + }; + + // Assist data is filled asynchronously. + @GuardedBy("mLock") + private Bundle mAssistResponse; + @GuardedBy("mLock") + private boolean mPendingResponse; + + AutoFillSession(IAutoFillService service, Object lock, String sessionToken, + IBinder activityToken) { + mService = service; + mSessionToken = sessionToken; + mActivityToken = activityToken; + mLock = lock; + mAm = ActivityManagerNative.getDefault(); + } + + void startLocked() { + /* + * TODO: apply security checks below: + * - checks if disabled by secure settings / device policy + * - log operation using noteOp() + * - check flags + * - display disclosure if needed + */ + mAssistResponse = null; + mPendingResponse = true; + try { + // TODO: add MetricsLogger call + if (!mAm.requestAssistContextExtras(ActivityManager.ASSIST_CONTEXT_FULL, + mAssistReceiver, (Bundle) null, mActivityToken, FOCUSED, NEW_SESSION_ID)) { + mPendingResponse = false; + Slog.w(TAG, "requestAssistContextExtras() rejected"); + } + } catch (RemoteException e) { + // Should happen, it's a local call. + } + } + + void finishLocked() { + try { + mService.finishSession(mSessionToken); + } catch (RemoteException e) { + Slog.e(TAG, "auto-fill service failed to finish session " + mSessionToken, e); + } + } + + private void deliverSessionDataLocked() { + if (mAssistResponse == null) { + Slog.w(TAG, "No assist data for session " + mSessionToken); + return; + } + + final Bundle assistData = mAssistResponse.getBundle(VoiceInteractionSession.KEY_DATA); + final AssistStructure structure = + mAssistResponse.getParcelable(VoiceInteractionSession.KEY_STRUCTURE); + try { + mService.newSession(mSessionToken, assistData, 0, structure); + } catch (RemoteException e) { + Slog.e(TAG, "auto-fill service failed to start session " + mSessionToken, e); + } finally { + mPendingResponse = false; + // We could set mAssistResponse to null here, but we don't so it's shown on dump() + } + } + + void dumpLocked(String prefix, PrintWriter pw) { + pw.print(prefix); pw.print("mSessionToken="); pw.println(mSessionToken); + pw.print(prefix); pw.print("mActivityToken="); pw.println(mActivityToken); + pw.print(prefix); pw.print("mPendingResponse="); pw.println(mPendingResponse); + pw.print(prefix); pw.print("mAssistResponse="); pw.println(mAssistResponse); + } + +} diff --git a/services/core/Android.mk b/services/core/Android.mk index 11586eedfee4..88a83855bbb0 100644 --- a/services/core/Android.mk +++ b/services/core/Android.mk @@ -19,8 +19,9 @@ LOCAL_AIDL_INCLUDES += \ LOCAL_JAVA_LIBRARIES := \ services.net \ telephony-common \ + android.hardware.light@2.0-java \ android.hardware.power@1.0-java \ - android.hardware.light@2.0-java + android.hardware.tv.cec@1.0-java LOCAL_STATIC_JAVA_LIBRARIES := tzdata_update diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java index 8e01e9eae376..82897fb40c50 100644 --- a/services/core/java/com/android/server/AlarmManagerService.java +++ b/services/core/java/com/android/server/AlarmManagerService.java @@ -938,7 +938,7 @@ class AlarmManagerService extends SystemService { try { ActivityManagerNative.getDefault().registerUidObserver(new UidObserver(), - ActivityManager.UID_OBSERVER_IDLE, null); + ActivityManager.UID_OBSERVER_IDLE, ActivityManager.PROCESS_STATE_UNKNOWN, null); } catch (RemoteException e) { // ignored; both services live in system_server } diff --git a/services/core/java/com/android/server/GestureLauncherService.java b/services/core/java/com/android/server/GestureLauncherService.java index 553cb071613b..830a6ed23f9c 100644 --- a/services/core/java/com/android/server/GestureLauncherService.java +++ b/services/core/java/com/android/server/GestureLauncherService.java @@ -40,7 +40,7 @@ import android.util.Slog; import android.view.KeyEvent; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.server.statusbar.StatusBarManagerInternal; /** diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java index a2207b259123..dd342c523e75 100644 --- a/services/core/java/com/android/server/LockSettingsService.java +++ b/services/core/java/com/android/server/LockSettingsService.java @@ -49,6 +49,8 @@ import android.os.IProgressListener; import android.os.Parcel; import android.os.Process; import android.os.RemoteException; +import android.os.ResultReceiver; +import android.os.ShellCallback; import android.os.storage.IMountService; import android.os.storage.StorageManager; import android.os.ServiceManager; @@ -79,6 +81,7 @@ import com.android.server.LockSettingsStorage.CredentialHash; import libcore.util.HexEncoding; import java.io.ByteArrayOutputStream; +import java.io.FileDescriptor; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -1585,6 +1588,31 @@ public class LockSettingsService extends ILockSettings.Stub { return mStrongAuthTracker.getStrongAuthForUser(userId); } + private boolean isCallerShell() { + final int callingUid = Binder.getCallingUid(); + return callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID; + } + + private void enforceShell() { + if (!isCallerShell()) { + throw new SecurityException("Caller must be shell"); + } + } + + @Override + public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, + String[] args, ShellCallback callback, ResultReceiver resultReceiver) + throws RemoteException { + enforceShell(); + final long origId = Binder.clearCallingIdentity(); + try { + (new LockSettingsShellCommand(mContext, new LockPatternUtils(mContext))).exec( + this, in, out, err, args, callback, resultReceiver); + } finally { + Binder.restoreCallingIdentity(origId); + } + } + private static final String[] VALID_SETTINGS = new String[] { LockPatternUtils.LOCKOUT_PERMANENT_KEY, LockPatternUtils.LOCKOUT_ATTEMPT_DEADLINE, diff --git a/services/core/java/com/android/server/LockSettingsShellCommand.java b/services/core/java/com/android/server/LockSettingsShellCommand.java new file mode 100644 index 000000000000..0efdd510459a --- /dev/null +++ b/services/core/java/com/android/server/LockSettingsShellCommand.java @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.server; + +import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC; +import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC; +import static com.android.internal.widget.LockPatternUtils.stringToPattern; + +import android.app.ActivityManagerNative; +import android.content.Context; +import android.os.Binder; +import android.os.Process; +import android.os.RemoteException; +import android.os.ShellCommand; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.widget.LockPatternUtils; +import com.android.internal.widget.LockPatternUtils.RequestThrottledException; + +class LockSettingsShellCommand extends ShellCommand { + + private static final String COMMAND_SET_PATTERN = "set-pattern"; + private static final String COMMAND_SET_PIN = "set-pin"; + private static final String COMMAND_SET_PASSWORD = "set-password"; + private static final String COMMAND_CLEAR = "clear"; + + private int mCurrentUserId; + private final LockPatternUtils mLockPatternUtils; + private final Context mContext; + private String mOld = ""; + private String mNew = ""; + + LockSettingsShellCommand(Context context, LockPatternUtils lockPatternUtils) { + mContext = context; + mLockPatternUtils = lockPatternUtils; + } + + @Override + public int onCommand(String cmd) { + try { + mCurrentUserId = ActivityManagerNative.getDefault().getCurrentUser().id; + + parseArgs(); + if (!checkCredential()) { + return -1; + } + switch (cmd) { + case COMMAND_SET_PATTERN: + runSetPattern(); + break; + case COMMAND_SET_PASSWORD: + runSetPassword(); + break; + case COMMAND_SET_PIN: + runSetPin(); + break; + case COMMAND_CLEAR: + runClear(); + break; + default: + getErrPrintWriter().println("Unknown command: " + cmd); + break; + } + return 0; + } catch (Exception e) { + getErrPrintWriter().println("Error while executing command: " + e); + return -1; + } + } + + @Override + public void onHelp() { + } + + private void parseArgs() { + String opt; + while ((opt = getNextOption()) != null) { + if ("--old".equals(opt)) { + mOld = getNextArgRequired(); + } else { + getErrPrintWriter().println("Unknown option: " + opt); + throw new IllegalArgumentException(); + } + } + mNew = getNextArg(); + } + + private void runSetPattern() throws RemoteException { + mLockPatternUtils.saveLockPattern(stringToPattern(mNew), mOld, mCurrentUserId); + getOutPrintWriter().println("Pattern set to '" + mNew + "'"); + } + + private void runSetPassword() throws RemoteException { + mLockPatternUtils.saveLockPassword(mNew, mOld, PASSWORD_QUALITY_ALPHABETIC, mCurrentUserId); + getOutPrintWriter().println("Password set to '" + mNew + "'"); + } + + private void runSetPin() throws RemoteException { + mLockPatternUtils.saveLockPassword(mNew, mOld, PASSWORD_QUALITY_NUMERIC, mCurrentUserId); + getOutPrintWriter().println("Pin set to '" + mNew + "'"); + } + + private void runClear() throws RemoteException { + mLockPatternUtils.clearLock(mCurrentUserId); + getOutPrintWriter().println("Lock credential cleared"); + } + + private boolean checkCredential() throws RemoteException, RequestThrottledException { + final boolean havePassword = mLockPatternUtils.isLockPasswordEnabled(mCurrentUserId); + final boolean havePattern = mLockPatternUtils.isLockPatternEnabled(mCurrentUserId); + if (havePassword || havePattern) { + boolean result; + if (havePassword) { + result = mLockPatternUtils.checkPassword(mOld, mCurrentUserId); + } else { + result = mLockPatternUtils.checkPattern(stringToPattern(mOld), + mCurrentUserId); + } + if (result) { + return true; + } else { + getOutPrintWriter().println("Old password '" + mOld + "' didn't match"); + return false; + } + } else { + return true; + } + } +} diff --git a/services/core/java/com/android/server/PinnerService.java b/services/core/java/com/android/server/PinnerService.java index 356ccb3596a9..fa5a52c712cd 100644 --- a/services/core/java/com/android/server/PinnerService.java +++ b/services/core/java/com/android/server/PinnerService.java @@ -63,7 +63,7 @@ public final class PinnerService extends SystemService { private BinderService mBinderService; - private final long MAX_CAMERA_PIN_SIZE = 50 * (1 << 20); //50MB max + private final long MAX_CAMERA_PIN_SIZE = 80 * (1 << 20); //80MB max private PinnerHandler mPinnerHandler = null; @@ -192,6 +192,9 @@ public final class PinnerService extends SystemService { if (isResolverActivity(cameraResolveInfo.activityInfo)) { + if (DEBUG) { + Slog.v(TAG, "cameraIntent returned resolverActivity"); + } return null; } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index db5a388ca9bc..b048fb40e557 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -22,9 +22,6 @@ import android.app.ContentProviderHolder; import android.app.IActivityManager; import android.app.WaitResult; import android.os.IDeviceIdentifiersPolicyService; -import android.util.Size; -import android.util.TypedValue; -import android.view.DisplayInfo; import com.android.internal.telephony.TelephonyIntents; import com.google.android.collect.Lists; import com.google.android.collect.Maps; @@ -80,7 +77,6 @@ import android.app.ActivityManager; import android.app.ActivityManager.RunningTaskInfo; import android.app.ActivityManager.StackId; import android.app.ActivityManager.StackInfo; -import android.app.ActivityManager.TaskDescription; import android.app.ActivityManager.TaskThumbnailInfo; import android.app.ActivityManagerInternal; import android.app.ActivityManagerInternal.SleepToken; @@ -221,6 +217,7 @@ import android.util.Pair; import android.util.PrintWriterPrinter; import android.util.Slog; import android.util.SparseArray; +import android.util.SparseIntArray; import android.util.TimeUtils; import android.util.Xml; import android.view.Gravity; @@ -1398,6 +1395,27 @@ public class ActivityManagerService extends IActivityManager.Stub boolean foregroundActivities; } + static final class UidObserverRegistration { + final int uid; + final String pkg; + final int which; + final int cutpoint; + + final SparseIntArray lastProcStates; + + UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) { + uid = _uid; + pkg = _pkg; + which = _which; + cutpoint = _cutpoint; + if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) { + lastProcStates = new SparseIntArray(); + } else { + lastProcStates = null; + } + } + } + final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>(); ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; @@ -4106,7 +4124,8 @@ public class ActivityManagerService extends IActivityManager.Stub while (i > 0) { i--; final IUidObserver observer = mUidObservers.getBroadcastItem(i); - final int which = (Integer)mUidObservers.getBroadcastCookie(i); + final UidObserverRegistration reg = (UidObserverRegistration) + mUidObservers.getBroadcastCookie(i); if (observer != null) { try { for (int j=0; j<N; j++) { @@ -4123,7 +4142,7 @@ public class ActivityManagerService extends IActivityManager.Stub } if (change == UidRecord.CHANGE_IDLE || change == UidRecord.CHANGE_GONE_IDLE) { - if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) { + if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) { if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, "UID idle uid=" + item.uid); observer.onUidIdle(item.uid); @@ -4134,7 +4153,7 @@ public class ActivityManagerService extends IActivityManager.Stub } } } else if (change == UidRecord.CHANGE_ACTIVE) { - if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) { + if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) { if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, "UID active uid=" + item.uid); observer.onUidActive(item.uid); @@ -4145,22 +4164,43 @@ public class ActivityManagerService extends IActivityManager.Stub } if (change == UidRecord.CHANGE_GONE || change == UidRecord.CHANGE_GONE_IDLE) { - if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) { + if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) { if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, "UID gone uid=" + item.uid); observer.onUidGone(item.uid); } + if (reg.lastProcStates != null) { + reg.lastProcStates.delete(item.uid); + } if (VALIDATE_UID_STATES && i == 0) { if (validateUid != null) { mValidateUids.remove(item.uid); } } } else { - if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) { + if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) { if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, "UID CHANGED uid=" + item.uid + ": " + item.processState); - observer.onUidStateChanged(item.uid, item.processState); + boolean doReport = true; + if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) { + final int lastState = reg.lastProcStates.get(item.uid, + ActivityManager.PROCESS_STATE_UNKNOWN); + if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) { + final boolean lastAboveCut = lastState <= reg.cutpoint; + final boolean newAboveCut = item.processState <= reg.cutpoint; + doReport = lastAboveCut != newAboveCut; + } else { + doReport = item.processState + != ActivityManager.PROCESS_STATE_NONEXISTENT; + } + } + if (doReport) { + if (reg.lastProcStates != null) { + reg.lastProcStates.put(item.uid, item.processState); + } + observer.onUidStateChanged(item.uid, item.processState); + } } if (VALIDATE_UID_STATES && i == 0) { validateUid.curProcState = validateUid.setProcState @@ -12246,13 +12286,15 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override - public void registerUidObserver(IUidObserver observer, int which, String callingPackage) { + public void registerUidObserver(IUidObserver observer, int which, int cutpoint, + String callingPackage) { if (!hasUsageStatsPermission(callingPackage)) { enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS, "registerUidObserver"); } synchronized (this) { - mUidObservers.register(observer, which); + mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(), + callingPackage, which, cutpoint)); } } @@ -12898,7 +12940,7 @@ public class ActivityManagerService extends IActivityManager.Stub } } } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME - && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) { + && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) { proc.notCachedSinceIdle = true; proc.initialIdlePss = 0; proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true, @@ -14333,7 +14375,7 @@ public class ActivityManagerService extends IActivityManager.Stub pw.print(" "); for (int i=0; i<ass.mStateTimes.length; i++) { long amt = ass.mStateTimes[i]; - if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) { + if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) { amt += now - ass.mLastStateUptime; } if (amt != 0) { @@ -14342,7 +14384,7 @@ public class ActivityManagerService extends IActivityManager.Stub i + ActivityManager.MIN_PROCESS_STATE)); pw.print("="); TimeUtils.formatDuration(amt, pw); - if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) { + if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) { pw.print("*"); } } @@ -14614,6 +14656,43 @@ public class ActivityManagerService extends IActivityManager.Stub pw.print(mode); pw.println(); } } + final int NI = mUidObservers.getRegisteredCallbackCount(); + boolean printed = false; + for (int i=0; i<NI; i++) { + final UidObserverRegistration reg = (UidObserverRegistration) + mUidObservers.getRegisteredCallbackCookie(i); + if (dumpPackage == null || dumpPackage.equals(reg.pkg)) { + if (!printed) { + pw.println(" mUidObservers:"); + printed = true; + } + pw.print(" "); UserHandle.formatUid(pw, reg.uid); + pw.print(" "); pw.print(reg.pkg); pw.print(":"); + if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) { + pw.print(" IDLE"); + } + if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) { + pw.print(" ACT" ); + } + if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) { + pw.print(" GONE"); + } + if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) { + pw.print(" STATE"); + pw.print(" (cut="); pw.print(reg.cutpoint); + pw.print(")"); + } + pw.println(); + if (reg.lastProcStates != null) { + final int NJ = reg.lastProcStates.size(); + for (int j=0; j<NJ; j++) { + pw.print(" Last "); + UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j)); + pw.print(": "); pw.println(reg.lastProcStates.valueAt(j)); + } + } + } + } } if (dumpPackage == null) { pw.println(" mWakefulness=" diff --git a/services/core/java/com/android/server/am/ActivityMetricsLogger.java b/services/core/java/com/android/server/am/ActivityMetricsLogger.java index be8f21d997a5..facfeb67b653 100644 --- a/services/core/java/com/android/server/am/ActivityMetricsLogger.java +++ b/services/core/java/com/android/server/am/ActivityMetricsLogger.java @@ -16,7 +16,7 @@ import android.os.SystemClock; import android.util.Slog; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import java.util.ArrayList; diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java index e4ec16994507..691d6b9cd628 100644 --- a/services/core/java/com/android/server/am/ActivityStarter.java +++ b/services/core/java/com/android/server/am/ActivityStarter.java @@ -458,9 +458,12 @@ class ActivityStarter { // Instead, launch the ephemeral installer. Once the installer is finished, it // starts either the intent we resolved here [on install error] or the ephemeral // app [on install success]. - if (rInfo != null && rInfo.ephemeralResolveInfo != null) { + if (rInfo != null && rInfo.ephemeralIntentInfo != null) { + final String packageName = + rInfo.ephemeralIntentInfo.getEphemeralResolveInfo().getPackageName(); + final String splitName = rInfo.ephemeralIntentInfo.getSplitName(); intent = buildEphemeralInstallerIntent(intent, ephemeralIntent, - rInfo.ephemeralResolveInfo.getPackageName(), callingPackage, resolvedType, + packageName, splitName, callingPackage, resolvedType, userId); resolvedType = null; callingUid = realCallingUid; @@ -524,7 +527,8 @@ class ActivityStarter { * Builds and returns an intent to launch the ephemeral installer. */ private Intent buildEphemeralInstallerIntent(Intent launchIntent, Intent origIntent, - String ephemeralPackage, String callingPackage, String resolvedType, int userId) { + String ephemeralPackageName, String ephemeralSplitName, String callingPackage, + String resolvedType, int userId) { final Intent nonEphemeralIntent = new Intent(origIntent); nonEphemeralIntent.setFlags(nonEphemeralIntent.getFlags() | Intent.FLAG_IGNORE_EPHEMERAL); // Intent that is launched if the ephemeral package couldn't be installed @@ -540,7 +544,7 @@ class ActivityStarter { if (USE_DEFAULT_EPHEMERAL_LAUNCHER) { // Force the intent to be directed to the ephemeral package ephemeralIntent = new Intent(origIntent); - ephemeralIntent.setPackage(ephemeralPackage); + ephemeralIntent.setPackage(ephemeralPackageName); } else { // Success intent goes back to the installer ephemeralIntent = new Intent(launchIntent); @@ -564,7 +568,8 @@ class ActivityStarter { | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); - intent.putExtra(Intent.EXTRA_PACKAGE_NAME, ephemeralPackage); + intent.putExtra(Intent.EXTRA_PACKAGE_NAME, ephemeralPackageName); + intent.putExtra(Intent.EXTRA_SPLIT_NAME, ephemeralSplitName); intent.putExtra(Intent.EXTRA_EPHEMERAL_FAILURE, new IntentSender(failureIntentTarget)); intent.putExtra(Intent.EXTRA_EPHEMERAL_SUCCESS, new IntentSender(successIntentTarget)); // TODO: Remove when the platform has fully implemented ephemeral apps @@ -1199,6 +1204,14 @@ class ActivityStarter { // since the app transition will not be triggered through the resume channel. mWindowManager.executeAppTransition(); } else { + // If the target stack was not previously focusable (previous top running activity + // on that stack was not visible) then any prior calls to move the stack to the + // will not update the focused stack. If starting the new activity now allows the + // task stack to be focusable, then ensure that we now update the focused stack + // accordingly. + if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) { + mTargetStack.moveToFront("startActivityUnchecked"); + } mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity, mOptions); } diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java index c19a5710666b..7a122e6e6d20 100644 --- a/services/core/java/com/android/server/am/AppErrors.java +++ b/services/core/java/com/android/server/am/AppErrors.java @@ -18,7 +18,7 @@ package com.android.server.am; import com.android.internal.app.ProcessMap; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto; +import com.android.internal.logging.nano.MetricsProto; import com.android.internal.os.ProcessCpuTracker; import com.android.server.Watchdog; diff --git a/services/core/java/com/android/server/am/AppNotRespondingDialog.java b/services/core/java/com/android/server/am/AppNotRespondingDialog.java index c6befd7fbb7a..9e297255c2f9 100644 --- a/services/core/java/com/android/server/am/AppNotRespondingDialog.java +++ b/services/core/java/com/android/server/am/AppNotRespondingDialog.java @@ -17,7 +17,7 @@ package com.android.server.am; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto; +import com.android.internal.logging.nano.MetricsProto; import android.content.ActivityNotFoundException; import android.content.Context; diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index 2b00f868ea70..1322ecf89baf 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -371,9 +371,6 @@ final class ProcessList { public static String makeProcStateString(int curProcState) { String procState; switch (curProcState) { - case -1: - procState = "N "; - break; case ActivityManager.PROCESS_STATE_PERSISTENT: procState = "P "; break; @@ -425,6 +422,9 @@ final class ProcessList { case ActivityManager.PROCESS_STATE_CACHED_EMPTY: procState = "CE"; break; + case ActivityManager.PROCESS_STATE_NONEXISTENT: + procState = "N "; + break; default: procState = "??"; break; diff --git a/services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java b/services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java index f1d01e06911a..372b2d8e566e 100644 --- a/services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java +++ b/services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java @@ -29,14 +29,14 @@ import android.net.metrics.NetworkEvent; import android.net.metrics.RaEvent; import android.net.metrics.ValidationProbeEvent; import android.os.Parcelable; -import com.android.server.connectivity.metrics.IpConnectivityLogClass; +import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass; import java.io.IOException; import java.util.ArrayList; import java.util.List; -import static com.android.server.connectivity.metrics.IpConnectivityLogClass.IpConnectivityEvent; -import static com.android.server.connectivity.metrics.IpConnectivityLogClass.IpConnectivityLog; -import static com.android.server.connectivity.metrics.IpConnectivityLogClass.NetworkId; +import static com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityEvent; +import static com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityLog; +import static com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.NetworkId; /** {@hide} */ final public class IpConnectivityEventBuilder { @@ -136,96 +136,107 @@ final public class IpConnectivityEventBuilder { } private static void setDhcpErrorEvent(IpConnectivityEvent out, DhcpErrorEvent in) { - out.dhcpEvent = new IpConnectivityLogClass.DHCPEvent(); - out.dhcpEvent.ifName = in.ifName; - out.dhcpEvent.errorCode = in.errorCode; + IpConnectivityLogClass.DHCPEvent dhcpEvent = new IpConnectivityLogClass.DHCPEvent(); + dhcpEvent.ifName = in.ifName; + dhcpEvent.setErrorCode(in.errorCode); + out.setDhcpEvent(dhcpEvent); } private static void setDhcpClientEvent(IpConnectivityEvent out, DhcpClientEvent in) { - out.dhcpEvent = new IpConnectivityLogClass.DHCPEvent(); - out.dhcpEvent.ifName = in.ifName; - out.dhcpEvent.stateTransition = in.msg; - out.dhcpEvent.durationMs = in.durationMs; + IpConnectivityLogClass.DHCPEvent dhcpEvent = new IpConnectivityLogClass.DHCPEvent(); + dhcpEvent.ifName = in.ifName; + dhcpEvent.setStateTransition(in.msg); + dhcpEvent.durationMs = in.durationMs; + out.setDhcpEvent(dhcpEvent); } private static void setDnsEvent(IpConnectivityEvent out, DnsEvent in) { - out.dnsLookupBatch = new IpConnectivityLogClass.DNSLookupBatch(); - out.dnsLookupBatch.networkId = netIdOf(in.netId); - out.dnsLookupBatch.eventTypes = bytesToInts(in.eventTypes); - out.dnsLookupBatch.returnCodes = bytesToInts(in.returnCodes); - out.dnsLookupBatch.latenciesMs = in.latenciesMs; + IpConnectivityLogClass.DNSLookupBatch dnsLookupBatch = new IpConnectivityLogClass.DNSLookupBatch(); + dnsLookupBatch.networkId = netIdOf(in.netId); + dnsLookupBatch.eventTypes = bytesToInts(in.eventTypes); + dnsLookupBatch.returnCodes = bytesToInts(in.returnCodes); + dnsLookupBatch.latenciesMs = in.latenciesMs; + out.setDnsLookupBatch(dnsLookupBatch); } private static void setIpManagerEvent(IpConnectivityEvent out, IpManagerEvent in) { - out.ipProvisioningEvent = new IpConnectivityLogClass.IpProvisioningEvent(); - out.ipProvisioningEvent.ifName = in.ifName; - out.ipProvisioningEvent.eventType = in.eventType; - out.ipProvisioningEvent.latencyMs = (int) in.durationMs; + IpConnectivityLogClass.IpProvisioningEvent ipProvisioningEvent = new IpConnectivityLogClass.IpProvisioningEvent(); + ipProvisioningEvent.ifName = in.ifName; + ipProvisioningEvent.eventType = in.eventType; + ipProvisioningEvent.latencyMs = (int) in.durationMs; + out.setIpProvisioningEvent(ipProvisioningEvent); } private static void setIpReachabilityEvent(IpConnectivityEvent out, IpReachabilityEvent in) { - out.ipReachabilityEvent = new IpConnectivityLogClass.IpReachabilityEvent(); - out.ipReachabilityEvent.ifName = in.ifName; - out.ipReachabilityEvent.eventType = in.eventType; + IpConnectivityLogClass.IpReachabilityEvent ipReachabilityEvent = new IpConnectivityLogClass.IpReachabilityEvent(); + ipReachabilityEvent.ifName = in.ifName; + ipReachabilityEvent.eventType = in.eventType; + out.setIpReachabilityEvent(ipReachabilityEvent); } private static void setDefaultNetworkEvent(IpConnectivityEvent out, DefaultNetworkEvent in) { - out.defaultNetworkEvent = new IpConnectivityLogClass.DefaultNetworkEvent(); - out.defaultNetworkEvent.networkId = netIdOf(in.netId); - out.defaultNetworkEvent.previousNetworkId = netIdOf(in.prevNetId); - out.defaultNetworkEvent.transportTypes = in.transportTypes; - out.defaultNetworkEvent.previousNetworkIpSupport = ipSupportOf(in); + IpConnectivityLogClass.DefaultNetworkEvent defaultNetworkEvent = new IpConnectivityLogClass.DefaultNetworkEvent(); + defaultNetworkEvent.networkId = netIdOf(in.netId); + defaultNetworkEvent.previousNetworkId = netIdOf(in.prevNetId); + defaultNetworkEvent.transportTypes = in.transportTypes; + defaultNetworkEvent.previousNetworkIpSupport = ipSupportOf(in); + out.setDefaultNetworkEvent(defaultNetworkEvent); } private static void setNetworkEvent(IpConnectivityEvent out, NetworkEvent in) { - out.networkEvent = new IpConnectivityLogClass.NetworkEvent(); - out.networkEvent.networkId = netIdOf(in.netId); - out.networkEvent.eventType = in.eventType; - out.networkEvent.latencyMs = (int) in.durationMs; + IpConnectivityLogClass.NetworkEvent networkEvent = new IpConnectivityLogClass.NetworkEvent(); + networkEvent.networkId = netIdOf(in.netId); + networkEvent.eventType = in.eventType; + networkEvent.latencyMs = (int) in.durationMs; + out.setNetworkEvent(networkEvent); } private static void setValidationProbeEvent(IpConnectivityEvent out, ValidationProbeEvent in) { - out.validationProbeEvent = new IpConnectivityLogClass.ValidationProbeEvent(); - out.validationProbeEvent.networkId = netIdOf(in.netId); - out.validationProbeEvent.latencyMs = (int) in.durationMs; - out.validationProbeEvent.probeType = in.probeType; - out.validationProbeEvent.probeResult = in.returnCode; + IpConnectivityLogClass.ValidationProbeEvent validationProbeEvent = new IpConnectivityLogClass.ValidationProbeEvent(); + validationProbeEvent.networkId = netIdOf(in.netId); + validationProbeEvent.latencyMs = (int) in.durationMs; + validationProbeEvent.probeType = in.probeType; + validationProbeEvent.probeResult = in.returnCode; + out.setValidationProbeEvent(validationProbeEvent); } private static void setApfProgramEvent(IpConnectivityEvent out, ApfProgramEvent in) { - out.apfProgramEvent = new IpConnectivityLogClass.ApfProgramEvent(); - out.apfProgramEvent.lifetime = in.lifetime; - out.apfProgramEvent.filteredRas = in.filteredRas; - out.apfProgramEvent.currentRas = in.currentRas; - out.apfProgramEvent.programLength = in.programLength; + IpConnectivityLogClass.ApfProgramEvent apfProgramEvent = new IpConnectivityLogClass.ApfProgramEvent(); + apfProgramEvent.lifetime = in.lifetime; + apfProgramEvent.filteredRas = in.filteredRas; + apfProgramEvent.currentRas = in.currentRas; + apfProgramEvent.programLength = in.programLength; if (isBitSet(in.flags, ApfProgramEvent.FLAG_MULTICAST_FILTER_ON)) { - out.apfProgramEvent.dropMulticast = true; + apfProgramEvent.dropMulticast = true; } if (isBitSet(in.flags, ApfProgramEvent.FLAG_HAS_IPV4_ADDRESS)) { - out.apfProgramEvent.hasIpv4Addr = true; + apfProgramEvent.hasIpv4Addr = true; } + out.setApfProgramEvent(apfProgramEvent); } private static void setApfStats(IpConnectivityEvent out, ApfStats in) { - out.apfStatistics = new IpConnectivityLogClass.ApfStatistics(); - out.apfStatistics.durationMs = in.durationMs; - out.apfStatistics.receivedRas = in.receivedRas; - out.apfStatistics.matchingRas = in.matchingRas; - out.apfStatistics.droppedRas = in.droppedRas; - out.apfStatistics.zeroLifetimeRas = in.zeroLifetimeRas; - out.apfStatistics.parseErrors = in.parseErrors; - out.apfStatistics.programUpdates = in.programUpdates; - out.apfStatistics.maxProgramSize = in.maxProgramSize; + IpConnectivityLogClass.ApfStatistics apfStatistics = new IpConnectivityLogClass.ApfStatistics(); + apfStatistics.durationMs = in.durationMs; + apfStatistics.receivedRas = in.receivedRas; + apfStatistics.matchingRas = in.matchingRas; + apfStatistics.droppedRas = in.droppedRas; + apfStatistics.zeroLifetimeRas = in.zeroLifetimeRas; + apfStatistics.parseErrors = in.parseErrors; + apfStatistics.programUpdates = in.programUpdates; + apfStatistics.maxProgramSize = in.maxProgramSize; + out.setApfStatistics(apfStatistics); } private static void setRaEvent(IpConnectivityEvent out, RaEvent in) { - out.raEvent = new IpConnectivityLogClass.RaEvent(); - out.raEvent.routerLifetime = in.routerLifetime; - out.raEvent.prefixValidLifetime = in.prefixValidLifetime; - out.raEvent.prefixPreferredLifetime = in.prefixPreferredLifetime; - out.raEvent.routeInfoLifetime = in.routeInfoLifetime; - out.raEvent.rdnssLifetime = in.rdnssLifetime; - out.raEvent.dnsslLifetime = in.dnsslLifetime; + IpConnectivityLogClass.RaEvent raEvent = new IpConnectivityLogClass.RaEvent(); + raEvent.routerLifetime = in.routerLifetime; + raEvent.prefixValidLifetime = in.prefixValidLifetime; + raEvent.prefixPreferredLifetime = in.prefixPreferredLifetime; + raEvent.routeInfoLifetime = in.routeInfoLifetime; + raEvent.rdnssLifetime = in.rdnssLifetime; + raEvent.dnsslLifetime = in.dnsslLifetime; + out.setRaEvent(raEvent); } private static int[] bytesToInts(byte[] in) { diff --git a/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java b/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java index 641c62fe2a4d..42f439c242f8 100644 --- a/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java +++ b/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java @@ -42,7 +42,7 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.function.ToIntFunction; -import static com.android.server.connectivity.metrics.IpConnectivityLogClass.IpConnectivityEvent; +import static com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityEvent; /** {@hide} */ final public class IpConnectivityMetrics extends SystemService { diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 971989b21219..9c762cce7e0f 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -220,6 +220,11 @@ public final class DisplayManagerService extends SystemService { private final DisplayViewport mTempDefaultViewport = new DisplayViewport(); private final DisplayViewport mTempExternalTouchViewport = new DisplayViewport(); + // The default color mode for default displays. Overrides the usual + // Display.Display.COLOR_MODE_DEFAULT for displays with the + // DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY flag set. + private final int mDefaultDisplayDefaultColorMode; + // Temporary list of deferred work to perform when setting the display state. // Only used by requestDisplayState. The field is self-synchronized and only // intended for use inside of the requestGlobalDisplayStateInternal function. @@ -232,6 +237,8 @@ public final class DisplayManagerService extends SystemService { mUiHandler = UiThread.getHandler(); mDisplayAdapterListener = new DisplayAdapterListener(); mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false); + mDefaultDisplayDefaultColorMode = mContext.getResources().getInteger( + com.android.internal.R.integer.config_defaultDisplayDefaultColorMode); PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mGlobalDisplayBrightness = pm.getDefaultScreenBrightnessSetting(); @@ -703,6 +710,14 @@ public final class DisplayManagerService extends SystemService { } if (display != null && display.getPrimaryDisplayDeviceLocked() == device) { int colorMode = mPersistentDataStore.getColorMode(device); + if (colorMode == Display.COLOR_MODE_INVALID) { + if ((device.getDisplayDeviceInfoLocked().flags + & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) { + colorMode = mDefaultDisplayDefaultColorMode; + } else { + colorMode = Display.COLOR_MODE_DEFAULT; + } + } display.setRequestedColorModeLocked(colorMode); } scheduleTraversalLocked(false); @@ -1043,6 +1058,7 @@ public final class DisplayManagerService extends SystemService { pw.println(" mNextNonDefaultDisplayId=" + mNextNonDefaultDisplayId); pw.println(" mDefaultViewport=" + mDefaultViewport); pw.println(" mExternalTouchViewport=" + mExternalTouchViewport); + pw.println(" mDefaultDisplayDefaultColorMode=" + mDefaultDisplayDefaultColorMode); pw.println(" mSingleDisplayDemoMode=" + mSingleDisplayDemoMode); pw.println(" mWifiDisplayScanRequestCount=" + mWifiDisplayScanRequestCount); diff --git a/services/core/java/com/android/server/display/PersistentDataStore.java b/services/core/java/com/android/server/display/PersistentDataStore.java index 5616fb97bad7..47701b99860a 100644 --- a/services/core/java/com/android/server/display/PersistentDataStore.java +++ b/services/core/java/com/android/server/display/PersistentDataStore.java @@ -183,11 +183,11 @@ final class PersistentDataStore { public int getColorMode(DisplayDevice device) { if (!device.hasStableUniqueId()) { - return Display.COLOR_MODE_DEFAULT; + return Display.COLOR_MODE_INVALID; } DisplayState state = getDisplayState(device.getUniqueId(), false); if (state == null) { - return Display.COLOR_MODE_DEFAULT; + return Display.COLOR_MODE_INVALID; } return state.getColorMode(); } diff --git a/services/core/java/com/android/server/dreams/DreamController.java b/services/core/java/com/android/server/dreams/DreamController.java index 393199dd6183..fbad8dede87d 100644 --- a/services/core/java/com/android/server/dreams/DreamController.java +++ b/services/core/java/com/android/server/dreams/DreamController.java @@ -17,7 +17,7 @@ package com.android.server.dreams; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import android.content.ComponentName; import android.content.Context; diff --git a/services/core/java/com/android/server/fingerprint/AuthenticationClient.java b/services/core/java/com/android/server/fingerprint/AuthenticationClient.java index 5297589c4795..d65e25785e39 100644 --- a/services/core/java/com/android/server/fingerprint/AuthenticationClient.java +++ b/services/core/java/com/android/server/fingerprint/AuthenticationClient.java @@ -17,7 +17,7 @@ package com.android.server.fingerprint; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import android.content.Context; import android.hardware.fingerprint.Fingerprint; diff --git a/services/core/java/com/android/server/fingerprint/EnrollClient.java b/services/core/java/com/android/server/fingerprint/EnrollClient.java index 640a46fb656f..c70ca7f5b28b 100644 --- a/services/core/java/com/android/server/fingerprint/EnrollClient.java +++ b/services/core/java/com/android/server/fingerprint/EnrollClient.java @@ -25,7 +25,7 @@ import android.os.RemoteException; import android.util.Slog; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import java.util.Arrays; diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java index 603402e32bfb..a2a55e532ef4 100644 --- a/services/core/java/com/android/server/hdmi/Constants.java +++ b/services/core/java/com/android/server/hdmi/Constants.java @@ -188,12 +188,6 @@ final class Constants { static final int INVALID_PHYSICAL_ADDRESS = HdmiDeviceInfo.PATH_INVALID; static final int PATH_INTERNAL = HdmiDeviceInfo.PATH_INTERNAL; - // Send result codes. It should be consistent with hdmi_cec.h's send_message error code. - static final int SEND_RESULT_SUCCESS = 0; - static final int SEND_RESULT_NAK = 1; - static final int SEND_RESULT_BUSY = 2; - static final int SEND_RESULT_FAILURE = 3; - // Strategy for device polling. // Should use "OR(|) operation of POLL_STRATEGY_XXX and POLL_ITERATION_XXX. static final int POLL_STRATEGY_MASK = 0x3; // first and second bit. @@ -231,26 +225,7 @@ final class Constants { static final int RECORDING_TYPE_OWN_SOURCE = 4; // Definitions used for setOption(). These should be in sync with the definition - // in hardware/libhardware/include/hardware/{hdmi_cec.h,mhl.h}. - - // TV gets turned on by incoming <Text/Image View On>. enabled by default. - // If set to disabled, TV won't turn on automatically. - static final int OPTION_CEC_AUTO_WAKEUP = 1; - - // If set to disabled, all CEC commands are discarded. - static final int OPTION_CEC_ENABLE = 2; - - // If set to disabled, system service yields control of CEC to sub-microcontroller. - // If enabled, it takes the control back. - static final int OPTION_CEC_SERVICE_CONTROL = 3; - - // Put other devices to standby when TV goes to standby. enabled by default. - // If set to disabled, TV doesn't send <Standby> to other devices. - static final int OPTION_CEC_AUTO_DEVICE_OFF = 4; - - // Passes the language used in the system when updated. The value to use is the 3 byte - // code as defined in ISO/FDIS 639-2. - static final int OPTION_CEC_SET_LANGUAGE = 5; + // in hardware/libhardware/include/hardware/mhl.h. // If set to disabled, TV does not switch ports when mobile device is connected. static final int OPTION_MHL_INPUT_SWITCHING = 101; diff --git a/services/core/java/com/android/server/hdmi/DeviceSelectAction.java b/services/core/java/com/android/server/hdmi/DeviceSelectAction.java index 5a1d896c74a6..c684a56ec5d4 100644 --- a/services/core/java/com/android/server/hdmi/DeviceSelectAction.java +++ b/services/core/java/com/android/server/hdmi/DeviceSelectAction.java @@ -16,13 +16,13 @@ package com.android.server.hdmi; -import android.hardware.hdmi.HdmiDeviceInfo; import android.hardware.hdmi.HdmiControlManager; +import android.hardware.hdmi.HdmiDeviceInfo; import android.hardware.hdmi.HdmiTvClient; import android.hardware.hdmi.IHdmiControlCallback; +import android.hardware.tv.cec.V1_0.SendMessageResult; import android.os.RemoteException; import android.util.Slog; - import com.android.server.hdmi.HdmiControlService.SendMessageCallback; /** @@ -95,7 +95,7 @@ final class DeviceSelectAction extends HdmiCecFeatureAction { sendCommand(mGivePowerStatus, new SendMessageCallback() { @Override public void onSendCompleted(int error) { - if (error != Constants.SEND_RESULT_SUCCESS) { + if (error != SendMessageResult.SUCCESS) { invokeCallback(HdmiControlManager.RESULT_COMMUNICATION_FAILED); finish(); return; diff --git a/services/core/java/com/android/server/hdmi/HdmiCecController.java b/services/core/java/com/android/server/hdmi/HdmiCecController.java index 687aaa1f4b22..461a9b0636e4 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecController.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecController.java @@ -17,23 +17,23 @@ package com.android.server.hdmi; import android.hardware.hdmi.HdmiPortInfo; +import android.hardware.tv.cec.V1_0.Result; +import android.hardware.tv.cec.V1_0.SendMessageResult; import android.os.Handler; import android.os.Looper; import android.os.MessageQueue; import android.util.Slog; import android.util.SparseArray; - import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.Predicate; import com.android.server.hdmi.HdmiAnnotations.IoThreadOnly; import com.android.server.hdmi.HdmiAnnotations.ServiceThreadOnly; import com.android.server.hdmi.HdmiControlService.DevicePollingCallback; - -import libcore.util.EmptyArray; - import java.util.ArrayList; import java.util.LinkedList; import java.util.List; +import libcore.util.EmptyArray; +import sun.util.locale.LanguageTag; /** * Manages HDMI-CEC command and behaviors. It converts user's command into CEC command @@ -256,7 +256,7 @@ final class HdmiCecController { if (HdmiUtils.isValidAddress(newLogicalAddress)) { return nativeAddLogicalAddress(mNativePtr, newLogicalAddress); } else { - return -1; + return Result.FAILURE_INVALID_ARGS; } } @@ -320,13 +320,27 @@ final class HdmiCecController { * Set an option to CEC HAL. * * @param flag key of option - * @param value value of option + * @param enabled whether to enable/disable the given option. + */ + @ServiceThreadOnly + void setOption(int flag, boolean enabled) { + assertRunOnServiceThread(); + HdmiLogger.debug("setOption: [flag:%d, enabled:%b]", flag, enabled); + nativeSetOption(mNativePtr, flag, enabled); + } + + /** + * Informs CEC HAL about the current system language. + * + * @param language Three-letter code defined in ISO/FDIS 639-2. Must be lowercase letters. */ @ServiceThreadOnly - void setOption(int flag, int value) { + void setLanguage(String language) { assertRunOnServiceThread(); - HdmiLogger.debug("setOption: [flag:%d, value:%d]", flag, value); - nativeSetOption(mNativePtr, flag, value); + if (!LanguageTag.isLanguage(language)) { + return; + } + nativeSetLanguage(mNativePtr, language); } /** @@ -336,9 +350,9 @@ final class HdmiCecController { * @param enabled whether to enable/disable ARC */ @ServiceThreadOnly - void setAudioReturnChannel(int port, boolean enabled) { + void enableAudioReturnChannel(int port, boolean enabled) { assertRunOnServiceThread(); - nativeSetAudioReturnChannel(mNativePtr, port, enabled); + nativeEnableAudioReturnChannel(mNativePtr, port, enabled); } /** @@ -472,9 +486,9 @@ final class HdmiCecController { // <Polling Message> is a message which has empty body. int ret = nativeSendCecCommand(mNativePtr, sourceAddress, destinationAddress, EMPTY_BODY); - if (ret == Constants.SEND_RESULT_SUCCESS) { + if (ret == SendMessageResult.SUCCESS) { return true; - } else if (ret != Constants.SEND_RESULT_NAK) { + } else if (ret != SendMessageResult.NACK) { // Unusual failure HdmiLogger.warning("Failed to send a polling message(%d->%d) with return code %d", sourceAddress, destinationAddress, ret); @@ -572,17 +586,17 @@ final class HdmiCecController { HdmiLogger.debug("[S]:" + cecMessage); byte[] body = buildBody(cecMessage.getOpcode(), cecMessage.getParams()); int i = 0; - int errorCode = Constants.SEND_RESULT_SUCCESS; + int errorCode = SendMessageResult.SUCCESS; do { errorCode = nativeSendCecCommand(mNativePtr, cecMessage.getSource(), cecMessage.getDestination(), body); - if (errorCode == Constants.SEND_RESULT_SUCCESS) { + if (errorCode == SendMessageResult.SUCCESS) { break; } } while (i++ < HdmiConfig.RETRANSMISSION_COUNT); final int finalError = errorCode; - if (finalError != Constants.SEND_RESULT_SUCCESS) { + if (finalError != SendMessageResult.SUCCESS) { Slog.w(TAG, "Failed to send " + cecMessage); } if (callback != null) { @@ -636,7 +650,8 @@ final class HdmiCecController { private static native int nativeGetVersion(long controllerPtr); private static native int nativeGetVendorId(long controllerPtr); private static native HdmiPortInfo[] nativeGetPortInfos(long controllerPtr); - private static native void nativeSetOption(long controllerPtr, int flag, int value); - private static native void nativeSetAudioReturnChannel(long controllerPtr, int port, boolean flag); + private static native void nativeSetOption(long controllerPtr, int flag, boolean enabled); + private static native void nativeSetLanguage(long controllerPtr, String language); + private static native void nativeEnableAudioReturnChannel(long controllerPtr, int port, boolean flag); private static native boolean nativeIsConnected(long controllerPtr, int port); } diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java index 43d8bac73a50..c85d97962a22 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java @@ -36,6 +36,7 @@ import android.hardware.hdmi.HdmiPortInfo; import android.hardware.hdmi.HdmiRecordSources; import android.hardware.hdmi.HdmiTimerRecordSources; import android.hardware.hdmi.IHdmiControlCallback; +import android.hardware.tv.cec.V1_0.SendMessageResult; import android.media.AudioManager; import android.media.AudioSystem; import android.media.tv.TvInputInfo; @@ -46,7 +47,6 @@ import android.util.ArraySet; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; - import com.android.internal.annotations.GuardedBy; import com.android.internal.util.IndentingPrintWriter; import com.android.server.hdmi.DeviceDiscoveryAction.DeviceDiscoveryCallback; @@ -57,9 +57,9 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.Iterator; import java.util.List; -import java.util.HashMap; /** * Represent a logical device of type TV residing in Android system. @@ -910,7 +910,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { HdmiLogger.debug("Set Arc Status[old:%b new:%b]", mArcEstablished, enabled); boolean oldStatus = mArcEstablished; // 1. Enable/disable ARC circuit. - setAudioReturnChannel(enabled); + enableAudioReturnChannel(enabled); // 2. Notify arc status to audio service. notifyArcStatusToAudioService(enabled); // 3. Update arc status; @@ -922,11 +922,11 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { * Switch hardware ARC circuit in the system. */ @ServiceThreadOnly - void setAudioReturnChannel(boolean enabled) { + void enableAudioReturnChannel(boolean enabled) { assertRunOnServiceThread(); HdmiDeviceInfo avr = getAvrDeviceInfo(); if (avr != null) { - mService.setAudioReturnChannel(avr.getPortId(), enabled); + mService.enableAudioReturnChannel(avr.getPortId(), enabled); } } @@ -1870,7 +1870,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { mService.sendCecCommand(message, new SendMessageCallback() { @Override public void onSendCompleted(int error) { - if (error != Constants.SEND_RESULT_SUCCESS) { + if (error != SendMessageResult.SUCCESS) { announceClearTimerRecordingResult(recorderAddress, CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE); } diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index 72ee218fba2c..18f1b6c0513c 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -20,10 +20,6 @@ import static android.hardware.hdmi.HdmiControlManager.DEVICE_EVENT_ADD_DEVICE; import static android.hardware.hdmi.HdmiControlManager.DEVICE_EVENT_REMOVE_DEVICE; import static com.android.server.hdmi.Constants.DISABLED; import static com.android.server.hdmi.Constants.ENABLED; -import static com.android.server.hdmi.Constants.OPTION_CEC_AUTO_WAKEUP; -import static com.android.server.hdmi.Constants.OPTION_CEC_ENABLE; -import static com.android.server.hdmi.Constants.OPTION_CEC_SERVICE_CONTROL; -import static com.android.server.hdmi.Constants.OPTION_CEC_SET_LANGUAGE; import static com.android.server.hdmi.Constants.OPTION_MHL_ENABLE; import static com.android.server.hdmi.Constants.OPTION_MHL_INPUT_SWITCHING; import static com.android.server.hdmi.Constants.OPTION_MHL_POWER_CHARGE; @@ -49,6 +45,8 @@ import android.hardware.hdmi.IHdmiMhlVendorCommandListener; import android.hardware.hdmi.IHdmiRecordListener; import android.hardware.hdmi.IHdmiSystemAudioModeChangeListener; import android.hardware.hdmi.IHdmiVendorCommandListener; +import android.hardware.tv.cec.V1_0.OptionKey; +import android.hardware.tv.cec.V1_0.SendMessageResult; import android.media.AudioManager; import android.media.tv.TvInputManager; import android.media.tv.TvInputManager.TvInputCallback; @@ -69,7 +67,6 @@ import android.util.ArraySet; import android.util.Slog; import android.util.SparseArray; import android.util.SparseIntArray; - import com.android.internal.annotations.GuardedBy; import com.android.internal.util.IndentingPrintWriter; import com.android.server.SystemService; @@ -77,11 +74,6 @@ import com.android.server.hdmi.HdmiAnnotations.ServiceThreadOnly; import com.android.server.hdmi.HdmiCecController.AllocateAddressCallback; import com.android.server.hdmi.HdmiCecLocalDevice.ActiveSource; import com.android.server.hdmi.HdmiCecLocalDevice.PendingActionClearedCallback; -import com.android.server.hdmi.SelectRequestBuffer.DeviceSelectRequest; -import com.android.server.hdmi.SelectRequestBuffer.PortSelectRequest; - -import libcore.util.EmptyArray; - import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; @@ -89,6 +81,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Locale; +import libcore.util.EmptyArray; /** * Provides a service for sending and processing HDMI control messages, @@ -123,9 +116,10 @@ public final class HdmiControlService extends SystemService { * * @param error result of send request. * <ul> - * <li>{@link Constants#SEND_RESULT_SUCCESS} - * <li>{@link Constants#SEND_RESULT_NAK} - * <li>{@link Constants#SEND_RESULT_FAILURE} + * <li>{@link SendMessageResult#SUCCESS} + * <li>{@link SendMessageResult#NACK} + * <li>{@link SendMessageResult#BUSY} + * <li>{@link SendMessageResult#FAIL} * </ul> */ void onSendCompleted(int error); @@ -466,7 +460,7 @@ public final class HdmiControlService extends SystemService { mWakeUpMessageReceived = false; if (isTvDeviceEnabled()) { - mCecController.setOption(OPTION_CEC_AUTO_WAKEUP, toInt(tv().getAutoWakeup())); + mCecController.setOption(OptionKey.WAKEUP, tv().getAutoWakeup()); } int reason = -1; switch (initiatedBy) { @@ -519,7 +513,7 @@ public final class HdmiControlService extends SystemService { if (isTvDeviceEnabled()) { tv().setAutoWakeup(enabled); } - setCecOption(OPTION_CEC_AUTO_WAKEUP, toInt(enabled)); + setCecOption(OptionKey.WAKEUP, enabled); break; case Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED: for (int type : mLocalDevices) { @@ -556,8 +550,8 @@ public final class HdmiControlService extends SystemService { private void initializeCec(int initiatedBy) { mAddressAllocated = false; - mCecController.setOption(OPTION_CEC_SERVICE_CONTROL, ENABLED); - mCecController.setOption(OPTION_CEC_SET_LANGUAGE, HdmiUtils.languageToInt(mLanguage)); + mCecController.setOption(OptionKey.SYSTEM_CEC_CONTROL, true); + mCecController.setLanguage(mLanguage); initializeLocalDevices(initiatedBy); } @@ -842,7 +836,7 @@ public final class HdmiControlService extends SystemService { } else { HdmiLogger.error("Invalid message type:" + command); if (callback != null) { - callback.onSendCompleted(Constants.SEND_RESULT_FAILURE); + callback.onSendCompleted(SendMessageResult.FAIL); } } } @@ -884,8 +878,8 @@ public final class HdmiControlService extends SystemService { return dispatchMessageToLocalDevice(message); } - void setAudioReturnChannel(int portId, boolean enabled) { - mCecController.setAudioReturnChannel(portId, enabled); + void enableAudioReturnChannel(int portId, boolean enabled) { + mCecController.enableAudioReturnChannel(portId, enabled); } @ServiceThreadOnly @@ -2079,7 +2073,7 @@ public final class HdmiControlService extends SystemService { if (isTvDeviceEnabled()) { tv().broadcastMenuLanguage(language); - mCecController.setOption(OPTION_CEC_SET_LANGUAGE, HdmiUtils.languageToInt(language)); + mCecController.setLanguage(language); } } @@ -2123,7 +2117,7 @@ public final class HdmiControlService extends SystemService { } mStandbyMessageReceived = false; mAddressAllocated = false; - mCecController.setOption(OPTION_CEC_SERVICE_CONTROL, DISABLED); + mCecController.setOption(OptionKey.SYSTEM_CEC_CONTROL, false); mMhlController.setOption(OPTION_MHL_SERVICE_CONTROL, DISABLED); } @@ -2216,7 +2210,7 @@ public final class HdmiControlService extends SystemService { } @ServiceThreadOnly - void setCecOption(int key, int value) { + void setCecOption(int key, boolean value) { assertRunOnServiceThread(); mCecController.setOption(key, value); } @@ -2249,7 +2243,7 @@ public final class HdmiControlService extends SystemService { @ServiceThreadOnly private void enableHdmiControlService() { - mCecController.setOption(OPTION_CEC_ENABLE, ENABLED); + mCecController.setOption(OptionKey.SYSTEM_CEC_CONTROL, true); mMhlController.setOption(OPTION_MHL_ENABLE, ENABLED); initializeCec(INITIATED_BY_ENABLE_CEC); @@ -2264,7 +2258,7 @@ public final class HdmiControlService extends SystemService { mCecController.flush(new Runnable() { @Override public void run() { - mCecController.setOption(OPTION_CEC_ENABLE, DISABLED); + mCecController.setOption(OptionKey.ENABLE_CEC, false); mMhlController.setOption(OPTION_MHL_ENABLE, DISABLED); clearLocalDevices(); } diff --git a/services/core/java/com/android/server/hdmi/HdmiUtils.java b/services/core/java/com/android/server/hdmi/HdmiUtils.java index 9aa9290e7f72..8b1641187ac8 100644 --- a/services/core/java/com/android/server/hdmi/HdmiUtils.java +++ b/services/core/java/com/android/server/hdmi/HdmiUtils.java @@ -291,18 +291,4 @@ final class HdmiUtils { info.getPhysicalAddress(), info.getPortId(), info.getDeviceType(), info.getVendorId(), info.getDisplayName(), newPowerStatus); } - - /** - * Convert 3 byte-long language code in string to integer representation. - * English(eng), for example, is converted to 0x656e67. - * - * @param language language code in string - * @return language code in integer representation - */ - static int languageToInt(String language) { - String normalized = language.toLowerCase(); - return ((normalized.charAt(0) & 0xFF) << 16) - | ((normalized.charAt(1) & 0xFF) << 8) - | (normalized.charAt(2) & 0xFF); - } } diff --git a/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java b/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java index 5f2d65172180..e1bcd9952457 100644 --- a/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java +++ b/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java @@ -265,7 +265,7 @@ final class HotplugDetectionAction extends HdmiCecFeatureAction { // Turn off system audio mode and update settings. tv().setSystemAudioMode(false, true); if (tv().isArcEstablished()) { - tv().setAudioReturnChannel(false); + tv().enableAudioReturnChannel(false); addAndStartAction(new RequestArcTerminationAction(localDevice(), address)); } } diff --git a/services/core/java/com/android/server/hdmi/OneTouchRecordAction.java b/services/core/java/com/android/server/hdmi/OneTouchRecordAction.java index d80b81f6fe4a..39de8ffa2a75 100644 --- a/services/core/java/com/android/server/hdmi/OneTouchRecordAction.java +++ b/services/core/java/com/android/server/hdmi/OneTouchRecordAction.java @@ -22,8 +22,8 @@ import static android.hardware.hdmi.HdmiControlManager.ONE_TOUCH_RECORD_RECORDIN import static android.hardware.hdmi.HdmiControlManager.ONE_TOUCH_RECORD_RECORDING_DIGITAL_SERVICE; import static android.hardware.hdmi.HdmiControlManager.ONE_TOUCH_RECORD_RECORDING_EXTERNAL_INPUT; +import android.hardware.tv.cec.V1_0.SendMessageResult; import android.util.Slog; - import com.android.server.hdmi.HdmiControlService.SendMessageCallback; /** @@ -62,7 +62,7 @@ public class OneTouchRecordAction extends HdmiCecFeatureAction { @Override public void onSendCompleted(int error) { // if failed to send <Record On>, display error message and finish action. - if (error != Constants.SEND_RESULT_SUCCESS) { + if (error != SendMessageResult.SUCCESS) { tv().announceOneTouchRecordResult( mRecorderAddress, ONE_TOUCH_RECORD_CHECK_RECORDER_CONNECTION); diff --git a/services/core/java/com/android/server/hdmi/PowerStatusMonitorAction.java b/services/core/java/com/android/server/hdmi/PowerStatusMonitorAction.java index fd7a7f9a887a..6893012342f9 100644 --- a/services/core/java/com/android/server/hdmi/PowerStatusMonitorAction.java +++ b/services/core/java/com/android/server/hdmi/PowerStatusMonitorAction.java @@ -18,10 +18,9 @@ package com.android.server.hdmi; import static android.hardware.hdmi.HdmiControlManager.POWER_STATUS_UNKNOWN; import android.hardware.hdmi.HdmiDeviceInfo; +import android.hardware.tv.cec.V1_0.SendMessageResult; import android.util.SparseIntArray; - import com.android.server.hdmi.HdmiControlService.SendMessageCallback; - import java.util.List; /** @@ -123,7 +122,7 @@ public class PowerStatusMonitorAction extends HdmiCecFeatureAction { public void onSendCompleted(int error) { // If fails to send <Give Device Power Status>, // update power status into UNKNOWN. - if (error != Constants.SEND_RESULT_SUCCESS) { + if (error != SendMessageResult.SUCCESS) { updatePowerStatus(logicalAddress, POWER_STATUS_UNKNOWN, true); } } diff --git a/services/core/java/com/android/server/hdmi/RequestArcInitiationAction.java b/services/core/java/com/android/server/hdmi/RequestArcInitiationAction.java index f69f975a4b67..4eb220fd65ee 100644 --- a/services/core/java/com/android/server/hdmi/RequestArcInitiationAction.java +++ b/services/core/java/com/android/server/hdmi/RequestArcInitiationAction.java @@ -16,6 +16,8 @@ package com.android.server.hdmi; +import android.hardware.tv.cec.V1_0.SendMessageResult; + /** * Feature action that handles ARC action initiated by TV devices. * @@ -44,7 +46,7 @@ final class RequestArcInitiationAction extends RequestArcAction { sendCommand(command, new HdmiControlService.SendMessageCallback() { @Override public void onSendCompleted(int error) { - if (error != Constants.SEND_RESULT_SUCCESS) { + if (error != SendMessageResult.SUCCESS) { // Turn off ARC status if <Request ARC Initiation> fails. tv().setArcStatus(false); finish(); diff --git a/services/core/java/com/android/server/hdmi/RequestArcTerminationAction.java b/services/core/java/com/android/server/hdmi/RequestArcTerminationAction.java index f5a01156cc92..8b5a29310233 100644 --- a/services/core/java/com/android/server/hdmi/RequestArcTerminationAction.java +++ b/services/core/java/com/android/server/hdmi/RequestArcTerminationAction.java @@ -16,6 +16,8 @@ package com.android.server.hdmi; +import android.hardware.tv.cec.V1_0.SendMessageResult; + /** * Feature action to handle <Request ARC Termination>. * @@ -43,7 +45,7 @@ final class RequestArcTerminationAction extends RequestArcAction { sendCommand(command, new HdmiControlService.SendMessageCallback() { @Override public void onSendCompleted(int error) { - if (error != Constants.SEND_RESULT_SUCCESS) { + if (error != SendMessageResult.SUCCESS) { // If failed to send <Request ARC Termination>, start "Disabled" ARC // transmission action. disableArcTransmission(); diff --git a/services/core/java/com/android/server/hdmi/SetArcTransmissionStateAction.java b/services/core/java/com/android/server/hdmi/SetArcTransmissionStateAction.java index 9b4950b5b1ba..6633789ffc06 100644 --- a/services/core/java/com/android/server/hdmi/SetArcTransmissionStateAction.java +++ b/services/core/java/com/android/server/hdmi/SetArcTransmissionStateAction.java @@ -17,6 +17,7 @@ package com.android.server.hdmi; import android.hardware.hdmi.HdmiDeviceInfo; +import android.hardware.tv.cec.V1_0.SendMessageResult; import android.util.Slog; /** @@ -81,14 +82,14 @@ final class SetArcTransmissionStateAction extends HdmiCecFeatureAction { @Override public void onSendCompleted(int error) { switch (error) { - case Constants.SEND_RESULT_SUCCESS: - case Constants.SEND_RESULT_BUSY: - case Constants.SEND_RESULT_FAILURE: + case SendMessageResult.SUCCESS: + case SendMessageResult.BUSY: + case SendMessageResult.FAIL: // The result of the command transmission, unless it is an obvious // failure indicated by the target device (or lack thereof), should // not affect the ARC status. Ignores it silently. break; - case Constants.SEND_RESULT_NAK: + case SendMessageResult.NACK: // If <Report ARC Initiated> is negatively ack'ed, disable ARC and // send <Report ARC Terminated> directly. setArcStatus(false); diff --git a/services/core/java/com/android/server/hdmi/SystemAudioAction.java b/services/core/java/com/android/server/hdmi/SystemAudioAction.java index a209cd0cca73..af1a85d31443 100644 --- a/services/core/java/com/android/server/hdmi/SystemAudioAction.java +++ b/services/core/java/com/android/server/hdmi/SystemAudioAction.java @@ -17,12 +17,12 @@ package com.android.server.hdmi; import android.annotation.Nullable; -import android.hardware.hdmi.HdmiDeviceInfo; import android.hardware.hdmi.HdmiControlManager; +import android.hardware.hdmi.HdmiDeviceInfo; import android.hardware.hdmi.IHdmiControlCallback; +import android.hardware.tv.cec.V1_0.SendMessageResult; import android.os.RemoteException; import android.util.Slog; - import java.util.List; /** @@ -96,7 +96,7 @@ abstract class SystemAudioAction extends HdmiCecFeatureAction { sendCommand(command, new HdmiControlService.SendMessageCallback() { @Override public void onSendCompleted(int error) { - if (error != Constants.SEND_RESULT_SUCCESS) { + if (error != SendMessageResult.SUCCESS) { HdmiLogger.debug("Failed to send <System Audio Mode Request>:" + error); setSystemAudioMode(false); finishWithCallback(HdmiControlManager.RESULT_COMMUNICATION_FAILED); diff --git a/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java b/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java index 78b40fd1892d..01063b757d43 100644 --- a/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java +++ b/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java @@ -16,6 +16,7 @@ package com.android.server.hdmi; +import android.hardware.tv.cec.V1_0.SendMessageResult; import com.android.server.hdmi.HdmiControlService.SendMessageCallback; /** @@ -48,7 +49,7 @@ final class SystemAudioAutoInitiationAction extends HdmiCecFeatureAction { mAvrAddress), new SendMessageCallback() { @Override public void onSendCompleted(int error) { - if (error != Constants.SEND_RESULT_SUCCESS) { + if (error != SendMessageResult.SUCCESS) { tv().setSystemAudioMode(false, true); finish(); } diff --git a/services/core/java/com/android/server/hdmi/SystemAudioStatusAction.java b/services/core/java/com/android/server/hdmi/SystemAudioStatusAction.java index 2ae5c979690d..cab8439b6f92 100644 --- a/services/core/java/com/android/server/hdmi/SystemAudioStatusAction.java +++ b/services/core/java/com/android/server/hdmi/SystemAudioStatusAction.java @@ -19,9 +19,9 @@ package com.android.server.hdmi; import android.annotation.Nullable; import android.hardware.hdmi.HdmiControlManager; import android.hardware.hdmi.IHdmiControlCallback; +import android.hardware.tv.cec.V1_0.SendMessageResult; import android.os.RemoteException; import android.util.Slog; - import com.android.server.hdmi.HdmiControlService.SendMessageCallback; /** @@ -56,7 +56,7 @@ final class SystemAudioStatusAction extends HdmiCecFeatureAction { new SendMessageCallback() { @Override public void onSendCompleted(int error) { - if (error != Constants.SEND_RESULT_SUCCESS) { + if (error != SendMessageResult.SUCCESS) { handleSendGiveAudioStatusFailure(); } } diff --git a/services/core/java/com/android/server/hdmi/TimerRecordingAction.java b/services/core/java/com/android/server/hdmi/TimerRecordingAction.java index 16fc25fb1917..525e223b2528 100644 --- a/services/core/java/com/android/server/hdmi/TimerRecordingAction.java +++ b/services/core/java/com/android/server/hdmi/TimerRecordingAction.java @@ -22,10 +22,9 @@ import static android.hardware.hdmi.HdmiControlManager.TIMER_RECORDING_TYPE_ANAL import static android.hardware.hdmi.HdmiControlManager.TIMER_RECORDING_TYPE_DIGITAL; import static android.hardware.hdmi.HdmiControlManager.TIMER_RECORDING_TYPE_EXTERNAL; +import android.hardware.tv.cec.V1_0.SendMessageResult; import android.util.Slog; - import com.android.server.hdmi.HdmiControlService.SendMessageCallback; - import java.util.Arrays; /** @@ -82,7 +81,7 @@ public class TimerRecordingAction extends HdmiCecFeatureAction { sendCommand(message, new SendMessageCallback() { @Override public void onSendCompleted(int error) { - if (error != Constants.SEND_RESULT_SUCCESS) { + if (error != SendMessageResult.SUCCESS) { tv().announceTimerRecordingResult(mRecorderAddress, TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION); finish(); diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java index a37dfed7c829..df6444704858 100644 --- a/services/core/java/com/android/server/job/JobSchedulerService.java +++ b/services/core/java/com/android/server/job/JobSchedulerService.java @@ -824,7 +824,8 @@ public final class JobSchedulerService extends com.android.server.SystemService try { ActivityManagerNative.getDefault().registerUidObserver(mUidObserver, ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE - | ActivityManager.UID_OBSERVER_IDLE, null); + | ActivityManager.UID_OBSERVER_IDLE, ActivityManager.PROCESS_STATE_UNKNOWN, + null); } catch (RemoteException e) { // ignored; both services live in system_server } diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index d8103fc3b39e..fd99f57af9b8 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -612,7 +612,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { try { mActivityManager.registerUidObserver(mUidObserver, ActivityManager.UID_OBSERVER_PROCSTATE|ActivityManager.UID_OBSERVER_GONE, - null); + ActivityManager.PROCESS_STATE_UNKNOWN, null); mNetworkManager.registerObserver(mAlertObserver); } catch (RemoteException e) { // ignored; both services live in system_server diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 6ebdb3cd696b..df5d6e73ce81 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -16,25 +16,24 @@ package com.android.server.notification; -import static android.app.NotificationManager.IMPORTANCE_DEFAULT; import static android.app.NotificationManager.IMPORTANCE_NONE; -import static android.service.notification.NotificationRankerService.REASON_APP_CANCEL; -import static android.service.notification.NotificationRankerService.REASON_APP_CANCEL_ALL; -import static android.service.notification.NotificationRankerService.REASON_CHANNEL_BANNED; -import static android.service.notification.NotificationRankerService.REASON_DELEGATE_CANCEL; -import static android.service.notification.NotificationRankerService.REASON_DELEGATE_CANCEL_ALL; -import static android.service.notification.NotificationRankerService.REASON_DELEGATE_CLICK; -import static android.service.notification.NotificationRankerService.REASON_DELEGATE_ERROR; -import static android.service.notification.NotificationRankerService.REASON_GROUP_SUMMARY_CANCELED; -import static android.service.notification.NotificationRankerService.REASON_LISTENER_CANCEL; -import static android.service.notification.NotificationRankerService.REASON_LISTENER_CANCEL_ALL; -import static android.service.notification.NotificationRankerService.REASON_PACKAGE_BANNED; -import static android.service.notification.NotificationRankerService.REASON_PACKAGE_CHANGED; -import static android.service.notification.NotificationRankerService.REASON_PACKAGE_SUSPENDED; -import static android.service.notification.NotificationRankerService.REASON_PROFILE_TURNED_OFF; -import static android.service.notification.NotificationRankerService.REASON_SNOOZED; -import static android.service.notification.NotificationRankerService.REASON_UNAUTOBUNDLED; -import static android.service.notification.NotificationRankerService.REASON_USER_STOPPED; +import static android.service.notification.NotificationAssistantService.REASON_APP_CANCEL; +import static android.service.notification.NotificationAssistantService.REASON_APP_CANCEL_ALL; +import static android.service.notification.NotificationAssistantService.REASON_CHANNEL_BANNED; +import static android.service.notification.NotificationAssistantService.REASON_DELEGATE_CANCEL; +import static android.service.notification.NotificationAssistantService.REASON_DELEGATE_CANCEL_ALL; +import static android.service.notification.NotificationAssistantService.REASON_DELEGATE_CLICK; +import static android.service.notification.NotificationAssistantService.REASON_DELEGATE_ERROR; +import static android.service.notification.NotificationAssistantService.REASON_GROUP_SUMMARY_CANCELED; +import static android.service.notification.NotificationAssistantService.REASON_LISTENER_CANCEL; +import static android.service.notification.NotificationAssistantService.REASON_LISTENER_CANCEL_ALL; +import static android.service.notification.NotificationAssistantService.REASON_PACKAGE_BANNED; +import static android.service.notification.NotificationAssistantService.REASON_PACKAGE_CHANGED; +import static android.service.notification.NotificationAssistantService.REASON_PACKAGE_SUSPENDED; +import static android.service.notification.NotificationAssistantService.REASON_PROFILE_TURNED_OFF; +import static android.service.notification.NotificationAssistantService.REASON_SNOOZED; +import static android.service.notification.NotificationAssistantService.REASON_UNAUTOBUNDLED; +import static android.service.notification.NotificationAssistantService.REASON_USER_STOPPED; import static android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_EFFECTS; import static android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_NOTIFICATION_EFFECTS; import static android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_CALL_EFFECTS; @@ -110,7 +109,7 @@ import android.service.notification.Condition; import android.service.notification.IConditionProvider; import android.service.notification.INotificationListener; import android.service.notification.IStatusBarNotificationHolder; -import android.service.notification.NotificationRankerService; +import android.service.notification.NotificationAssistantService; import android.service.notification.NotificationListenerService; import android.service.notification.NotificationRankingUpdate; import android.service.notification.StatusBarNotification; @@ -125,7 +124,6 @@ import android.util.Log; import android.util.Slog; import android.util.SparseArray; import android.util.Xml; -import android.view.WindowManager; import android.view.WindowManagerInternal; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; @@ -169,12 +167,10 @@ import java.io.PrintWriter; import java.nio.charset.StandardCharsets; import java.util.ArrayDeque; import java.util.ArrayList; -import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.Set; import java.util.concurrent.TimeUnit; /** {@hide} */ @@ -229,7 +225,6 @@ public class NotificationManagerService extends SystemService { /** notification_enqueue status value for an ignored notification. */ private static final int EVENTLOG_ENQUEUE_STATUS_IGNORED = 2; private static final long MIN_PACKAGE_OVERRATE_LOG_INTERVAL = 5000; // milliseconds - private String mRankerServicePackageName; private IActivityManager mAm; AudioManager mAudioManager; @@ -301,7 +296,7 @@ public class NotificationManagerService extends SystemService { private final UserProfiles mUserProfiles = new UserProfiles(); private NotificationListeners mListeners; - private NotificationRankers mRankerServices; + private NotificationAssistants mNotificationAssistants; private ConditionProviders mConditionProviders; private NotificationUsageStats mUsageStats; @@ -758,9 +753,9 @@ public class NotificationManagerService extends SystemService { } } mListeners.onPackagesChanged(removingPackage, pkgList); - mRankerServices.onPackagesChanged(removingPackage, pkgList); + mNotificationAssistants.onPackagesChanged(removingPackage, pkgList); mConditionProviders.onPackagesChanged(removingPackage, pkgList); - mRankingHelper.onPackagesChanged(removingPackage, pkgList); + mRankingHelper.onPackagesChanged(removingPackage, changeUserId, pkgList); } } }; @@ -808,7 +803,7 @@ public class NotificationManagerService extends SystemService { // Refresh managed services mConditionProviders.onUserSwitched(user); mListeners.onUserSwitched(user); - mRankerServices.onUserSwitched(user); + mNotificationAssistants.onUserSwitched(user); mZenModeHelper.onUserSwitched(user); } else if (action.equals(Intent.ACTION_USER_ADDED)) { mUserProfiles.updateCache(context); @@ -819,7 +814,7 @@ public class NotificationManagerService extends SystemService { final int user = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); mConditionProviders.onUserUnlocked(user); mListeners.onUserUnlocked(user); - mRankerServices.onUserUnlocked(user); + mNotificationAssistants.onUserUnlocked(user); mZenModeHelper.onUserUnlocked(user); } } @@ -962,10 +957,6 @@ public class NotificationManagerService extends SystemService { mVibrator = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE); mAppUsageStats = LocalServices.getService(UsageStatsManagerInternal.class); - // This is the package that contains the AOSP framework update. - mRankerServicePackageName = getContext().getPackageManager() - .getServicesSystemSharedLibraryPackageName(); - mHandler = new WorkerHandler(); mRankingThread.start(); String[] extractorNames; @@ -1059,10 +1050,8 @@ public class NotificationManagerService extends SystemService { // This is a MangedServices object that keeps track of the listeners. mListeners = new NotificationListeners(); - // This is a MangedServices object that keeps track of the ranker. - mRankerServices = new NotificationRankers(); - // Find the updatable ranker and register it. - mRankerServices.registerRanker(); + // This is a MangedServices object that keeps track of the assistant. + mNotificationAssistants = new NotificationAssistants(); mStatusBar = getLocalService(StatusBarManagerInternal.class); if (mStatusBar != null) { @@ -1209,7 +1198,7 @@ public class NotificationManagerService extends SystemService { // bind to listener services. mSettingsObserver.observe(); mListeners.onBootPhaseAppsCanStart(); - mRankerServices.onBootPhaseAppsCanStart(); + mNotificationAssistants.onBootPhaseAppsCanStart(); mConditionProviders.onBootPhaseAppsCanStart(); } } @@ -1682,10 +1671,10 @@ public class NotificationManagerService extends SystemService { final StatusBarNotification sbnOut = new StatusBarNotification( sbn.getPackageName(), sbn.getOpPkg(), + sbn.getNotificationChannel(), sbn.getId(), sbn.getTag(), sbn.getUid(), sbn.getInitialPid(), - 0, // hide score from apps sbn.getNotification().clone(), - sbn.getUser(), sbn.getPostTime()); + sbn.getUser(), sbn.getOverrideGroupKey(), sbn.getPostTime()); list.add(sbnOut); } } @@ -1791,8 +1780,8 @@ public class NotificationManagerService extends SystemService { long identity = Binder.clearCallingIdentity(); try { ManagedServices manager = - mRankerServices.isComponentEnabledForCurrentProfiles(component) - ? mRankerServices + mNotificationAssistants.isComponentEnabledForCurrentProfiles(component) + ? mNotificationAssistants : mListeners; manager.setComponentState(component, true); } finally { @@ -2358,12 +2347,12 @@ public class NotificationManagerService extends SystemService { } @Override - public void applyAdjustmentFromRankerService(INotificationListener token, + public void applyAdjustmentFromAssistantService(INotificationListener token, Adjustment adjustment) throws RemoteException { final long identity = Binder.clearCallingIdentity(); try { synchronized (mNotificationList) { - mRankerServices.checkServiceTokenLocked(token); + mNotificationAssistants.checkServiceTokenLocked(token); applyAdjustmentLocked(adjustment); } mRankingHandler.requestSort(); @@ -2373,13 +2362,13 @@ public class NotificationManagerService extends SystemService { } @Override - public void applyAdjustmentsFromRankerService(INotificationListener token, + public void applyAdjustmentsFromAssistantService(INotificationListener token, List<Adjustment> adjustments) throws RemoteException { final long identity = Binder.clearCallingIdentity(); try { synchronized (mNotificationList) { - mRankerServices.checkServiceTokenLocked(token); + mNotificationAssistants.checkServiceTokenLocked(token); for (Adjustment adjustment : adjustments) { applyAdjustmentLocked(adjustment); } @@ -2478,15 +2467,14 @@ public class NotificationManagerService extends SystemService { } final StatusBarNotification summarySbn = new StatusBarNotification(adjustedSbn.getPackageName(), - adjustedSbn.getOpPkg(), Integer.MAX_VALUE, + adjustedSbn.getOpPkg(), + adjustedSbn.getNotificationChannel(), + Integer.MAX_VALUE, GroupHelper.AUTOGROUP_KEY, adjustedSbn.getUid(), adjustedSbn.getInitialPid(), summaryNotification, adjustedSbn.getUser(), GroupHelper.AUTOGROUP_KEY, System.currentTimeMillis()); - summaryRecord = new NotificationRecord(getContext(), summarySbn, - mRankingHelper.getNotificationChannel(adjustedSbn.getPackageName(), - adjustedSbn.getUid(), - adjustedSbn.getNotification().getNotificationChannel())); + summaryRecord = new NotificationRecord(getContext(), summarySbn); summaries.put(pkg, summarySbn.getKey()); } } @@ -2632,9 +2620,8 @@ public class NotificationManagerService extends SystemService { } } pw.println(')'); - pw.println("\n mRankerServicePackageName: " + mRankerServicePackageName); - pw.println("\n Notification ranker services:"); - mRankerServices.dump(pw, filter); + pw.println("\n Notification assistant services:"); + mNotificationAssistants.dump(pw, filter); } if (!zenOnly) { @@ -2734,9 +2721,11 @@ public class NotificationManagerService extends SystemService { throw new IllegalArgumentException("null not allowed: pkg=" + pkg + " id=" + id + " notification=" + notification); } + final NotificationChannel channel = mRankingHelper.getNotificationChannelWithFallback(pkg, + callingUid, notification.getNotificationChannel()); final StatusBarNotification n = new StatusBarNotification( - pkg, opPkg, id, tag, callingUid, callingPid, 0, notification, - user); + pkg, opPkg, channel, id, tag, callingUid, callingPid, notification, + user, null, System.currentTimeMillis()); // Limit the number of notifications that any given package except the android // package or a registered listener can enqueue. Prevents DOS attacks and deals with leaks. @@ -2799,9 +2788,7 @@ public class NotificationManagerService extends SystemService { Notification.PRIORITY_MAX); // setup local book-keeping - final NotificationRecord r = new NotificationRecord(getContext(), n, - mRankingHelper.getNotificationChannelWithFallback(pkg, callingUid, - n.getNotification().getNotificationChannel())); + final NotificationRecord r = new NotificationRecord(getContext(), n); mHandler.post(new EnqueueNotificationRunnable(userId, r)); idOut[0] = id; @@ -2885,9 +2872,9 @@ public class NotificationManagerService extends SystemService { } } - // tell the ranker service about the notification - if (mRankerServices.isEnabled()) { - mRankerServices.onNotificationEnqueued(r); + // tell the assistant service about the notification + if (mNotificationAssistants.isEnabled()) { + mNotificationAssistants.onNotificationEnqueued(r); // TODO delay the code below here for 100ms or until there is an answer } @@ -4075,19 +4062,19 @@ public class NotificationManagerService extends SystemService { } } - public class NotificationRankers extends ManagedServices { + public class NotificationAssistants extends ManagedServices { - public NotificationRankers() { + public NotificationAssistants() { super(getContext(), mHandler, mNotificationList, mUserProfiles); } @Override protected Config getConfig() { Config c = new Config(); - c.caption = "notification ranker service"; - c.serviceInterface = NotificationRankerService.SERVICE_INTERFACE; - c.secureSettingName = null; - c.bindPermission = Manifest.permission.BIND_NOTIFICATION_RANKER_SERVICE; + c.caption = "notification assistant service"; + c.serviceInterface = NotificationAssistantService.SERVICE_INTERFACE; + c.secureSettingName = Settings.Secure.ENABLED_NOTIFICATION_ASSISTANT; + c.bindPermission = Manifest.permission.BIND_NOTIFICATION_ASSISTANT_SERVICE; c.settingsAction = Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS; c.clientLabel = R.string.notification_ranker_binding_label; return c; @@ -4117,10 +4104,10 @@ public class NotificationManagerService extends SystemService { final StatusBarNotification sbn = r.sbn; TrimCache trimCache = new TrimCache(sbn); - // mServices is the list inside ManagedServices of all the rankers, + // mServices is the list inside ManagedServices of all the assistants, // There should be only one, but it's a list, so while we enforce // singularity elsewhere, we keep it general here, to avoid surprises. - for (final ManagedServiceInfo info : NotificationRankers.this.mServices) { + for (final ManagedServiceInfo info : NotificationAssistants.this.mServices) { boolean sbnVisible = isVisibleToListener(sbn, info); if (!sbnVisible) { continue; @@ -4140,68 +4127,18 @@ public class NotificationManagerService extends SystemService { private void notifyEnqueued(final ManagedServiceInfo info, final StatusBarNotification sbn, int importance, boolean fromUser) { - final INotificationListener ranker = (INotificationListener) info.service; + final INotificationListener assistant = (INotificationListener) info.service; StatusBarNotificationHolder sbnHolder = new StatusBarNotificationHolder(sbn); try { - ranker.onNotificationEnqueued(sbnHolder, importance, fromUser); + assistant.onNotificationEnqueued(sbnHolder, importance, fromUser); } catch (RemoteException ex) { - Log.e(TAG, "unable to notify ranker (enqueued): " + ranker, ex); + Log.e(TAG, "unable to notify assistant (enqueued): " + assistant, ex); } } public boolean isEnabled() { return !mServices.isEmpty(); } - - @Override - public void onUserSwitched(int user) { - synchronized (mNotificationList) { - int i = mServices.size()-1; - while (i --> 0) { - final ManagedServiceInfo info = mServices.get(i); - unregisterService(info.service, info.userid); - } - } - registerRanker(); - } - - @Override - public void onPackagesChanged(boolean removingPackage, String[] pkgList) { - if (DEBUG) Slog.d(TAG, "onPackagesChanged removingPackage=" + removingPackage - + " pkgList=" + (pkgList == null ? null : Arrays.asList(pkgList))); - if (mRankerServicePackageName == null) { - return; - } - - if (pkgList != null && (pkgList.length > 0) && !removingPackage) { - for (String pkgName : pkgList) { - if (mRankerServicePackageName.equals(pkgName)) { - registerRanker(); - } - } - } - } - - protected void registerRanker() { - // Find the updatable ranker and register it. - if (mRankerServicePackageName == null) { - Slog.w(TAG, "could not start ranker service: no package specified!"); - return; - } - Set<ComponentName> rankerComponents = queryPackageForServices( - mRankerServicePackageName, UserHandle.USER_SYSTEM); - Iterator<ComponentName> iterator = rankerComponents.iterator(); - if (iterator.hasNext()) { - ComponentName rankerComponent = iterator.next(); - if (iterator.hasNext()) { - Slog.e(TAG, "found multiple ranker services:" + rankerComponents); - } else { - registerSystemService(rankerComponent, UserHandle.USER_SYSTEM); - } - } else { - Slog.w(TAG, "could not start ranker service: none found"); - } - } } public class NotificationListeners extends ManagedServices { diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java index a1256db61cba..965257c873e9 100644 --- a/services/core/java/com/android/server/notification/NotificationRecord.java +++ b/services/core/java/com/android/server/notification/NotificationRecord.java @@ -101,11 +101,8 @@ public final class NotificationRecord { private String mUserExplanation; private String mPeopleExplanation; - private NotificationChannel mNotificationChannel; - @VisibleForTesting - public NotificationRecord(Context context, StatusBarNotification sbn, - NotificationChannel channel) + public NotificationRecord(Context context, StatusBarNotification sbn) { this.sbn = sbn; mOriginalFlags = sbn.getNotification().flags; @@ -114,7 +111,6 @@ public final class NotificationRecord { mUpdateTimeMs = mCreationTimeMs; mContext = context; stats = new NotificationUsageStats.SingleNotificationStats(); - mNotificationChannel = channel; mImportance = defaultImportance(); } @@ -148,8 +144,8 @@ public final class NotificationRecord { || (n.defaults & Notification.DEFAULT_VIBRATE) != 0 || n.sound != null || n.vibrate != null - || mNotificationChannel.shouldVibrate() - || mNotificationChannel.getRingtone() != null; + || sbn.getNotificationChannel().shouldVibrate() + || sbn.getNotificationChannel().getRingtone() != null; stats.isNoisy = isNoisy; if (!isNoisy && importance > IMPORTANCE_LOW) { @@ -287,7 +283,7 @@ public final class NotificationRecord { pw.println(prefix + " mVisibleSinceMs=" + mVisibleSinceMs); pw.println(prefix + " mUpdateTimeMs=" + mUpdateTimeMs); pw.println(prefix + " mSuppressedVisualEffects= " + mSuppressedVisualEffects); - pw.println(prefix + " mNotificationChannel= " + mNotificationChannel); + pw.println(prefix + " notificationChannel= " + notification.getNotificationChannel()); } @@ -535,6 +531,6 @@ public final class NotificationRecord { } public NotificationChannel getChannel() { - return mNotificationChannel; + return sbn.getNotificationChannel(); } } diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java index 1bb8b3bcd326..d65ea7f7715b 100644 --- a/services/core/java/com/android/server/notification/RankingHelper.java +++ b/services/core/java/com/android/server/notification/RankingHelper.java @@ -716,9 +716,8 @@ public class RankingHelper implements RankingConfig { return packageBans; } - public void onPackagesChanged(boolean removingPackage, String[] pkgList) { - if (removingPackage || pkgList == null || pkgList.length == 0 - || mRestoredWithoutUids.isEmpty()) { + public void onPackagesChanged(boolean removingPackage, int changeUserId, String[] pkgList) { + if (removingPackage || pkgList == null || pkgList.length == 0) { return; // nothing to do } boolean updated = false; @@ -726,8 +725,7 @@ public class RankingHelper implements RankingConfig { final Record r = mRestoredWithoutUids.get(pkg); if (r != null) { try { - //TODO: http://b/22388012 - r.uid = mPm.getPackageUidAsUser(r.pkg, UserHandle.USER_SYSTEM); + r.uid = mPm.getPackageUidAsUser(r.pkg, changeUserId); mRestoredWithoutUids.remove(pkg); mRecords.put(recordKey(r.pkg, r.uid), r); updated = true; @@ -737,7 +735,7 @@ public class RankingHelper implements RankingConfig { } try { Record fullRecord = getRecord(pkg, - mPm.getPackageUidAsUser(pkg, UserHandle.USER_SYSTEM)); + mPm.getPackageUidAsUser(pkg, changeUserId)); if (fullRecord != null) { clampDefaultChannel(fullRecord); } diff --git a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java index 27e2a6e03ae5..ecc03d7c5fbb 100644 --- a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java +++ b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java @@ -54,6 +54,8 @@ final class EphemeralResolverConnection { private final Object mLock = new Object(); private final GetEphemeralResolveInfoCaller mGetEphemeralResolveInfoCaller = new GetEphemeralResolveInfoCaller(); + private final GetEphemeralIntentFilterCaller mGetEphemeralIntentFilterCaller = + new GetEphemeralIntentFilterCaller(); private final ServiceConnection mServiceConnection = new MyServiceConnection(); private final Context mContext; /** Intent used to bind to the service */ @@ -67,12 +69,26 @@ final class EphemeralResolverConnection { mIntent = new Intent(Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE).setComponent(componentName); } - public final List<EphemeralResolveInfo> getEphemeralResolveInfoList( - int hashPrefix[], int prefixMask) { + public final List<EphemeralResolveInfo> getEphemeralResolveInfoList(int hashPrefix[]) { throwIfCalledOnMainThread(); try { return mGetEphemeralResolveInfoCaller.getEphemeralResolveInfoList( - getRemoteInstanceLazy(), hashPrefix, prefixMask); + getRemoteInstanceLazy(), hashPrefix); + } catch (RemoteException re) { + } catch (TimeoutException te) { + } finally { + synchronized (mLock) { + mLock.notifyAll(); + } + } + return null; + } + + public final List<EphemeralResolveInfo> getEphemeralIntentFilterList(int digestPrefix[]) { + throwIfCalledOnMainThread(); + try { + return mGetEphemeralIntentFilterCaller.getEphemeralIntentFilterList( + getRemoteInstanceLazy(), digestPrefix); } catch (RemoteException re) { } catch (TimeoutException te) { } finally { @@ -182,10 +198,38 @@ final class EphemeralResolverConnection { } public List<EphemeralResolveInfo> getEphemeralResolveInfoList( - IEphemeralResolver target, int hashPrefix[], int prefixMask) + IEphemeralResolver target, int hashPrefix[]) + throws RemoteException, TimeoutException { + final int sequence = onBeforeRemoteCall(); + target.getEphemeralResolveInfoList(mCallback, hashPrefix, sequence); + return getResultTimed(sequence); + } + } + + private static final class GetEphemeralIntentFilterCaller + extends TimedRemoteCaller<List<EphemeralResolveInfo>> { + private final IRemoteCallback mCallback; + + public GetEphemeralIntentFilterCaller() { + super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS); + mCallback = new IRemoteCallback.Stub() { + @Override + public void sendResult(Bundle data) throws RemoteException { + final ArrayList<EphemeralResolveInfo> resolveList = + data.getParcelableArrayList( + EphemeralResolverService.EXTRA_RESOLVE_INFO); + int sequence = + data.getInt(EphemeralResolverService.EXTRA_SEQUENCE, -1); + onRemoteMethodResult(resolveList, sequence); + } + }; + } + + public List<EphemeralResolveInfo> getEphemeralIntentFilterList( + IEphemeralResolver target, int digestPrefix[]) throws RemoteException, TimeoutException { final int sequence = onBeforeRemoteCall(); - target.getEphemeralResolveInfoList(mCallback, hashPrefix, prefixMask, sequence); + target.getEphemeralIntentFilterList(mCallback, digestPrefix, sequence); return getResultTimed(sequence); } } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 57afabe89dfa..09b61772c1e9 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -122,6 +122,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.AppsQueryHelper; import android.content.pm.ComponentInfo; import android.content.pm.EphemeralApplicationInfo; +import android.content.pm.EphemeralIntentFilter; import android.content.pm.EphemeralResolveInfo; import android.content.pm.EphemeralResolveInfo.EphemeralDigest; import android.content.pm.EphemeralResolveInfo.EphemeralResolveIntentInfo; @@ -471,9 +472,12 @@ public class PackageManagerService extends IPackageManager.Stub { * VENDOR_OVERLAY_DIR. */ private static final String VENDOR_OVERLAY_THEME_PROPERTY = "ro.boot.vendor.overlay.theme"; - - private static int DEFAULT_EPHEMERAL_HASH_PREFIX_MASK = 0xFFFFF000; - private static int DEFAULT_EPHEMERAL_HASH_PREFIX_COUNT = 5; + /** + * Same as VENDOR_OVERLAY_THEME_PROPERTY, except persistent. If set will override whatever + * is in VENDOR_OVERLAY_THEME_PROPERTY. + */ + private static final String VENDOR_OVERLAY_THEME_PERSIST_PROPERTY + = "persist.vendor.overlay.theme"; /** Permission grant: not grant the permission. */ private static final int GRANT_DENIED = 1; @@ -2289,7 +2293,10 @@ public class PackageManagerService extends IPackageManager.Stub { // Collect vendor overlay packages. (Do this before scanning any apps.) // For security and version matching reason, only consider // overlay packages if they reside in the right directory. - String overlayThemeDir = SystemProperties.get(VENDOR_OVERLAY_THEME_PROPERTY); + String overlayThemeDir = SystemProperties.get(VENDOR_OVERLAY_THEME_PERSIST_PROPERTY); + if (overlayThemeDir.isEmpty()) { + overlayThemeDir = SystemProperties.get(VENDOR_OVERLAY_THEME_PROPERTY); + } if (!overlayThemeDir.isEmpty()) { scanDirTracedLI(new File(VENDOR_OVERLAY_DIR, overlayThemeDir), mDefParseFlags | PackageParser.PARSE_IS_SYSTEM @@ -4936,19 +4943,15 @@ public class PackageManagerService extends IPackageManager.Stub { return true; } - private static EphemeralResolveInfo getEphemeralResolveInfo( + private static EphemeralResolveIntentInfo getEphemeralIntentInfo( Context context, EphemeralResolverConnection resolverConnection, Intent intent, String resolvedType, int userId, String packageName) { - final int ephemeralPrefixMask = Global.getInt(context.getContentResolver(), - Global.EPHEMERAL_HASH_PREFIX_MASK, DEFAULT_EPHEMERAL_HASH_PREFIX_MASK); - final int ephemeralPrefixCount = Global.getInt(context.getContentResolver(), - Global.EPHEMERAL_HASH_PREFIX_COUNT, DEFAULT_EPHEMERAL_HASH_PREFIX_COUNT); - final EphemeralDigest digest = new EphemeralDigest(intent.getData(), ephemeralPrefixMask, - ephemeralPrefixCount); + final EphemeralDigest digest = + new EphemeralDigest(intent.getData().getHost(), 5 /*maxDigests*/); final int[] shaPrefix = digest.getDigestPrefix(); final byte[][] digestBytes = digest.getDigestBytes(); final List<EphemeralResolveInfo> ephemeralResolveInfoList = - resolverConnection.getEphemeralResolveInfoList(shaPrefix, ephemeralPrefixMask); + resolverConnection.getEphemeralResolveInfoList(shaPrefix); if (ephemeralResolveInfoList == null || ephemeralResolveInfoList.size() == 0) { // No hash prefix match; there are no ephemeral apps for this domain. return null; @@ -4960,9 +4963,10 @@ public class PackageManagerService extends IPackageManager.Stub { if (!Arrays.equals(digestBytes[i], ephemeralApplication.getDigestBytes())) { continue; } - final List<IntentFilter> filters = ephemeralApplication.getFilters(); + final List<EphemeralIntentFilter> ephemeralFilters = + ephemeralApplication.getIntentFilters(); // No filters; this should never happen. - if (filters.isEmpty()) { + if (ephemeralFilters.isEmpty()) { continue; } if (packageName != null @@ -4971,13 +4975,21 @@ public class PackageManagerService extends IPackageManager.Stub { } // We have a domain match; resolve the filters to see if anything matches. final EphemeralIntentResolver ephemeralResolver = new EphemeralIntentResolver(); - for (int j = filters.size() - 1; j >= 0; --j) { - final EphemeralResolveIntentInfo intentInfo = - new EphemeralResolveIntentInfo(filters.get(j), ephemeralApplication); - ephemeralResolver.addFilter(intentInfo); + for (int j = ephemeralFilters.size() - 1; j >= 0; --j) { + final EphemeralIntentFilter ephemeralFilter = ephemeralFilters.get(j); + final List<IntentFilter> splitFilters = ephemeralFilter.getFilters(); + if (splitFilters == null || splitFilters.isEmpty()) { + continue; + } + for (int k = splitFilters.size() - 1; k >= 0; --k) { + final EphemeralResolveIntentInfo intentInfo = + new EphemeralResolveIntentInfo(splitFilters.get(k), + ephemeralApplication, ephemeralFilter.getSplitName()); + ephemeralResolver.addFilter(intentInfo); + } } - List<EphemeralResolveInfo> matchedResolveInfoList = ephemeralResolver.queryIntent( - intent, resolvedType, false /*defaultOnly*/, userId); + List<EphemeralResolveIntentInfo> matchedResolveInfoList = ephemeralResolver + .queryIntent(intent, resolvedType, false /*defaultOnly*/, userId); if (!matchedResolveInfoList.isEmpty()) { return matchedResolveInfoList.get(0); } @@ -5460,15 +5472,15 @@ public class PackageManagerService extends IPackageManager.Stub { } if (addEphemeral) { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral"); - final EphemeralResolveInfo ai = getEphemeralResolveInfo( + final EphemeralResolveIntentInfo intentInfo = getEphemeralIntentInfo( mContext, mEphemeralResolverConnection, intent, resolvedType, userId, matchEphemeralPackage ? pkgName : null); - if (ai != null) { + if (intentInfo != null) { if (DEBUG_EPHEMERAL) { Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list"); } final ResolveInfo ephemeralInstaller = new ResolveInfo(mEphemeralInstallerInfo); - ephemeralInstaller.ephemeralResolveInfo = ai; + ephemeralInstaller.ephemeralIntentInfo = intentInfo; // make sure this resolver is the default ephemeralInstaller.isDefault = true; ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART @@ -11442,7 +11454,7 @@ public class PackageManagerService extends IPackageManager.Stub { } private static final class EphemeralIntentResolver - extends IntentResolver<EphemeralResolveIntentInfo, EphemeralResolveInfo> { + extends IntentResolver<EphemeralResolveIntentInfo, EphemeralResolveIntentInfo> { /** * The result that has the highest defined order. Ordering applies on a * per-package basis. Mapping is from package name to Pair of order and @@ -11467,7 +11479,7 @@ public class PackageManagerService extends IPackageManager.Stub { } @Override - protected EphemeralResolveInfo newResult(EphemeralResolveIntentInfo info, int match, + protected EphemeralResolveIntentInfo newResult(EphemeralResolveIntentInfo info, int match, int userId) { if (!sUserManager.exists(userId)) { return null; @@ -11485,18 +11497,18 @@ public class PackageManagerService extends IPackageManager.Stub { // non-zero order, enable ordering mOrderResult.put(packageName, new Pair<>(order, res)); } - return res; + return info; } @Override - protected void filterResults(List<EphemeralResolveInfo> results) { + protected void filterResults(List<EphemeralResolveIntentInfo> results) { // only do work if ordering is enabled [most of the time it won't be] if (mOrderResult.size() == 0) { return; } int resultSize = results.size(); for (int i = 0; i < resultSize; i++) { - final EphemeralResolveInfo info = results.get(i); + final EphemeralResolveInfo info = results.get(i).getEphemeralResolveInfo(); final String packageName = info.getPackageName(); final Pair<Integer, EphemeralResolveInfo> savedInfo = mOrderResult.get(packageName); if (savedInfo == null) { @@ -18089,8 +18101,10 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); } synchronized (mPackages) { - if (uid == Process.SHELL_UID) { + if (uid == Process.SHELL_UID + && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) { // Shell can only change whole packages between ENABLED and DISABLED_USER states + // unless it is a test package. int oldState = pkgSetting.getEnabled(userId); if (className == null && diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java index 38d69ed287e1..d558b07a7a70 100644 --- a/services/core/java/com/android/server/pm/ShortcutPackage.java +++ b/services/core/java/com/android/server/pm/ShortcutPackage.java @@ -635,11 +635,7 @@ class ShortcutPackage extends ShortcutPackageItem { return false; // Shouldn't happen. } - // Always scan the settings app, since its version code is the same for DR and MR1. - // TODO Fix it properly: b/32554059 - final boolean isSettings = "com.android.settings".equals(getPackageName()); - - if (!isNewApp && !forceRescan && !isSettings) { + if (!isNewApp && !forceRescan) { // Return if the package hasn't changed, ie: // - version code hasn't change // - lastUpdateTime hasn't change @@ -656,11 +652,6 @@ class ShortcutPackage extends ShortcutPackageItem { return false; } } - if (isSettings) { - if (ShortcutService.DEBUG) { - Slog.d(TAG, "Always scan settings."); - } - } } finally { s.logDurationStat(Stats.PACKAGE_UPDATE_CHECK, start); } diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java index 37acf5cc4a0f..ad31a321ccff 100644 --- a/services/core/java/com/android/server/pm/ShortcutService.java +++ b/services/core/java/com/android/server/pm/ShortcutService.java @@ -468,7 +468,7 @@ public class ShortcutService extends IShortcutService.Stub { @Override public void onUidGone(int uid) throws RemoteException { - handleOnUidStateChanged(uid, ActivityManager.MAX_PROCESS_STATE); + handleOnUidStateChanged(uid, ActivityManager.PROCESS_STATE_NONEXISTENT); } @Override @@ -497,8 +497,7 @@ public class ShortcutService extends IShortcutService.Stub { } private boolean isProcessStateForeground(int processState) { - return (processState != ActivityManager.PROCESS_STATE_NONEXISTENT) - && (processState <= PROCESS_STATE_FOREGROUND_THRESHOLD); + return processState <= PROCESS_STATE_FOREGROUND_THRESHOLD; } boolean isUidForegroundLocked(int uid) { @@ -2667,8 +2666,7 @@ public class ShortcutService extends IShortcutService.Stub { } } - rescanUpdatedPackagesLocked(ownerUserId, user.getLastAppScanTime(), - /* forceRescan=*/ false); + rescanUpdatedPackagesLocked(ownerUserId, user.getLastAppScanTime()); } } finally { logDurationStat(Stats.CHECK_PACKAGE_CHANGES, start); @@ -2676,8 +2674,7 @@ public class ShortcutService extends IShortcutService.Stub { verifyStates(); } - private void rescanUpdatedPackagesLocked(@UserIdInt int userId, long lastScanTime, - boolean forceRescan) { + private void rescanUpdatedPackagesLocked(@UserIdInt int userId, long lastScanTime) { final ShortcutUser user = getUserShortcutsLocked(userId); // Note after each OTA, we'll need to rescan all system apps, as their lastUpdateTime @@ -2689,7 +2686,8 @@ public class ShortcutService extends IShortcutService.Stub { // Then for each installed app, publish manifest shortcuts when needed. forUpdatedPackages(userId, lastScanTime, afterOta, ai -> { user.attemptToRestoreIfNeededAndSave(this, ai.packageName, userId); - user.rescanPackageIfNeeded(ai.packageName, forceRescan); + + user.rescanPackageIfNeeded(ai.packageName, /* forceRescan= */ true); }); // Write the time just before the scan, because there may be apps that have just @@ -2937,32 +2935,26 @@ public class ShortcutService extends IShortcutService.Stub { private void forUpdatedPackages(@UserIdInt int userId, long lastScanTime, boolean afterOta, Consumer<ApplicationInfo> callback) { if (DEBUG) { - Slog.d(TAG, "forUpdatedPackages for user " + userId + ", lastScanTime=" + lastScanTime); + Slog.d(TAG, "forUpdatedPackages for user " + userId + ", lastScanTime=" + lastScanTime + + " afterOta=" + afterOta); } final List<PackageInfo> list = getInstalledPackages(userId); for (int i = list.size() - 1; i >= 0; i--) { final PackageInfo pi = list.get(i); // If the package has been updated since the last scan time, then scan it. - // Also if it's a system app with no update, lastUpdateTime is not reliable, so - // just scan it. - if (pi.lastUpdateTime >= lastScanTime - || (afterOta && isPureSystemApp(pi.applicationInfo))) { + // Also if it's right after an OTA, always re-scan all apps anyway, since the + // shortcut parser might have changed. + if (afterOta || (pi.lastUpdateTime >= lastScanTime)) { if (DEBUG) { - Slog.d(TAG, "Found updated package " + pi.packageName); + Slog.d(TAG, "Found updated package " + pi.packageName + + " updateTime=" + pi.lastUpdateTime); } callback.accept(pi.applicationInfo); } } } - /** - * @return true if it's a system app with no updates. - */ - private boolean isPureSystemApp(ApplicationInfo ai) { - return ai.isSystemApp() && !ai.isUpdatedSystemApp(); - } - private boolean isApplicationFlagSet(@NonNull String packageName, int userId, int flags) { final ApplicationInfo ai = injectApplicationInfoWithUninstalled(packageName, userId); return (ai != null) && ((ai.flags & flags) == flags); @@ -3213,8 +3205,8 @@ public class ShortcutService extends IShortcutService.Stub { // Rescan all packages to re-publish manifest shortcuts and do other checks. rescanUpdatedPackagesLocked(userId, - 0, // lastScanTime = 0; rescan all packages. - /* forceRescan= */ true); + 0 // lastScanTime = 0; rescan all packages. + ); saveUserLocked(userId); } @@ -3677,7 +3669,8 @@ public class ShortcutService extends IShortcutService.Stub { @VisibleForTesting void injectRegisterUidObserver(IUidObserver observer, int which) { try { - ActivityManagerNative.getDefault().registerUidObserver(observer, which, null); + ActivityManagerNative.getDefault().registerUidObserver(observer, which, + ActivityManager.PROCESS_STATE_UNKNOWN, null); } catch (RemoteException shouldntHappen) { } } diff --git a/services/core/java/com/android/server/policy/GlobalActions.java b/services/core/java/com/android/server/policy/GlobalActions.java index a8bd4d289616..3bea663c6700 100644 --- a/services/core/java/com/android/server/policy/GlobalActions.java +++ b/services/core/java/com/android/server/policy/GlobalActions.java @@ -19,7 +19,7 @@ package com.android.server.policy; import com.android.internal.app.AlertController; import com.android.internal.app.AlertController.AlertParams; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.policy.EmergencyAffordanceManager; import com.android.internal.telephony.TelephonyIntents; import com.android.internal.telephony.TelephonyProperties; diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index d755e58c2ba2..1790554a258b 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -2731,6 +2731,8 @@ public final class PowerManagerService extends SystemService } } else { disabled = !wakeLock.mUidState.mActive && + wakeLock.mUidState.mProcState + != ActivityManager.PROCESS_STATE_NONEXISTENT && wakeLock.mUidState.mProcState > ActivityManager.PROCESS_STATE_RECEIVER; } } diff --git a/services/core/java/com/android/server/storage/AppFuseBridge.java b/services/core/java/com/android/server/storage/AppFuseBridge.java new file mode 100644 index 000000000000..23be9a3a27f7 --- /dev/null +++ b/services/core/java/com/android/server/storage/AppFuseBridge.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.storage; + +import android.annotation.CallSuper; +import android.annotation.WorkerThread; +import android.os.Handler; +import android.os.ParcelFileDescriptor; +import android.system.ErrnoException; +import android.system.Os; +import android.system.OsConstants; +import android.util.Log; +import com.android.internal.os.AppFuseMount; +import libcore.io.IoUtils; + +import java.io.File; +import java.io.FileDescriptor; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.concurrent.CountDownLatch; + +public class AppFuseBridge implements Runnable { + private static final String TAG = AppFuseBridge.class.getSimpleName(); + + private final FileDescriptor mDeviceFd; + private final FileDescriptor mProxyFd; + private final CountDownLatch mMountLatch = new CountDownLatch(1); + + /** + * @param deviceFd FD of /dev/fuse. Ownership of fd is taken by AppFuseBridge. + * @param proxyFd FD of socket pair. Ownership of fd is taken by AppFuseBridge. + */ + private AppFuseBridge(FileDescriptor deviceFd, FileDescriptor proxyFd) { + mDeviceFd = deviceFd; + mProxyFd = proxyFd; + } + + public static AppFuseMount startMessageLoop( + int uid, + String name, + FileDescriptor deviceFd, + Handler handler, + ParcelFileDescriptor.OnCloseListener listener) + throws IOException, ErrnoException, InterruptedException { + final FileDescriptor localFd = new FileDescriptor(); + final FileDescriptor remoteFd = new FileDescriptor(); + // Needs to specify OsConstants.SOCK_SEQPACKET to keep message boundaries. + Os.socketpair(OsConstants.AF_UNIX, OsConstants.SOCK_SEQPACKET, 0, remoteFd, localFd); + + // Caller must invoke #start() after instantiate AppFuseBridge. + // Otherwise FDs will be leaked. + final AppFuseBridge bridge = new AppFuseBridge(deviceFd, localFd); + final Thread thread = new Thread(bridge, TAG); + thread.start(); + try { + bridge.mMountLatch.await(); + } catch (InterruptedException error) { + throw error; + } + return new AppFuseMount( + new File("/mnt/appfuse/" + uid + "_" + name), + ParcelFileDescriptor.fromFd(remoteFd, handler, listener)); + } + + @Override + public void run() { + // deviceFd and proxyFd must be closed in native_start_loop. + final int deviceFd = mDeviceFd.getInt$(); + final int proxyFd = mProxyFd.getInt$(); + mDeviceFd.setInt$(-1); + mProxyFd.setInt$(-1); + native_start_loop(deviceFd, proxyFd); + } + + // Used by com_android_server_storage_AppFuse.cpp. + private void onMount() { + mMountLatch.countDown(); + } + + private native boolean native_start_loop(int deviceFd, int proxyFd); +} diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java index 670b9ccdf5f6..869e20745a48 100644 --- a/services/core/java/com/android/server/wm/AccessibilityController.java +++ b/services/core/java/com/android/server/wm/AccessibilityController.java @@ -1034,7 +1034,6 @@ final class AccessibilityController { boolean focusedWindowAdded = false; final int visibleWindowCount = visibleWindows.size(); - int skipRemainingWindowsForTaskId = -1; HashSet<Integer> skipRemainingWindowsForTasks = new HashSet<>(); for (int i = visibleWindowCount - 1; i >= 0; i--) { final WindowState windowState = visibleWindows.valueAt(i); diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index f0381352be42..299fa05d0ed9 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -40,9 +40,7 @@ import com.android.server.EventLogTags; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.HashMap; -import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; import static android.app.AppOpsManager.MODE_ALLOWED; import static android.app.AppOpsManager.MODE_DEFAULT; import static android.app.AppOpsManager.OP_NONE; @@ -55,17 +53,13 @@ import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG; import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM; import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT; import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; -import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; -import static com.android.server.wm.AppTransition.TRANSIT_UNSET; + import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEEP_SCREEN_ON; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_POWER; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT; @@ -78,7 +72,6 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerService.H.REPORT_LOSING_FOCUS; import static com.android.server.wm.WindowManagerService.H.SEND_NEW_CONFIGURATION; -import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL; import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES; import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES; import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_NONE; @@ -760,9 +753,6 @@ class RootWindowContainer extends WindowContainer<DisplayContent> { WindowToken token = exitingTokens.get(i); if (!token.hasVisible) { exitingTokens.remove(i); - if (token.windowType == TYPE_WALLPAPER) { - displayContent.mWallpaperController.removeWallpaperToken(token); - } } } } diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java index 250d381e614b..178fbe75ca59 100644 --- a/services/core/java/com/android/server/wm/WallpaperController.java +++ b/services/core/java/com/android/server/wm/WallpaperController.java @@ -55,7 +55,7 @@ class WallpaperController { private static final String TAG = TAG_WITH_CLASS_NAME ? "WallpaperController" : TAG_WM; final private WindowManagerService mService; - private final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<>(); + private final ArrayList<WallpaperWindowToken> mWallpaperTokens = new ArrayList<>(); // If non-null, this is the currently visible window that is associated // with the wallpaper. @@ -135,7 +135,7 @@ class WallpaperController { */ void startWallpaperAnimation(Animation a) { for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) { - final WindowToken token = mWallpaperTokens.get(curTokenNdx); + final WallpaperWindowToken token = mWallpaperTokens.get(curTokenNdx); token.startAnimation(a); } } @@ -163,7 +163,7 @@ class WallpaperController { final boolean visible = isWallpaperVisible(mWallpaperTarget); for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) { - final WindowToken token = mWallpaperTokens.get(curTokenNdx); + final WallpaperWindowToken token = mWallpaperTokens.get(curTokenNdx); token.updateWallpaperVisibility(visible); } } @@ -189,7 +189,7 @@ class WallpaperController { final boolean wasDeferred = (mDeferredHideWallpaper == winGoingAway); for (int i = mWallpaperTokens.size() - 1; i >= 0; i--) { - final WindowToken token = mWallpaperTokens.get(i); + final WallpaperWindowToken token = mWallpaperTokens.get(i); token.hideWallpaperToken(wasDeferred, "hideWallpapers"); if (DEBUG_WALLPAPER_LIGHT && !token.hidden) Slog.d(TAG, "Hiding wallpaper " + token + " from " + winGoingAway + " target=" + mWallpaperTarget + " lower=" @@ -304,7 +304,7 @@ class WallpaperController { || window == mUpperWallpaperTarget) { boolean doWait = sync; for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) { - final WindowToken token = mWallpaperTokens.get(curTokenNdx); + final WallpaperWindowToken token = mWallpaperTokens.get(curTokenNdx); token.sendWindowWallpaperCommand(action, x, y, z, extras, sync); } @@ -652,7 +652,7 @@ class WallpaperController { // Start stepping backwards from here, ensuring that our wallpaper windows are correctly placed. boolean changed = false; for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) { - final WindowToken token = mWallpaperTokens.get(curTokenNdx); + final WallpaperWindowToken token = mWallpaperTokens.get(curTokenNdx); changed |= token.updateWallpaperWindowsPlacement(windows, wallpaperTarget, wallpaperTargetIndex, visible, dw, dh, mWallpaperAnimLayerAdjustment); } @@ -725,7 +725,7 @@ class WallpaperController { boolean wallpaperReady = true; for (int curTokenIndex = mWallpaperTokens.size() - 1; curTokenIndex >= 0 && wallpaperReady; curTokenIndex--) { - final WindowToken token = mWallpaperTokens.get(curTokenIndex); + final WallpaperWindowToken token = mWallpaperTokens.get(curTokenIndex); if (token.hasVisibleNotDrawnWallpaper()) { // We've told this wallpaper to be visible, but it is not drawn yet wallpaperReady = false; @@ -777,11 +777,11 @@ class WallpaperController { } } - void addWallpaperToken(WindowToken token) { + void addWallpaperToken(WallpaperWindowToken token) { mWallpaperTokens.add(token); } - void removeWallpaperToken(WindowToken token) { + void removeWallpaperToken(WallpaperWindowToken token) { mWallpaperTokens.remove(token); } diff --git a/services/core/java/com/android/server/wm/WallpaperWindowToken.java b/services/core/java/com/android/server/wm/WallpaperWindowToken.java new file mode 100644 index 000000000000..fdefcfe2d174 --- /dev/null +++ b/services/core/java/com/android/server/wm/WallpaperWindowToken.java @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.server.wm; + +import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD; +import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; +import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE; +import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS; +import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT; +import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT; +import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; +import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; + +import android.os.Bundle; +import android.os.IBinder; +import android.os.RemoteException; +import android.util.Slog; +import android.view.DisplayInfo; +import android.view.animation.Animation; + +/** + * A token that represents a set of wallpaper windows. + */ +class WallpaperWindowToken extends WindowToken { + + private static final String TAG = TAG_WITH_CLASS_NAME ? "WallpaperWindowToken" : TAG_WM; + + WallpaperWindowToken(WindowManagerService service, IBinder token, boolean explicit, + DisplayContent dc) { + super(service, token, TYPE_WALLPAPER, explicit, dc); + dc.mWallpaperController.addWallpaperToken(this); + } + + @Override + void setExiting() { + super.setExiting(); + mDisplayContent.mWallpaperController.removeWallpaperToken(this); + } + + void hideWallpaperToken(boolean wasDeferred, String reason) { + for (int j = mChildren.size() - 1; j >= 0; j--) { + final WindowState wallpaper = mChildren.get(j); + wallpaper.hideWallpaperWindow(wasDeferred, reason); + } + hidden = true; + } + + void sendWindowWallpaperCommand( + String action, int x, int y, int z, Bundle extras, boolean sync) { + for (int wallpaperNdx = mChildren.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) { + final WindowState wallpaper = mChildren.get(wallpaperNdx); + try { + wallpaper.mClient.dispatchWallpaperCommand(action, x, y, z, extras, sync); + // We only want to be synchronous with one wallpaper. + sync = false; + } catch (RemoteException e) { + } + } + } + + void updateWallpaperOffset(int dw, int dh, boolean sync) { + final WallpaperController wallpaperController = mDisplayContent.mWallpaperController; + for (int wallpaperNdx = mChildren.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) { + final WindowState wallpaper = mChildren.get(wallpaperNdx); + if (wallpaperController.updateWallpaperOffset(wallpaper, dw, dh, sync)) { + final WindowStateAnimator winAnimator = wallpaper.mWinAnimator; + winAnimator.computeShownFrameLocked(); + // No need to lay out the windows - we can just set the wallpaper position directly. + winAnimator.setWallpaperOffset(wallpaper.mShownPosition); + // We only want to be synchronous with one wallpaper. + sync = false; + } + } + } + + void updateWallpaperVisibility(boolean visible) { + final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo(); + final int dw = displayInfo.logicalWidth; + final int dh = displayInfo.logicalHeight; + + if (hidden == visible) { + hidden = !visible; + // Need to do a layout to ensure the wallpaper now has the correct size. + mDisplayContent.setLayoutNeeded(); + } + + final WallpaperController wallpaperController = mDisplayContent.mWallpaperController; + for (int wallpaperNdx = mChildren.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) { + final WindowState wallpaper = mChildren.get(wallpaperNdx); + if (visible) { + wallpaperController.updateWallpaperOffset(wallpaper, dw, dh, false); + } + + wallpaper.dispatchWallpaperVisibility(visible); + } + } + + /** + * Starts {@param anim} on all children. + */ + void startAnimation(Animation anim) { + for (int ndx = mChildren.size() - 1; ndx >= 0; ndx--) { + final WindowState windowState = mChildren.get(ndx); + windowState.mWinAnimator.setAnimation(anim); + } + } + + boolean updateWallpaperWindowsPlacement(ReadOnlyWindowList windowList, + WindowState wallpaperTarget, int wallpaperTargetIndex, boolean visible, int dw, int dh, + int wallpaperAnimLayerAdj) { + + boolean changed = false; + if (hidden == visible) { + if (DEBUG_WALLPAPER_LIGHT) Slog.d(TAG, + "Wallpaper token " + token + " hidden=" + !visible); + hidden = !visible; + // Need to do a layout to ensure the wallpaper now has the correct size. + mDisplayContent.setLayoutNeeded(); + } + + final WallpaperController wallpaperController = mDisplayContent.mWallpaperController; + for (int wallpaperNdx = mChildren.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) { + final WindowState wallpaper = mChildren.get(wallpaperNdx); + + if (visible) { + wallpaperController.updateWallpaperOffset(wallpaper, dw, dh, false); + } + + // First, make sure the client has the current visibility state. + wallpaper.dispatchWallpaperVisibility(visible); + wallpaper.adjustAnimLayer(wallpaperAnimLayerAdj); + + if (DEBUG_LAYERS || DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "adjustWallpaper win " + + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer); + + // First, if this window is at the current index, then all is well. + if (wallpaper == wallpaperTarget) { + wallpaperTargetIndex--; + wallpaperTarget = wallpaperTargetIndex > 0 + ? windowList.get(wallpaperTargetIndex - 1) : null; + continue; + } + + // The window didn't match... the current wallpaper window, + // wherever it is, is in the wrong place, so make sure it is not in the list. + int oldIndex = windowList.indexOf(wallpaper); + if (oldIndex >= 0) { + if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, + "Wallpaper removing at " + oldIndex + ": " + wallpaper); + mDisplayContent.removeFromWindowList(wallpaper); + if (oldIndex < wallpaperTargetIndex) { + wallpaperTargetIndex--; + } + } + + // Now stick it in. For apps over wallpaper keep the wallpaper at the bottommost + // layer. For keyguard over wallpaper put the wallpaper under the lowest window that + // is currently on screen, i.e. not hidden by policy. + int insertionIndex = 0; + if (visible && wallpaperTarget != null) { + final int privateFlags = wallpaperTarget.mAttrs.privateFlags; + if ((privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) { + insertionIndex = Math.min(windowList.indexOf(wallpaperTarget), + findLowestWindowOnScreen(windowList)); + } + } + if (DEBUG_WALLPAPER_LIGHT || DEBUG_WINDOW_MOVEMENT + || (DEBUG_ADD_REMOVE && oldIndex != insertionIndex)) Slog.v(TAG, + "Moving wallpaper " + wallpaper + " from " + oldIndex + " to " + insertionIndex); + + mDisplayContent.addToWindowList(wallpaper, insertionIndex); + changed = true; + } + + return changed; + } + + /** + * @return The index in {@param windows} of the lowest window that is currently on screen and + * not hidden by the policy. + */ + private int findLowestWindowOnScreen(ReadOnlyWindowList windowList) { + final int size = windowList.size(); + for (int index = 0; index < size; index++) { + final WindowState win = windowList.get(index); + if (win.isOnScreen()) { + return index; + } + } + return Integer.MAX_VALUE; + } + + boolean hasVisibleNotDrawnWallpaper() { + for (int j = mChildren.size() - 1; j >= 0; --j) { + final WindowState wallpaper = mChildren.get(j); + if (wallpaper.hasVisibleNotDrawnWallpaper()) { + return true; + } + } + return false; + } + + @Override + public String toString() { + if (stringName == null) { + StringBuilder sb = new StringBuilder(); + sb.append("WallpaperWindowToken{"); + sb.append(Integer.toHexString(System.identityHashCode(this))); + sb.append(" token="); sb.append(token); sb.append('}'); + stringName = sb.toString(); + } + return stringName; + } +} diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 77237526faf4..5baa72a859eb 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -1932,6 +1932,12 @@ public class WindowManagerService extends IWindowManager.Stub || (flagChanges & FLAG_DISMISS_KEYGUARD) != 0)) { win.mAppToken.checkKeyguardFlagsChanged(); } + if (((attrChanges & LayoutParams.ACCESSIBILITY_TITLE_CHANGED) != 0) + && (mAccessibilityController != null) + && (win.getDisplayId() == DEFAULT_DISPLAY)) { + // No move or resize, but the controller checks for title changes as well + mAccessibilityController.onSomeWindowResizedOrMovedLocked(); + } } if (DEBUG_LAYOUT) Slog.v(TAG_WM, "Relayout " + win + ": viewVisibility=" + viewVisibility @@ -2409,9 +2415,10 @@ public class WindowManagerService extends IWindowManager.Stub + " displayId=" + displayId); return; } - token = new WindowToken(this, binder, type, true, dc); if (type == TYPE_WALLPAPER) { - dc.mWallpaperController.addWallpaperToken(token); + new WallpaperWindowToken(this, binder, true, dc); + } else { + new WindowToken(this, binder, type, true, dc); } } } @@ -2440,9 +2447,6 @@ public class WindowManagerService extends IWindowManager.Stub } token.setExiting(); - if (token.windowType == TYPE_WALLPAPER) { - dc.mWallpaperController.removeWallpaperToken(token); - } mInputMonitor.updateInputWindowsLw(true /*force*/); } diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java index b821f0900e65..93f1610e926d 100644 --- a/services/core/java/com/android/server/wm/WindowToken.java +++ b/services/core/java/com/android/server/wm/WindowToken.java @@ -82,7 +82,7 @@ class WindowToken extends WindowContainer<WindowState> { boolean sendingToBottom; // The display this token is on. - private DisplayContent mDisplayContent; + protected DisplayContent mDisplayContent; /** * Compares two child window of this token and returns -1 if the first is lesser than the @@ -280,169 +280,6 @@ class WindowToken extends WindowContainer<WindowState> { return false; } - void hideWallpaperToken(boolean wasDeferred, String reason) { - for (int j = mChildren.size() - 1; j >= 0; j--) { - final WindowState wallpaper = mChildren.get(j); - wallpaper.hideWallpaperWindow(wasDeferred, reason); - } - hidden = true; - } - - void sendWindowWallpaperCommand( - String action, int x, int y, int z, Bundle extras, boolean sync) { - for (int wallpaperNdx = mChildren.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) { - final WindowState wallpaper = mChildren.get(wallpaperNdx); - try { - wallpaper.mClient.dispatchWallpaperCommand(action, x, y, z, extras, sync); - // We only want to be synchronous with one wallpaper. - sync = false; - } catch (RemoteException e) { - } - } - } - - void updateWallpaperOffset(int dw, int dh, boolean sync) { - final WallpaperController wallpaperController = mDisplayContent.mWallpaperController; - for (int wallpaperNdx = mChildren.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) { - final WindowState wallpaper = mChildren.get(wallpaperNdx); - if (wallpaperController.updateWallpaperOffset(wallpaper, dw, dh, sync)) { - final WindowStateAnimator winAnimator = wallpaper.mWinAnimator; - winAnimator.computeShownFrameLocked(); - // No need to lay out the windows - we can just set the wallpaper position directly. - winAnimator.setWallpaperOffset(wallpaper.mShownPosition); - // We only want to be synchronous with one wallpaper. - sync = false; - } - } - } - - void updateWallpaperVisibility(boolean visible) { - final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo(); - final int dw = displayInfo.logicalWidth; - final int dh = displayInfo.logicalHeight; - - if (hidden == visible) { - hidden = !visible; - // Need to do a layout to ensure the wallpaper now has the correct size. - mDisplayContent.setLayoutNeeded(); - } - - final WallpaperController wallpaperController = mDisplayContent.mWallpaperController; - for (int wallpaperNdx = mChildren.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) { - final WindowState wallpaper = mChildren.get(wallpaperNdx); - if (visible) { - wallpaperController.updateWallpaperOffset(wallpaper, dw, dh, false); - } - - wallpaper.dispatchWallpaperVisibility(visible); - } - } - - /** - * Starts {@param anim} on all children. - */ - void startAnimation(Animation anim) { - for (int ndx = mChildren.size() - 1; ndx >= 0; ndx--) { - final WindowState windowState = mChildren.get(ndx); - windowState.mWinAnimator.setAnimation(anim); - } - } - - boolean updateWallpaperWindowsPlacement(ReadOnlyWindowList windowList, - WindowState wallpaperTarget, int wallpaperTargetIndex, boolean visible, int dw, int dh, - int wallpaperAnimLayerAdj) { - - boolean changed = false; - if (hidden == visible) { - if (DEBUG_WALLPAPER_LIGHT) Slog.d(TAG, - "Wallpaper token " + token + " hidden=" + !visible); - hidden = !visible; - // Need to do a layout to ensure the wallpaper now has the correct size. - mDisplayContent.setLayoutNeeded(); - } - - final WallpaperController wallpaperController = mDisplayContent.mWallpaperController; - for (int wallpaperNdx = mChildren.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) { - final WindowState wallpaper = mChildren.get(wallpaperNdx); - - if (visible) { - wallpaperController.updateWallpaperOffset(wallpaper, dw, dh, false); - } - - // First, make sure the client has the current visibility state. - wallpaper.dispatchWallpaperVisibility(visible); - wallpaper.adjustAnimLayer(wallpaperAnimLayerAdj); - - if (DEBUG_LAYERS || DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "adjustWallpaper win " - + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer); - - // First, if this window is at the current index, then all is well. - if (wallpaper == wallpaperTarget) { - wallpaperTargetIndex--; - wallpaperTarget = wallpaperTargetIndex > 0 - ? windowList.get(wallpaperTargetIndex - 1) : null; - continue; - } - - // The window didn't match... the current wallpaper window, - // wherever it is, is in the wrong place, so make sure it is not in the list. - int oldIndex = windowList.indexOf(wallpaper); - if (oldIndex >= 0) { - if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, - "Wallpaper removing at " + oldIndex + ": " + wallpaper); - mDisplayContent.removeFromWindowList(wallpaper); - if (oldIndex < wallpaperTargetIndex) { - wallpaperTargetIndex--; - } - } - - // Now stick it in. For apps over wallpaper keep the wallpaper at the bottommost - // layer. For keyguard over wallpaper put the wallpaper under the lowest window that - // is currently on screen, i.e. not hidden by policy. - int insertionIndex = 0; - if (visible && wallpaperTarget != null) { - final int privateFlags = wallpaperTarget.mAttrs.privateFlags; - if ((privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) { - insertionIndex = Math.min(windowList.indexOf(wallpaperTarget), - findLowestWindowOnScreen(windowList)); - } - } - if (DEBUG_WALLPAPER_LIGHT || DEBUG_WINDOW_MOVEMENT - || (DEBUG_ADD_REMOVE && oldIndex != insertionIndex)) Slog.v(TAG, - "Moving wallpaper " + wallpaper + " from " + oldIndex + " to " + insertionIndex); - - mDisplayContent.addToWindowList(wallpaper, insertionIndex); - changed = true; - } - - return changed; - } - - /** - * @return The index in {@param windows} of the lowest window that is currently on screen and - * not hidden by the policy. - */ - private int findLowestWindowOnScreen(ReadOnlyWindowList windowList) { - final int size = windowList.size(); - for (int index = 0; index < size; index++) { - final WindowState win = windowList.get(index); - if (win.isOnScreen()) { - return index; - } - } - return Integer.MAX_VALUE; - } - - boolean hasVisibleNotDrawnWallpaper() { - for (int j = mChildren.size() - 1; j >= 0; --j) { - final WindowState wallpaper = mChildren.get(j); - if (wallpaper.hasVisibleNotDrawnWallpaper()) { - return true; - } - } - return false; - } - int getHighestAnimLayer() { int highest = -1; for (int j = 0; j < mChildren.size(); j++) { diff --git a/services/core/jni/Android.mk b/services/core/jni/Android.mk index 3a9ff5fe8734..c03a4602f2fe 100644 --- a/services/core/jni/Android.mk +++ b/services/core/jni/Android.mk @@ -19,6 +19,7 @@ LOCAL_SRC_FILES += \ $(LOCAL_REL_DIR)/com_android_server_location_FlpHardwareProvider.cpp \ $(LOCAL_REL_DIR)/com_android_server_power_PowerManagerService.cpp \ $(LOCAL_REL_DIR)/com_android_server_SerialService.cpp \ + $(LOCAL_REL_DIR)/com_android_server_storage_AppFuseBridge.cpp \ $(LOCAL_REL_DIR)/com_android_server_SystemServer.cpp \ $(LOCAL_REL_DIR)/com_android_server_tv_TvUinputBridge.cpp \ $(LOCAL_REL_DIR)/com_android_server_tv_TvInputHal.cpp \ @@ -37,6 +38,7 @@ LOCAL_C_INCLUDES += \ frameworks/base/libs/hwui \ frameworks/base/core/jni \ frameworks/native/services \ + system/core/libappfuse/include \ system/security/keystore/include \ $(call include-path-for, libhardware)/hardware \ $(call include-path-for, libhardware_legacy)/hardware_legacy \ @@ -44,6 +46,7 @@ LOCAL_C_INCLUDES += \ LOCAL_SHARED_LIBRARIES += \ libandroid_runtime \ libandroidfw \ + libappfuse \ libbinder \ libcutils \ liblog \ @@ -67,10 +70,11 @@ LOCAL_SHARED_LIBRARIES += \ libhidl \ libhwbinder \ libutils \ + android.hardware.audio.common@2.0 \ + android.hardware.light@2.0 \ android.hardware.power@1.0 \ + android.hardware.thermal@1.0 \ + android.hardware.tv.cec@1.0 \ + android.hardware.tv.input@1.0 \ android.hardware.vibrator@1.0 \ - android.hardware.light@2.0 \ android.hardware.vr@1.0 \ - android.hardware.audio.common@2.0 \ - android.hardware.tv.input@1.0 \ - android.hardware.thermal@1.0 \ diff --git a/services/core/jni/com_android_server_hdmi_HdmiCecController.cpp b/services/core/jni/com_android_server_hdmi_HdmiCecController.cpp index a23fbcbd42c7..0c5729e9b32c 100644 --- a/services/core/jni/com_android_server_hdmi_HdmiCecController.cpp +++ b/services/core/jni/com_android_server_hdmi_HdmiCecController.cpp @@ -21,16 +21,32 @@ #include <JNIHelp.h> #include <ScopedPrimitiveArray.h> -#include <cstring> - +#include <android/hardware/tv/cec/1.0/IHdmiCec.h> +#include <android/hardware/tv/cec/1.0/IHdmiCecCallback.h> +#include <android/hardware/tv/cec/1.0/types.h> #include <android_os_MessageQueue.h> #include <android_runtime/AndroidRuntime.h> #include <android_runtime/Log.h> -#include <hardware/hdmi_cec.h> #include <sys/param.h> +#include <utils/Errors.h> #include <utils/Looper.h> #include <utils/RefBase.h> +using ::android::hardware::tv::cec::V1_0::CecLogicalAddress; +using ::android::hardware::tv::cec::V1_0::CecMessage; +using ::android::hardware::tv::cec::V1_0::HdmiPortInfo; +using ::android::hardware::tv::cec::V1_0::HotplugEvent; +using ::android::hardware::tv::cec::V1_0::IHdmiCec; +using ::android::hardware::tv::cec::V1_0::IHdmiCecCallback; +using ::android::hardware::tv::cec::V1_0::MaxLength; +using ::android::hardware::tv::cec::V1_0::OptionKey; +using ::android::hardware::tv::cec::V1_0::Result; +using ::android::hardware::tv::cec::V1_0::SendMessageResult; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::hidl_vec; +using ::android::hardware::hidl_string; + namespace android { static struct { @@ -40,15 +56,13 @@ static struct { class HdmiCecController { public: - HdmiCecController(hdmi_cec_device_t* device, jobject callbacksObj, - const sp<Looper>& looper); - - void init(); + HdmiCecController(sp<IHdmiCec> hdmiCec, jobject callbacksObj, const sp<Looper>& looper); + ~HdmiCecController(); // Send message to other device. Note that it runs in IO thread. - int sendMessage(const cec_message_t& message); + int sendMessage(const CecMessage& message); // Add a logical address to device. - int addLogicalAddress(cec_logical_address_t address); + int addLogicalAddress(CecLogicalAddress address); // Clear all logical address registered to the device. void clearLogicaladdress(); // Get physical address of device. @@ -59,10 +73,12 @@ public: uint32_t getVendorId(); // Get Port information on all the HDMI ports. jobjectArray getPortInfos(); - // Set a flag and its value. - void setOption(int flag, int value); - // Set audio return channel status. - void setAudioReturnChannel(int port, bool flag); + // Set an option to CEC HAL. + void setOption(OptionKey key, bool enabled); + // Informs CEC HAL about the current system language. + void setLanguage(hidl_string language); + // Enable audio return channel. + void enableAudioReturnChannel(int port, bool flag); // Whether to hdmi device is connected to the given port. bool isConnected(int port); @@ -71,69 +87,48 @@ public: } private: + class HdmiCecCallback : public IHdmiCecCallback { + public: + HdmiCecCallback(HdmiCecController* controller) : mController(controller) {}; + Return<void> onCecMessage(const CecMessage& event) override; + Return<void> onHotplugEvent(const HotplugEvent& event) override; + private: + HdmiCecController* mController; + }; + static const int INVALID_PHYSICAL_ADDRESS = 0xFFFF; - static void onReceived(const hdmi_event_t* event, void* arg); - hdmi_cec_device_t* mDevice; + sp<IHdmiCec> mHdmiCec; jobject mCallbacksObj; + sp<IHdmiCecCallback> mHdmiCecCallback; sp<Looper> mLooper; }; -// RefBase wrapper for hdmi_event_t. As hdmi_event_t coming from HAL -// may keep its own lifetime, we need to copy it in order to delegate -// it to service thread. -class CecEventWrapper : public LightRefBase<CecEventWrapper> { -public: - explicit CecEventWrapper(const hdmi_event_t& event) { - // Copy message. - switch (event.type) { - case HDMI_EVENT_CEC_MESSAGE: - mEvent.cec.initiator = event.cec.initiator; - mEvent.cec.destination = event.cec.destination; - mEvent.cec.length = event.cec.length; - std::memcpy(mEvent.cec.body, event.cec.body, event.cec.length); - break; - case HDMI_EVENT_HOT_PLUG: - mEvent.hotplug.connected = event.hotplug.connected; - mEvent.hotplug.port_id = event.hotplug.port_id; - break; - default: - // TODO: add more type whenever new type is introduced. - break; - } - } - - const cec_message_t& cec() const { - return mEvent.cec; - } - - const hotplug_event_t& hotplug() const { - return mEvent.hotplug; - } - - virtual ~CecEventWrapper() {} - -private: - hdmi_event_t mEvent; -}; - // Handler class to delegate incoming message to service thread. class HdmiCecEventHandler : public MessageHandler { public: - HdmiCecEventHandler(HdmiCecController* controller, const sp<CecEventWrapper>& event) - : mController(controller), - mEventWrapper(event) { - } + enum EventType { + CEC_MESSAGE, + HOT_PLUG + }; + + HdmiCecEventHandler(HdmiCecController* controller, const CecMessage& cecMessage) + : mController(controller), + mCecMessage(cecMessage) {} + + HdmiCecEventHandler(HdmiCecController* controller, const HotplugEvent& hotplugEvent) + : mController(controller), + mHotplugEvent(hotplugEvent) {} virtual ~HdmiCecEventHandler() {} void handleMessage(const Message& message) { switch (message.what) { - case HDMI_EVENT_CEC_MESSAGE: - propagateCecCommand(mEventWrapper->cec()); + case EventType::CEC_MESSAGE: + propagateCecCommand(mCecMessage); break; - case HDMI_EVENT_HOT_PLUG: - propagateHotplugEvent(mEventWrapper->hotplug()); + case EventType::HOT_PLUG: + propagateHotplugEvent(mHotplugEvent); break; default: // TODO: add more type whenever new type is introduced. @@ -143,14 +138,13 @@ public: private: // Propagate the message up to Java layer. - void propagateCecCommand(const cec_message_t& message) { - jint srcAddr = message.initiator; - jint dstAddr = message.destination; + void propagateCecCommand(const CecMessage& message) { JNIEnv* env = AndroidRuntime::getJNIEnv(); - jbyteArray body = env->NewByteArray(message.length); - const jbyte* bodyPtr = reinterpret_cast<const jbyte *>(message.body); - env->SetByteArrayRegion(body, 0, message.length, bodyPtr); - + jint srcAddr = static_cast<jint>(message.initiator); + jint dstAddr = static_cast<jint>(message.destination); + jbyteArray body = env->NewByteArray(message.body.size()); + const jbyte* bodyPtr = reinterpret_cast<const jbyte *>(message.body.data()); + env->SetByteArrayRegion(body, 0, message.body.size(), bodyPtr); env->CallVoidMethod(mController->getCallbacksObj(), gHdmiCecControllerClassInfo.handleIncomingCecCommand, srcAddr, dstAddr, body); @@ -159,10 +153,10 @@ private: checkAndClearExceptionFromCallback(env, __FUNCTION__); } - void propagateHotplugEvent(const hotplug_event_t& event) { + void propagateHotplugEvent(const HotplugEvent& event) { // Note that this method should be called in service thread. JNIEnv* env = AndroidRuntime::getJNIEnv(); - jint port = event.port_id; + jint port = static_cast<jint>(event.portId); jboolean connected = (jboolean) event.connected; env->CallVoidMethod(mController->getCallbacksObj(), gHdmiCecControllerClassInfo.handleHotplug, port, connected); @@ -180,51 +174,83 @@ private: } HdmiCecController* mController; - sp<CecEventWrapper> mEventWrapper; + CecMessage mCecMessage; + HotplugEvent mHotplugEvent; }; -HdmiCecController::HdmiCecController(hdmi_cec_device_t* device, - jobject callbacksObj, const sp<Looper>& looper) : - mDevice(device), - mCallbacksObj(callbacksObj), - mLooper(looper) { +HdmiCecController::HdmiCecController(sp<IHdmiCec> hdmiCec, + jobject callbacksObj, const sp<Looper>& looper) + : mHdmiCec(hdmiCec), + mCallbacksObj(callbacksObj), + mLooper(looper) { + mHdmiCecCallback = new HdmiCecCallback(this); + Return<void> ret = mHdmiCec->setCallback(mHdmiCecCallback); + if (!ret.getStatus().isOk()) { + ALOGE("Failed to set a cec callback."); + } } -void HdmiCecController::init() { - mDevice->register_event_callback(mDevice, HdmiCecController::onReceived, this); +HdmiCecController::~HdmiCecController() { + Return<void> ret = mHdmiCec->setCallback(nullptr); + if (!ret.getStatus().isOk()) { + ALOGE("Failed to set a cec callback."); + } } -int HdmiCecController::sendMessage(const cec_message_t& message) { +int HdmiCecController::sendMessage(const CecMessage& message) { // TODO: propagate send_message's return value. - return mDevice->send_message(mDevice, &message); + Return<SendMessageResult> ret = mHdmiCec->sendMessage(message); + if (!ret.getStatus().isOk()) { + ALOGE("Failed to send CEC message."); + return static_cast<int>(SendMessageResult::FAIL); + } + return static_cast<int>((SendMessageResult) ret); } -int HdmiCecController::addLogicalAddress(cec_logical_address_t address) { - return mDevice->add_logical_address(mDevice, address); +int HdmiCecController::addLogicalAddress(CecLogicalAddress address) { + Return<Result> ret = mHdmiCec->addLogicalAddress(address); + if (!ret.getStatus().isOk()) { + ALOGE("Failed to add a logical address."); + return static_cast<int>(Result::FAILURE_UNKNOWN); + } + return static_cast<int>((Result) ret); } void HdmiCecController::clearLogicaladdress() { - mDevice->clear_logical_address(mDevice); + Return<void> ret = mHdmiCec->clearLogicalAddress(); + if (!ret.getStatus().isOk()) { + ALOGE("Failed to clear logical address."); + } } int HdmiCecController::getPhysicalAddress() { + Result result; uint16_t addr; - if (!mDevice->get_physical_address(mDevice, &addr)) { - return addr; + Return<void> ret = mHdmiCec->getPhysicalAddress([&result, &addr](Result res, uint16_t paddr) { + result = res; + addr = paddr; + }); + if (!ret.getStatus().isOk()) { + ALOGE("Failed to get physical address."); + return INVALID_PHYSICAL_ADDRESS; } - return INVALID_PHYSICAL_ADDRESS; + return result == Result::SUCCESS ? addr : INVALID_PHYSICAL_ADDRESS; } int HdmiCecController::getVersion() { - int version = 0; - mDevice->get_version(mDevice, &version); - return version; + Return<int32_t> ret = mHdmiCec->getCecVersion(); + if (!ret.getStatus().isOk()) { + ALOGE("Failed to get cec version."); + } + return ret; } uint32_t HdmiCecController::getVendorId() { - uint32_t vendorId = 0; - mDevice->get_vendor_id(mDevice, &vendorId); - return vendorId; + Return<uint32_t> ret = mHdmiCec->getVendorId(); + if (!ret.getStatus().isOk()) { + ALOGE("Failed to get vendor id."); + } + return ret; } jobjectArray HdmiCecController::getPortInfos() { @@ -237,48 +263,69 @@ jobjectArray HdmiCecController::getPortInfos() { if (ctor == NULL) { return NULL; } - hdmi_port_info* ports; - int numPorts; - mDevice->get_port_info(mDevice, &ports, &numPorts); - jobjectArray res = env->NewObjectArray(numPorts, hdmiPortInfo, NULL); + hidl_vec<HdmiPortInfo> ports; + Return<void> ret = mHdmiCec->getPortInfo([&ports](hidl_vec<HdmiPortInfo> list) { + ports = list; + }); + if (!ret.getStatus().isOk()) { + ALOGE("Failed to get port information."); + return NULL; + } + jobjectArray res = env->NewObjectArray(ports.size(), hdmiPortInfo, NULL); // MHL support field will be obtained from MHL HAL. Leave it to false. jboolean mhlSupported = (jboolean) 0; - for (int i = 0; i < numPorts; ++i) { - hdmi_port_info* info = &ports[i]; - jboolean cecSupported = (jboolean) info->cec_supported; - jboolean arcSupported = (jboolean) info->arc_supported; - jobject infoObj = env->NewObject(hdmiPortInfo, ctor, info->port_id, info->type, - info->physical_address, cecSupported, mhlSupported, arcSupported); + for (size_t i = 0; i < ports.size(); ++i) { + jboolean cecSupported = (jboolean) ports[i].cecSupported; + jboolean arcSupported = (jboolean) ports[i].arcSupported; + jobject infoObj = env->NewObject(hdmiPortInfo, ctor, ports[i].portId, ports[i].type, + ports[i].physicalAddress, cecSupported, mhlSupported, arcSupported); env->SetObjectArrayElement(res, i, infoObj); } return res; } -void HdmiCecController::setOption(int flag, int value) { - mDevice->set_option(mDevice, flag, value); +void HdmiCecController::setOption(OptionKey key, bool enabled) { + Return<void> ret = mHdmiCec->setOption(key, enabled); + if (!ret.getStatus().isOk()) { + ALOGE("Failed to set option."); + } } -// Set audio return channel status. - void HdmiCecController::setAudioReturnChannel(int port, bool enabled) { - mDevice->set_audio_return_channel(mDevice, port, enabled ? 1 : 0); +void HdmiCecController::setLanguage(hidl_string language) { + Return<void> ret = mHdmiCec->setLanguage(language); + if (!ret.getStatus().isOk()) { + ALOGE("Failed to set language."); + } +} + +// Enable audio return channel. +void HdmiCecController::enableAudioReturnChannel(int port, bool enabled) { + Return<void> ret = mHdmiCec->enableAudioReturnChannel(port, enabled); + if (!ret.getStatus().isOk()) { + ALOGE("Failed to enable/disable ARC."); + } } // Whether to hdmi device is connected to the given port. bool HdmiCecController::isConnected(int port) { - return mDevice->is_connected(mDevice, port) == HDMI_CONNECTED; + Return<bool> ret = mHdmiCec->isConnected(port); + if (!ret.getStatus().isOk()) { + ALOGE("Failed to get connection info."); + } + return ret; } -// static -void HdmiCecController::onReceived(const hdmi_event_t* event, void* arg) { - HdmiCecController* controller = static_cast<HdmiCecController*>(arg); - if (controller == NULL) { - return; - } +Return<void> HdmiCecController::HdmiCecCallback::onCecMessage(const CecMessage& message) { + sp<HdmiCecEventHandler> handler(new HdmiCecEventHandler(mController, message)); + mController->mLooper->sendMessage(handler, HdmiCecEventHandler::EventType::CEC_MESSAGE); + return Void(); +} - sp<CecEventWrapper> spEvent(new CecEventWrapper(*event)); - sp<HdmiCecEventHandler> handler(new HdmiCecEventHandler(controller, spEvent)); - controller->mLooper->sendMessage(handler, event->type); +Return<void> HdmiCecController::HdmiCecCallback::onHotplugEvent(const HotplugEvent& event) { + sp<HdmiCecEventHandler> handler(new HdmiCecEventHandler(mController, event)); + mController->mLooper->sendMessage(handler, HdmiCecEventHandler::EventType::HOT_PLUG); + return Void(); } //------------------------------------------------------------------------------ @@ -288,30 +335,19 @@ void HdmiCecController::onReceived(const hdmi_event_t* event, void* arg) { static jlong nativeInit(JNIEnv* env, jclass clazz, jobject callbacksObj, jobject messageQueueObj) { - int err; - hw_module_t* module; - err = hw_get_module(HDMI_CEC_HARDWARE_MODULE_ID, - const_cast<const hw_module_t **>(&module)); - if (err != 0) { - ALOGE("Error acquiring hardware module: %d", err); - return 0; - } - - hw_device_t* device; - err = module->methods->open(module, HDMI_CEC_HARDWARE_INTERFACE, &device); - if (err != 0) { - ALOGE("Error opening hardware module: %d", err); + // TODO(b/31632518) + sp<IHdmiCec> hdmiCec = IHdmiCec::getService("tv.cec"); + if (hdmiCec == nullptr) { + ALOGE("Couldn't get tv.cec service."); return 0; } - sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj); HdmiCecController* controller = new HdmiCecController( - reinterpret_cast<hdmi_cec_device*>(device), + hdmiCec, env->NewGlobalRef(callbacksObj), messageQueue->getLooper()); - controller->init(); GET_METHOD_ID(gHdmiCecControllerClassInfo.handleIncomingCecCommand, clazz, "handleIncomingCecCommand", "(II[B)V"); @@ -323,14 +359,18 @@ static jlong nativeInit(JNIEnv* env, jclass clazz, jobject callbacksObj, static jint nativeSendCecCommand(JNIEnv* env, jclass clazz, jlong controllerPtr, jint srcAddr, jint dstAddr, jbyteArray body) { - cec_message_t message; - message.initiator = static_cast<cec_logical_address_t>(srcAddr); - message.destination = static_cast<cec_logical_address_t>(dstAddr); + CecMessage message; + message.initiator = static_cast<CecLogicalAddress>(srcAddr); + message.destination = static_cast<CecLogicalAddress>(dstAddr); jsize len = env->GetArrayLength(body); - message.length = MIN(len, CEC_MESSAGE_BODY_MAX_LENGTH); ScopedByteArrayRO bodyPtr(env, body); - std::memcpy(message.body, bodyPtr.get(), message.length); + size_t bodyLength = MIN(static_cast<size_t>(len), + static_cast<size_t>(MaxLength::MESSAGE_BODY)); + message.body.resize(bodyLength); + for (size_t i = 0; i < bodyLength; ++i) { + message.body[i] = static_cast<uint8_t>(bodyPtr[i]); + } HdmiCecController* controller = reinterpret_cast<HdmiCecController*>(controllerPtr); @@ -340,7 +380,7 @@ static jint nativeSendCecCommand(JNIEnv* env, jclass clazz, jlong controllerPtr, static jint nativeAddLogicalAddress(JNIEnv* env, jclass clazz, jlong controllerPtr, jint logicalAddress) { HdmiCecController* controller = reinterpret_cast<HdmiCecController*>(controllerPtr); - return controller->addLogicalAddress(static_cast<cec_logical_address_t>(logicalAddress)); + return controller->addLogicalAddress(static_cast<CecLogicalAddress>(logicalAddress)); } static void nativeClearLogicalAddress(JNIEnv* env, jclass clazz, jlong controllerPtr) { @@ -370,13 +410,20 @@ static jobjectArray nativeGetPortInfos(JNIEnv* env, jclass clazz, jlong controll static void nativeSetOption(JNIEnv* env, jclass clazz, jlong controllerPtr, jint flag, jint value) { HdmiCecController* controller = reinterpret_cast<HdmiCecController*>(controllerPtr); - controller->setOption(flag, value); + controller->setOption(static_cast<OptionKey>(flag), value > 0 ? true : false); +} + +static void nativeSetLanguage(JNIEnv* env, jclass clazz, jlong controllerPtr, jstring language) { + HdmiCecController* controller = reinterpret_cast<HdmiCecController*>(controllerPtr); + const char *languageStr = env->GetStringUTFChars(language, NULL); + controller->setLanguage(languageStr); + env->ReleaseStringUTFChars(language, languageStr); } -static void nativeSetAudioReturnChannel(JNIEnv* env, jclass clazz, jlong controllerPtr, +static void nativeEnableAudioReturnChannel(JNIEnv* env, jclass clazz, jlong controllerPtr, jint port, jboolean enabled) { HdmiCecController* controller = reinterpret_cast<HdmiCecController*>(controllerPtr); - controller->setAudioReturnChannel(port, enabled == JNI_TRUE); + controller->enableAudioReturnChannel(port, enabled == JNI_TRUE); } static jboolean nativeIsConnected(JNIEnv* env, jclass clazz, jlong controllerPtr, jint port) { @@ -398,8 +445,9 @@ static const JNINativeMethod sMethods[] = { { "nativeGetPortInfos", "(J)[Landroid/hardware/hdmi/HdmiPortInfo;", (void *) nativeGetPortInfos }, - { "nativeSetOption", "(JII)V", (void *) nativeSetOption }, - { "nativeSetAudioReturnChannel", "(JIZ)V", (void *) nativeSetAudioReturnChannel }, + { "nativeSetOption", "(JIZ)V", (void *) nativeSetOption }, + { "nativeSetLanguage", "(JLjava/lang/String;)V", (void *) nativeSetLanguage }, + { "nativeEnableAudioReturnChannel", "(JIZ)V", (void *) nativeEnableAudioReturnChannel }, { "nativeIsConnected", "(JI)Z", (void *) nativeIsConnected }, }; diff --git a/services/core/jni/com_android_server_storage_AppFuseBridge.cpp b/services/core/jni/com_android_server_storage_AppFuseBridge.cpp new file mode 100644 index 000000000000..640fd0e55127 --- /dev/null +++ b/services/core/jni/com_android_server_storage_AppFuseBridge.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specic language governing permissions and + * limitations under the License. + */ + +// Need to use LOGE_EX. +#define LOG_TAG "AppFuseBridge" + +#include <android_runtime/Log.h> +#include <android-base/logging.h> +#include <core_jni_helpers.h> +#include <libappfuse/FuseBridgeLoop.h> +#include <nativehelper/JNIHelp.h> + +namespace android { +namespace { + +constexpr const char* CLASS_NAME = "com/android/server/storage/AppFuseBridge"; +static jclass appFuseClass; +static jmethodID appFuseOnMount; + +class Callback : public FuseBridgeLoop::Callback { + JNIEnv* mEnv; + jobject mSelf; + +public: + Callback(JNIEnv* env, jobject self) : mEnv(env), mSelf(self) {} + void OnMount() override { + mEnv->CallVoidMethod(mSelf, appFuseOnMount); + if (mEnv->ExceptionCheck()) { + LOGE_EX(mEnv, nullptr); + mEnv->ExceptionClear(); + } + } +}; + +jboolean com_android_server_storage_AppFuseBridge_start_loop( + JNIEnv* env, jobject self, jint devJavaFd, jint proxyJavaFd) { + FuseBridgeLoop loop; + Callback callback(env, self); + return loop.Start(devJavaFd, proxyJavaFd, &callback); +} + +const JNINativeMethod methods[] = { + { + "native_start_loop", + "(II)Z", + (void *) com_android_server_storage_AppFuseBridge_start_loop + } +}; + +} // namespace + +void register_android_server_storage_AppFuse(JNIEnv* env) { + CHECK(env != nullptr); + + appFuseClass = MakeGlobalRefOrDie(env, FindClassOrDie(env, CLASS_NAME)); + appFuseOnMount = GetMethodIDOrDie(env, appFuseClass, "onMount", "()V"); + RegisterMethodsOrDie(env, CLASS_NAME, methods, NELEM(methods)); +} +} // namespace android diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp index d69c37f0afea..c291ba0dc24a 100644 --- a/services/core/jni/onload.cpp +++ b/services/core/jni/onload.cpp @@ -28,6 +28,7 @@ int register_android_server_InputWindowHandle(JNIEnv* env); int register_android_server_InputManager(JNIEnv* env); int register_android_server_LightsService(JNIEnv* env); int register_android_server_PowerManagerService(JNIEnv* env); +int register_android_server_storage_AppFuse(JNIEnv* env); int register_android_server_SerialService(JNIEnv* env); int register_android_server_SystemServer(JNIEnv* env); int register_android_server_UsbDeviceManager(JNIEnv* env); @@ -83,6 +84,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) register_android_server_PersistentDataBlockService(env); register_android_server_Watchdog(env); register_android_server_HardwarePropertiesManagerService(env); + register_android_server_storage_AppFuse(env); return JNI_VERSION_1_4; } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 0ea8d4e5101d..7f8b9b814533 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -22,7 +22,7 @@ import static android.app.admin.DevicePolicyManager.WIPE_EXTERNAL_STORAGE; import static android.app.admin.DevicePolicyManager.WIPE_RESET_PROTECTION_DATA; import static android.content.pm.PackageManager.GET_UNINSTALLED_PACKAGES; -import static com.android.internal.logging.MetricsProto.MetricsEvent.PROVISIONING_ENTRY_POINT_ADB; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.PROVISIONING_ENTRY_POINT_ADB; import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW; import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; import static org.xmlpull.v1.XmlPullParser.END_TAG; diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 6614fe3a31e3..3db24fa28d9f 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -185,6 +185,8 @@ public final class SystemServer { "com.android.server.content.ContentService$Lifecycle"; private static final String WALLPAPER_SERVICE_CLASS = "com.android.server.wallpaper.WallpaperManagerService$Lifecycle"; + private static final String AUTO_FILL_MANAGER_SERVICE_CLASS = + "com.android.server.autofill.AutoFillManagerService"; private static final String PERSISTENT_DATA_BLOCK_PROP = "ro.frp.pst"; @@ -1366,6 +1368,10 @@ public final class SystemServer { mSystemServiceManager.startService(RetailDemoModeService.class); traceEnd(); + traceBeginAndSlog("StartAutoFillService"); + mSystemServiceManager.startService(AUTO_FILL_MANAGER_SERVICE_CLASS); + traceEnd(); + // It is now time to start up the app processes... traceBeginAndSlog("MakeVibratorServiceReady"); diff --git a/services/net/java/android/net/ip/IpManager.java b/services/net/java/android/net/ip/IpManager.java index 01d93048bfe2..39f14e5ee287 100644 --- a/services/net/java/android/net/ip/IpManager.java +++ b/services/net/java/android/net/ip/IpManager.java @@ -631,6 +631,11 @@ public class IpManager extends StateMachine { return shouldLog; } + // TODO: Migrate all Log.e(...) to logError(...). + private void logError(String fmt, Object... args) { + mLocalLog.log("ERROR " + String.format(fmt, args)); + } + private void getNetworkInterface() { try { mNetworkInterface = NetworkInterface.getByName(mInterfaceName); @@ -880,7 +885,7 @@ public class IpManager extends StateMachine { mNwService.setInterfaceConfig(mInterfaceName, ifcg); if (VDBG) Log.d(mTag, "IPv4 configuration succeeded"); } catch (IllegalStateException | RemoteException e) { - Log.e(mTag, "IPv4 configuration failed: ", e); + logError("IPv4 configuration failed: %s", e); return false; } return true; @@ -944,6 +949,12 @@ public class IpManager extends StateMachine { } } + private void doImmediateProvisioningFailure(int failureType) { + if (DBG) { Log.e(mTag, "onProvisioningFailure(): " + failureType); } + recordMetric(failureType); + mCallback.onProvisioningFailure(new LinkProperties(mLinkProperties)); + } + private boolean startIPv4() { // If we have a StaticIpConfiguration attempt to apply it and // handle the result accordingly. @@ -951,9 +962,6 @@ public class IpManager extends StateMachine { if (setIPv4Address(mConfiguration.mStaticIpConfig.ipAddress)) { handleIPv4Success(new DhcpResults(mConfiguration.mStaticIpConfig)); } else { - if (VDBG) { Log.d(mTag, "onProvisioningFailure()"); } - recordMetric(IpManagerEvent.PROVISIONING_FAIL); - mCallback.onProvisioningFailure(new LinkProperties(mLinkProperties)); return false; } } else { @@ -972,16 +980,40 @@ public class IpManager extends StateMachine { mNwService.setInterfaceIpv6PrivacyExtensions(mInterfaceName, true); mNwService.enableIpv6(mInterfaceName); } catch (RemoteException re) { - Log.e(mTag, "Unable to change interface settings: " + re); + logError("Unable to change interface settings: %s", re); return false; } catch (IllegalStateException ie) { - Log.e(mTag, "Unable to change interface settings: " + ie); + logError("Unable to change interface settings: %s", ie); return false; } return true; } + private boolean startIpReachabilityMonitor() { + try { + mIpReachabilityMonitor = new IpReachabilityMonitor( + mContext, + mInterfaceName, + new IpReachabilityMonitor.Callback() { + @Override + public void notifyLost(InetAddress ip, String logMsg) { + mCallback.onReachabilityLost(logMsg); + } + }, + mAvoidBadWifiTracker); + } catch (IllegalArgumentException iae) { + // Failed to start IpReachabilityMonitor. Log it and call + // onProvisioningFailure() immediately. + // + // See http://b/31038971. + logError("IpReachabilityMonitor failure: %s", iae); + mIpReachabilityMonitor = null; + } + + return (mIpReachabilityMonitor != null); + } + private void stopAllIP() { // We don't need to worry about routes, just addresses, because: // - disableIpv6() will clear autoconf IPv6 routes as well, and @@ -1165,29 +1197,23 @@ public class IpManager extends StateMachine { mCallback.setFallbackMulticastFilter(mMulticastFiltering); } - if (mConfiguration.mEnableIPv6) { - // TODO: Consider transitionTo(mStoppingState) if this fails. - startIPv6(); + if (mConfiguration.mEnableIPv6 && !startIPv6()) { + doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV6); + transitionTo(mStoppingState); + return; } - if (mConfiguration.mEnableIPv4) { - if (!startIPv4()) { - transitionTo(mStoppingState); - return; - } + if (mConfiguration.mEnableIPv4 && !startIPv4()) { + doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV4); + transitionTo(mStoppingState); + return; } - if (mConfiguration.mUsingIpReachabilityMonitor) { - mIpReachabilityMonitor = new IpReachabilityMonitor( - mContext, - mInterfaceName, - new IpReachabilityMonitor.Callback() { - @Override - public void notifyLost(InetAddress ip, String logMsg) { - mCallback.onReachabilityLost(logMsg); - } - }, - mAvoidBadWifiTracker); + if (mConfiguration.mUsingIpReachabilityMonitor && !startIpReachabilityMonitor()) { + doImmediateProvisioningFailure( + IpManagerEvent.ERROR_STARTING_IPREACHABILITYMONITOR); + transitionTo(mStoppingState); + return; } } diff --git a/services/print/java/com/android/server/print/UserState.java b/services/print/java/com/android/server/print/UserState.java index 65c740f9ca3e..7474a64c32cb 100644 --- a/services/print/java/com/android/server/print/UserState.java +++ b/services/print/java/com/android/server/print/UserState.java @@ -68,7 +68,7 @@ import android.util.SparseArray; import com.android.internal.R; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.os.BackgroundThread; import com.android.internal.os.SomeArgs; import com.android.server.print.RemotePrintService.PrintServiceCallbacks; diff --git a/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java index 4570a4b432a8..d20e351157cb 100644 --- a/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java +++ b/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java @@ -226,11 +226,11 @@ public class BuzzBeepBlinkTest { if (insistent) { n.flags |= Notification.FLAG_INSISTENT; } - StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, id, mTag, mUid, mPid, - mScore, n, mUser, System.currentTimeMillis()); - NotificationRecord r = new NotificationRecord(getContext(), sbn, - new NotificationChannel(NotificationChannel.DEFAULT_CHANNEL_ID, "misc", - NotificationManager.IMPORTANCE_DEFAULT)); + NotificationChannel channel = + new NotificationChannel("test", "test", NotificationManager.IMPORTANCE_HIGH); + StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, channel, id, mTag, mUid, + mPid, n, mUser, null, System.currentTimeMillis()); + NotificationRecord r = new NotificationRecord(getContext(), sbn); mService.addNotification(r); return r; } diff --git a/services/tests/notification/src/com/android/server/notification/GroupHelperTest.java b/services/tests/notification/src/com/android/server/notification/GroupHelperTest.java index 22b674b93b09..6c3f44778ae6 100644 --- a/services/tests/notification/src/com/android/server/notification/GroupHelperTest.java +++ b/services/tests/notification/src/com/android/server/notification/GroupHelperTest.java @@ -31,6 +31,7 @@ import org.mockito.MockitoAnnotations; import android.app.AlarmManager; import android.app.Notification; import android.app.NotificationChannel; +import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.os.UserHandle; @@ -68,7 +69,10 @@ public class GroupHelperTest { if (groupKey != null) { nb.setGroup(groupKey); } - return new StatusBarNotification(pkg, pkg, id, tag, 0, 0, 0, nb.build(), user); + NotificationChannel channel = + new NotificationChannel("test", "test", NotificationManager.IMPORTANCE_LOW); + return new StatusBarNotification(pkg, pkg, channel, id, tag, 0, 0, nb.build(), user, null, + System.currentTimeMillis()); } private StatusBarNotification getSbn(String pkg, int id, String tag, diff --git a/services/tests/notification/src/com/android/server/notification/ImportanceExtractorTest.java b/services/tests/notification/src/com/android/server/notification/ImportanceExtractorTest.java index 305b5e0acd84..6bc96754e200 100644 --- a/services/tests/notification/src/com/android/server/notification/ImportanceExtractorTest.java +++ b/services/tests/notification/src/com/android/server/notification/ImportanceExtractorTest.java @@ -69,9 +69,9 @@ public class ImportanceExtractorTest { .setDefaults(Notification.DEFAULT_SOUND); Notification n = builder.build(); - StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, mId, mTag, mUid, - mPid, mScore, n, mUser, System.currentTimeMillis()); - NotificationRecord r = new NotificationRecord(getContext(), sbn, channel); + StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, channel, mId, mTag, mUid, + mPid, n, mUser, null, System.currentTimeMillis()); + NotificationRecord r = new NotificationRecord(getContext(), sbn); return r; } diff --git a/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java b/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java index 629146f19006..92c67b5b0aa9 100644 --- a/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java +++ b/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java @@ -98,8 +98,8 @@ public class RankingHelperTest { .setWhen(1205) .build(); mRecordGroupGSortA = new NotificationRecord(getContext(), new StatusBarNotification( - "package", "package", 1, null, 0, 0, 0, mNotiGroupGSortA, user), - getDefaultChannel()); + "package", "package", getDefaultChannel(), 1, null, 0, 0, mNotiGroupGSortA, user, + null, System.currentTimeMillis())); mNotiGroupGSortB = new Notification.Builder(getContext()) .setContentTitle("B") @@ -108,24 +108,24 @@ public class RankingHelperTest { .setWhen(1200) .build(); mRecordGroupGSortB = new NotificationRecord(getContext(), new StatusBarNotification( - "package", "package", 1, null, 0, 0, 0, mNotiGroupGSortB, user), - getDefaultChannel()); + "package", "package", getDefaultChannel(), 1, null, 0, 0, mNotiGroupGSortB, user, + null, System.currentTimeMillis())); mNotiNoGroup = new Notification.Builder(getContext()) .setContentTitle("C") .setWhen(1201) .build(); mRecordNoGroup = new NotificationRecord(getContext(), new StatusBarNotification( - "package", "package", 1, null, 0, 0, 0, mNotiNoGroup, user), - getDefaultChannel()); + "package", "package", getDefaultChannel(), 1, null, 0, 0, mNotiNoGroup, user, + null, System.currentTimeMillis())); mNotiNoGroup2 = new Notification.Builder(getContext()) .setContentTitle("D") .setWhen(1202) .build(); mRecordNoGroup2 = new NotificationRecord(getContext(), new StatusBarNotification( - "package", "package", 1, null, 0, 0, 0, mNotiNoGroup2, user), - getDefaultChannel()); + "package", "package", getDefaultChannel(), 1, null, 0, 0, mNotiNoGroup2, user, + null, System.currentTimeMillis())); mNotiNoGroupSortA = new Notification.Builder(getContext()) .setContentTitle("E") @@ -133,8 +133,8 @@ public class RankingHelperTest { .setSortKey("A") .build(); mRecordNoGroupSortA = new NotificationRecord(getContext(), new StatusBarNotification( - "package", "package", 1, null, 0, 0, 0, mNotiNoGroupSortA, user), - getDefaultChannel()); + "package", "package", getDefaultChannel(), 1, null, 0, 0, mNotiNoGroupSortA, user, + null, System.currentTimeMillis())); final ApplicationInfo legacy = new ApplicationInfo(); legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1; diff --git a/services/tests/notification/src/com/android/server/notification/SnoozeHelperTest.java b/services/tests/notification/src/com/android/server/notification/SnoozeHelperTest.java index ffc45ea96e91..7a3ee7f4c068 100644 --- a/services/tests/notification/src/com/android/server/notification/SnoozeHelperTest.java +++ b/services/tests/notification/src/com/android/server/notification/SnoozeHelperTest.java @@ -178,9 +178,13 @@ public class SnoozeHelperTest { .setWhen(1205) .build(); return new NotificationRecord(getContext(), new StatusBarNotification( - pkg, pkg, id, tag, 0, 0, 0, n, user), - new NotificationChannel(NotificationChannel.DEFAULT_CHANNEL_ID, "name", - NotificationManager.IMPORTANCE_HIGH)); + pkg, pkg, getDefaultChannel(), id, tag, 0, 0, n, user, null, + System.currentTimeMillis())); + } + + private NotificationChannel getDefaultChannel() { + return new NotificationChannel(NotificationChannel.DEFAULT_CHANNEL_ID, "name", + NotificationManager.IMPORTANCE_LOW); } } diff --git a/services/tests/servicestests/src/com/android/server/LockSettingsShellCommandTest.java b/services/tests/servicestests/src/com/android/server/LockSettingsShellCommandTest.java new file mode 100644 index 000000000000..d6ee367e0bbd --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/LockSettingsShellCommandTest.java @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.server; + +import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC; +import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC; + +import static com.android.internal.widget.LockPatternUtils.stringToPattern; + +import static junit.framework.Assert.*; + +import static org.mockito.Matchers.anyInt; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import static java.io.FileDescriptor.*; + +import android.app.ActivityManager; +import android.content.Context; +import android.os.Binder; +import android.os.Debug; +import android.os.Handler; +import android.os.Looper; +import android.os.ResultReceiver; +import android.os.ShellCallback; +import android.platform.test.annotations.Presubmit; +import android.support.test.InstrumentationRegistry; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; + +import com.android.internal.widget.LockPatternUtils; + +import junit.framework.Assert; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.io.FileDescriptor; + +/** + * Test class for {@link LockSettingsShellCommand}. + * + * runtest frameworks-services -c com.android.server.LockSettingsShellCommandTest + */ +@SmallTest +@Presubmit +@RunWith(AndroidJUnit4.class) +public class LockSettingsShellCommandTest { + + private LockSettingsShellCommand mCommand; + + private @Mock LockPatternUtils mLockPatternUtils; + private int mUserId; + private final Binder mBinder = new Binder(); + private final ShellCallback mShellCallback = new ShellCallback(); + private final ResultReceiver mResultReceiver = new ResultReceiver( + new Handler(Looper.getMainLooper())); + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + final Context context = InstrumentationRegistry.getTargetContext(); + mUserId = ActivityManager.getCurrentUser(); + mCommand = new LockSettingsShellCommand(context, mLockPatternUtils); + } + + @Test + public void testWrongPassword() throws Exception { + when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(false); + when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(true); + when(mLockPatternUtils.checkPassword("1234", mUserId)).thenReturn(false); + assertEquals(-1, mCommand.exec(mBinder, in, out, err, + new String[] { "set-pin", "--old", "1234" }, + mShellCallback, mResultReceiver)); + verify(mLockPatternUtils, never()).saveLockPassword(any(), any(), anyInt(), anyInt()); + } + + @Test + public void testChangePin() throws Exception { + when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(false); + when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(true); + when(mLockPatternUtils.checkPassword("1234", mUserId)).thenReturn(true); + assertEquals(0, mCommand.exec(new Binder(), in, out, err, + new String[] { "set-pin", "--old", "1234", "4321" }, + mShellCallback, mResultReceiver)); + verify(mLockPatternUtils).saveLockPassword("4321", "1234", PASSWORD_QUALITY_NUMERIC, + mUserId); + } + + @Test + public void testChangePassword() throws Exception { + when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(false); + when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(true); + when(mLockPatternUtils.checkPassword("1234", mUserId)).thenReturn(true); + assertEquals(0, mCommand.exec(new Binder(), in, out, err, + new String[] { "set-password", "--old", "1234", "4321" }, + mShellCallback, mResultReceiver)); + verify(mLockPatternUtils).saveLockPassword("4321", "1234", PASSWORD_QUALITY_ALPHABETIC, + mUserId); + } + + @Test + public void testChangePattern() throws Exception { + when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(true); + when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(false); + when(mLockPatternUtils.checkPattern(stringToPattern("1234"), mUserId)).thenReturn(true); + assertEquals(0, mCommand.exec(new Binder(), in, out, err, + new String[] { "set-pattern", "--old", "1234", "4321" }, + mShellCallback, mResultReceiver)); + verify(mLockPatternUtils).saveLockPattern(stringToPattern("4321"), "1234", mUserId); + } + + @Test + public void testClear() throws Exception { + when(mLockPatternUtils.isLockPatternEnabled(mUserId)).thenReturn(true); + when(mLockPatternUtils.isLockPasswordEnabled(mUserId)).thenReturn(false); + when(mLockPatternUtils.checkPattern(stringToPattern("1234"), mUserId)).thenReturn(true); + assertEquals(0, mCommand.exec(new Binder(), in, out, err, + new String[] { "clear", "--old", "1234" }, + mShellCallback, mResultReceiver)); + verify(mLockPatternUtils).clearLock(mUserId); + } +} diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java index 42d94124d0fe..3114f3fc2b26 100644 --- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java @@ -246,7 +246,8 @@ public class NetworkPolicyManagerServiceTest { Log.d(TAG, "set mUidObserver to " + mUidObserver); return null; } - }).when(mActivityManager).registerUidObserver(any(), anyInt(), null); + }).when(mActivityManager).registerUidObserver(any(), anyInt(), + ActivityManager.PROCESS_STATE_UNKNOWN, null); mService = new NetworkPolicyManagerService(mServiceContext, mActivityManager, mStatsService, mNetworkManager, mIpm, mTime, mPolicyDir, true); diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java index 792f3001c049..9f01773eea10 100644 --- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java @@ -737,6 +737,10 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { // Start the service. initService(); setCaller(CALLING_PACKAGE_1); + + if (ENABLE_DUMP) { + Log.d(TAG, "setUp done"); + } } private static boolean b(Boolean value) { diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java index 3cfdc329a971..771ca1467d61 100644 --- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java +++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java @@ -4181,7 +4181,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { assertEquals(START_TIME, findShortcut(shortcuts.getValue(), "s4").getLastChangedTimestamp()); - // Next, send unlock even on user-10. Now we scan packages on this user and send a + // Next, send an unlock event on user-10. Now we scan packages on this user and send a // notification to the launcher. mInjectedCurrentTimeMillis = START_TIME + 200; @@ -4222,9 +4222,8 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { updatePackageVersion(CALLING_PACKAGE_2, 10); // Then send the broadcast, to only user-0. - mService.mPackageMonitor.onReceive(getTestContext(), + mService.mPackageMonitor.onReceive(getTestContext(), genPackageUpdateIntent(CALLING_PACKAGE_2, USER_0)); - mService.checkPackageChanges(USER_10); waitOnMainThread(); @@ -4395,7 +4394,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); // Next. - // Update the build finger print. All system apps will be scanned now. + // Update the build finger print. All apps will be scanned now. mInjectedBuildFingerprint = "update1"; mInjectedCurrentTimeMillis += 1000; mService.checkPackageChanges(USER_0); @@ -4406,12 +4405,11 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { assertWith(getCallerShortcuts()) - .isEmpty(); + .haveIds("ms1"); }); // Next. // Update manifest shortcuts. - mInjectedBuildFingerprint = "update2"; addManifestShortcutResource( new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_2); @@ -4421,35 +4419,20 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { mInjectedCurrentTimeMillis += 1000; mService.checkPackageChanges(USER_0); - // Fingerprint hasn't changed, so CALLING_PACKAGE_1 wasn't scanned. + // Fingerprint hasn't changed, so there packages weren't scanned. runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { assertWith(getCallerShortcuts()) .haveIds("ms1"); }); runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { assertWith(getCallerShortcuts()) - .isEmpty(); - }); - - // Update the fingerprint, but CALLING_PACKAGE_1's version code hasn't changed, so - // still not scanned. - mInjectedBuildFingerprint = "update2"; - mInjectedCurrentTimeMillis += 1000; - mService.checkPackageChanges(USER_0); - - runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { - assertWith(getCallerShortcuts()) .haveIds("ms1"); }); - runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { - assertWith(getCallerShortcuts()) - .isEmpty(); - }); - // Now update the version code, so CALLING_PACKAGE_1 is scanned again. - mInjectedBuildFingerprint = "update3"; + // Update the fingerprint. CALLING_PACKAGE_1's version code hasn't changed, but we scan + // all apps anyway. + mInjectedBuildFingerprint = "update2"; mInjectedCurrentTimeMillis += 1000; - updatePackageVersion(CALLING_PACKAGE_1, 1); mService.checkPackageChanges(USER_0); runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { @@ -4458,7 +4441,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { assertWith(getCallerShortcuts()) - .isEmpty(); + .haveIds("ms1", "ms2"); }); // Make sure getLastAppScanTime / getLastAppScanOsFingerprint are persisted. @@ -5721,6 +5704,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { R.xml.shortcut_5); // Unlock user-0. + mInjectedCurrentTimeMillis += 100; mService.handleUnlockUser(USER_0); runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { @@ -5750,6 +5734,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { uninstallPackage(USER_10, CALLING_PACKAGE_1); uninstallPackage(USER_10, CALLING_PACKAGE_3); + mInjectedCurrentTimeMillis += 100; mService.handleUnlockUser(USER_10); runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { @@ -5774,6 +5759,8 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { // hasn't changed. shutdownServices(); + mInjectedCurrentTimeMillis += 100; + addManifestShortcutResource( new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_5); @@ -5785,7 +5772,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { mService.handleUnlockUser(USER_0); runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { - assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled( + assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled( // FAIL mManager.getManifestShortcuts()))), "ms1"); assertEmpty(mManager.getPinnedShortcuts()); @@ -5808,6 +5795,8 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { // Do it again, but this time we change the app version, so we do detect the changes. shutdownServices(); + mInjectedCurrentTimeMillis += 100; + updatePackageVersion(CALLING_PACKAGE_1, 1); updatePackageLastUpdateTime(CALLING_PACKAGE_3, 1); @@ -5870,6 +5859,8 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { shutdownServices(); + mInjectedCurrentTimeMillis += 100; + addManifestShortcutResource( new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_0); diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index d75dd7d1f6f1..dcf2f0696bfd 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -4650,32 +4650,46 @@ public class TelephonyManager { /* <p>Requires permission: * @link android.Manifest.permission#CALL_PHONE} + * @param ussdRequest the USSD command to be executed. + * @param wrappedCallback receives a callback result. */ @RequiresPermission(android.Manifest.permission.CALL_PHONE) public void sendUssdRequest(String ussdRequest, final OnReceiveUssdResponseCallback callback, Handler handler) { - checkNotNull(callback, "OnReceiveUssdResponseCallback cannot be null."); - - ResultReceiver wrappedCallback = new ResultReceiver(handler) { - @Override - protected void onReceiveResult(int resultCode, Bundle ussdResponse) { - Rlog.d(TAG, "USSD:" + resultCode); - checkNotNull(ussdResponse, "ussdResponse cannot be null."); - UssdResponse response = ussdResponse.getParcelable(USSD_RESPONSE); - - if (resultCode == USSD_RETURN_SUCCESS) { - callback.onReceiveUssdResponse(response.getUssdRequest(), - response.getReturnMessage()); - } else { - callback.onReceiveUssdResponseFailed(response.getUssdRequest(), resultCode); - } - } + sendUssdRequest(ussdRequest, getSubId(), callback, handler); + } + + /* <p>Requires permission: + * @link android.Manifest.permission#CALL_PHONE} + * @param subId The subscription to use. + * @param ussdRequest the USSD command to be executed. + * @param wrappedCallback receives a callback result. + */ + @RequiresPermission(android.Manifest.permission.CALL_PHONE) + public void sendUssdRequest(String ussdRequest, int subId, + final OnReceiveUssdResponseCallback callback, Handler handler) { + checkNotNull(callback, "OnReceiveUssdResponseCallback cannot be null."); + + ResultReceiver wrappedCallback = new ResultReceiver(handler) { + @Override + protected void onReceiveResult(int resultCode, Bundle ussdResponse) { + Rlog.d(TAG, "USSD:" + resultCode); + checkNotNull(ussdResponse, "ussdResponse cannot be null."); + UssdResponse response = ussdResponse.getParcelable(USSD_RESPONSE); + + if (resultCode == USSD_RETURN_SUCCESS) { + callback.onReceiveUssdResponse(response.getUssdRequest(), + response.getReturnMessage()); + } else { + callback.onReceiveUssdResponseFailed(response.getUssdRequest(), resultCode); + } + } }; try { ITelephony telephony = getITelephony(); if (telephony != null) { - telephony.handleUssdRequest(ussdRequest, wrappedCallback); + telephony.handleUssdRequest(subId, ussdRequest, wrappedCallback); } } catch (RemoteException e) { Log.e(TAG, "Error calling ITelephony#sendUSSDCode", e); diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 4c66be1955df..9c62988c0e25 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -275,10 +275,11 @@ interface ITelephony { /** * Handles USSD commands. * + * @param subId The subscription to use. * @param ussdRequest the USSD command to be executed. * @param wrappedCallback receives a callback result. */ - void handleUssdRequest(String ussdRequest, in ResultReceiver wrappedCallback); + void handleUssdRequest(int subId, String ussdRequest, in ResultReceiver wrappedCallback); /** * Handles PIN MMI commands (PIN/PIN2/PUK/PUK2), which are initiated diff --git a/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java b/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java index 6ff0c5a8595e..6a064d271bcc 100644 --- a/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java +++ b/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java @@ -25,7 +25,7 @@ import static com.android.server.connectivity.MetricsTestUtil.anInt; import static com.android.server.connectivity.MetricsTestUtil.anIntArray; import static com.android.server.connectivity.MetricsTestUtil.b; import static com.android.server.connectivity.MetricsTestUtil.describeIpEvent; -import static com.android.server.connectivity.metrics.IpConnectivityLogClass.IpConnectivityLog; +import static com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityLog; import android.net.ConnectivityMetricsEvent; import android.net.metrics.ApfProgramEvent; diff --git a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java b/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java index c7982b1a1f39..78d16d93287e 100644 --- a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java +++ b/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java @@ -34,7 +34,7 @@ import android.net.metrics.ValidationProbeEvent; import android.os.Parcelable; import android.util.Base64; -import com.android.server.connectivity.metrics.IpConnectivityLogClass; +import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass; import junit.framework.TestCase; diff --git a/tools/aapt2/Main.cpp b/tools/aapt2/Main.cpp index 8dd176d27345..a3404e5db21c 100644 --- a/tools/aapt2/Main.cpp +++ b/tools/aapt2/Main.cpp @@ -25,7 +25,7 @@ namespace aapt { static const char* sMajorVersion = "2"; // Update minor version whenever a feature or flag is added. -static const char* sMinorVersion = "2"; +static const char* sMinorVersion = "3"; int PrintVersion() { std::cerr << "Android Asset Packaging Tool (aapt) " << sMajorVersion << "." diff --git a/tools/aapt2/Resource.cpp b/tools/aapt2/Resource.cpp index 1d414743de71..3eef7aa71a92 100644 --- a/tools/aapt2/Resource.cpp +++ b/tools/aapt2/Resource.cpp @@ -41,6 +41,8 @@ StringPiece ToString(ResourceType type) { return "dimen"; case ResourceType::kDrawable: return "drawable"; + case ResourceType::kFont: + return "font"; case ResourceType::kFraction: return "fraction"; case ResourceType::kId: @@ -83,6 +85,7 @@ static const std::map<StringPiece, ResourceType> sResourceTypeMap{ {"color", ResourceType::kColor}, {"dimen", ResourceType::kDimen}, {"drawable", ResourceType::kDrawable}, + {"font", ResourceType::kFont}, {"fraction", ResourceType::kFraction}, {"id", ResourceType::kId}, {"integer", ResourceType::kInteger}, diff --git a/tools/aapt2/Resource.h b/tools/aapt2/Resource.h index 78acb700c7c0..13330b548d2c 100644 --- a/tools/aapt2/Resource.h +++ b/tools/aapt2/Resource.h @@ -46,6 +46,7 @@ enum class ResourceType { kColor, kDimen, kDrawable, + kFont, kFraction, kId, kInteger, diff --git a/tools/aapt2/Resource_test.cpp b/tools/aapt2/Resource_test.cpp index 720ab91c5740..6acb4d3eb850 100644 --- a/tools/aapt2/Resource_test.cpp +++ b/tools/aapt2/Resource_test.cpp @@ -57,6 +57,10 @@ TEST(ResourceTypeTest, ParseResourceTypes) { ASSERT_NE(type, nullptr); EXPECT_EQ(*type, ResourceType::kDrawable); + type = ParseResourceType("font"); + ASSERT_NE(type, nullptr); + EXPECT_EQ(*type, ResourceType::kFont); + type = ParseResourceType("fraction"); ASSERT_NE(type, nullptr); EXPECT_EQ(*type, ResourceType::kFraction); diff --git a/tools/aapt2/compile/Compile.cpp b/tools/aapt2/compile/Compile.cpp index a06140cff542..f0b18e65cc1a 100644 --- a/tools/aapt2/compile/Compile.cpp +++ b/tools/aapt2/compile/Compile.cpp @@ -482,7 +482,9 @@ class BigBufferOutputStream : public io::OutputStream { void BackUp(int count) override { buffer_->BackUp(count); } - int64_t ByteCount() const override { return buffer_->size(); } + google::protobuf::int64 ByteCount() const override { + return buffer_->size(); + } bool HadError() const override { return false; } diff --git a/tools/aapt2/compile/Png.cpp b/tools/aapt2/compile/Png.cpp index f1bc53ee9cf7..7ab05b58b8b9 100644 --- a/tools/aapt2/compile/Png.cpp +++ b/tools/aapt2/compile/Png.cpp @@ -232,6 +232,13 @@ PNG_COLOR_TYPE_RGB_ALPHA) { } }*/ +#ifdef MAX +#undef MAX +#endif +#ifdef ABS +#undef ABS +#endif + #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define ABS(a) ((a) < 0 ? -(a) : (a)) diff --git a/tools/aapt2/compile/Png.h b/tools/aapt2/compile/Png.h index 01c9adbc9094..aff1da3f05d2 100644 --- a/tools/aapt2/compile/Png.h +++ b/tools/aapt2/compile/Png.h @@ -62,8 +62,8 @@ class PngChunkFilter : public io::InputStream { void BackUp(int count) override; bool Skip(int count) override; - int64_t ByteCount() const override { - return static_cast<int64_t>(window_start_); + google::protobuf::int64 ByteCount() const override { + return static_cast<google::protobuf::int64>(window_start_); } bool HadError() const override { return error_; } diff --git a/tools/aapt2/integration-tests/AppOne/res/font/myfont-italic.ttf b/tools/aapt2/integration-tests/AppOne/res/font/myfont-italic.ttf new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/tools/aapt2/integration-tests/AppOne/res/font/myfont-italic.ttf diff --git a/tools/aapt2/integration-tests/AppOne/res/font/myfont-normal.ttf b/tools/aapt2/integration-tests/AppOne/res/font/myfont-normal.ttf new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/tools/aapt2/integration-tests/AppOne/res/font/myfont-normal.ttf diff --git a/tools/aapt2/integration-tests/AppOne/res/font/myfont.xml b/tools/aapt2/integration-tests/AppOne/res/font/myfont.xml new file mode 100644 index 000000000000..1fb67914894e --- /dev/null +++ b/tools/aapt2/integration-tests/AppOne/res/font/myfont.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<font-family xmlns:android="http://schemas.android.com/apk/res/android"> + <font android:fontStyle="normal" android:fontWeight="400" android:font="@font/myfont-normal" /> + <font android:fontStyle="italic" android:fontWeight="400" android:font="@font/myfont-italic" /> +</font-family> diff --git a/tools/aapt2/proto/TableProtoSerializer.cpp b/tools/aapt2/proto/TableProtoSerializer.cpp index 68db6b333bdc..0d0e46da4ec8 100644 --- a/tools/aapt2/proto/TableProtoSerializer.cpp +++ b/tools/aapt2/proto/TableProtoSerializer.cpp @@ -361,7 +361,7 @@ bool CompiledFileInputStream::ReadLittleEndian32(uint32_t* out_val) { bool CompiledFileInputStream::ReadCompiledFile(pb::CompiledFile* out_val) { EnsureAlignedRead(); - uint64_t pb_size = 0u; + google::protobuf::uint64 pb_size = 0u; if (!in_.ReadLittleEndian64(&pb_size)) { return false; } @@ -389,7 +389,7 @@ bool CompiledFileInputStream::ReadDataMetaData(uint64_t* out_offset, uint64_t* out_len) { EnsureAlignedRead(); - uint64_t pb_size = 0u; + google::protobuf::uint64 pb_size = 0u; if (!in_.ReadLittleEndian64(&pb_size)) { return false; } diff --git a/tools/aapt2/readme.md b/tools/aapt2/readme.md index 93c790d80c4c..ac411b15ae83 100644 --- a/tools/aapt2/readme.md +++ b/tools/aapt2/readme.md @@ -1,5 +1,9 @@ # Android Asset Packaging Tool 2.0 (AAPT2) release notes +## Version 2.3 +### `aapt2` +- Support new `font` resource type. + ## Version 2.2 ### `aapt2 compile ...` - Added support for inline complex XML resources. See diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java index a0b297701869..1b3b563fb51e 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java @@ -374,7 +374,9 @@ public final class BridgeContext extends Context { return true; } - return false; + // If the value is not a valid reference, fallback to pass the value as a string. + outValue.string = value.getValue(); + return true; } |